From f1f157082fcdea90bea1bd7a4a1d7d9de94ce771 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 17 Sep 2009 09:43:36 +0200 Subject: s3-winbindd: Fix Bug #6711: trusts to windows 2008 (2008 r2) not working. Winbindd should always try to use LSA via an schannel authenticated ncacn_ip_tcp connection when talking to AD for LSA lookup calls. In Samba <-> W2k8 interdomain trust scenarios, LookupSids3 and LookupNames4 via an schannel ncacn_ip_tcp LSA connection are the *only* options to successfully resolve sids and names. Guenther (cherry picked from commit 6a8ef6c424c52be861ed2a9806f917a64ec892a6) (cherry picked from commit acc5e6012adca290ddc067a4ed25a8161b74250e) --- source/winbindd/winbindd.h | 2 ++ source/winbindd/winbindd_cm.c | 2 ++ source/winbindd/winbindd_rpc.c | 64 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/source/winbindd/winbindd.h b/source/winbindd/winbindd.h index f97eed07fc3..63b72692f7b 100644 --- a/source/winbindd/winbindd.h +++ b/source/winbindd/winbindd.h @@ -183,6 +183,8 @@ struct winbindd_domain { * to False. This variable is around so that * we don't have to try _ex every time. */ + bool can_do_ncacn_ip_tcp; + /* Lookup methods for this domain (LDAP or RPC) */ struct winbindd_methods *methods; diff --git a/source/winbindd/winbindd_cm.c b/source/winbindd/winbindd_cm.c index 2f823cb6066..9ea3e75116a 100644 --- a/source/winbindd/winbindd_cm.c +++ b/source/winbindd/winbindd_cm.c @@ -1924,6 +1924,8 @@ done: DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n", domain->name, domain->active_directory ? "" : "NOT ")); + domain->can_do_ncacn_ip_tcp = domain->active_directory; + TALLOC_FREE(cli); TALLOC_FREE(mem_ctx); diff --git a/source/winbindd/winbindd_rpc.c b/source/winbindd/winbindd_rpc.c index c1f1a6468df..db43559436f 100644 --- a/source/winbindd/winbindd_rpc.c +++ b/source/winbindd/winbindd_rpc.c @@ -1173,6 +1173,15 @@ static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, return result; } +typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_sids, + const DOM_SID *sids, + char ***pdomains, + char ***pnames, + enum lsa_SidType **ptypes); + NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, uint32_t num_sids, @@ -1185,12 +1194,23 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli = NULL; struct policy_handle lsa_policy; unsigned int orig_timeout; + lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids; + if (domain->can_do_ncacn_ip_tcp) { + status = cm_connect_lsa_tcp(domain, mem_ctx, &cli); + if (NT_STATUS_IS_OK(status)) { + lookup_sids_fn = rpccli_lsa_lookup_sids3; + goto lookup; + } + domain->can_do_ncacn_ip_tcp = false; + } status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { return status; } + lookup: /* * This call can take a long time * allow the server to time out. @@ -1198,9 +1218,14 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, */ orig_timeout = rpccli_set_timeout(cli, 35000); - status = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy, - num_sids, sids, domains, - names, types); + status = lookup_sids_fn(cli, + mem_ctx, + &lsa_policy, + num_sids, + sids, + domains, + names, + types); /* And restore our original timeout. */ rpccli_set_timeout(cli, orig_timeout); @@ -1212,6 +1237,16 @@ NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, return status; } +typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *pol, + int num_names, + const char **names, + const char ***dom_names, + int level, + struct dom_sid **sids, + enum lsa_SidType **types); + NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, uint32_t num_names, @@ -1224,12 +1259,24 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli = NULL; struct policy_handle lsa_policy; unsigned int orig_timeout; + lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names; + if (domain->can_do_ncacn_ip_tcp) { + status = cm_connect_lsa_tcp(domain, mem_ctx, &cli); + if (NT_STATUS_IS_OK(status)) { + lookup_names_fn = rpccli_lsa_lookup_names4; + goto lookup; + } + domain->can_do_ncacn_ip_tcp = false; + } status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); + if (!NT_STATUS_IS_OK(status)) { return status; } + lookup: + /* * This call can take a long time * allow the server to time out. @@ -1237,8 +1284,15 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, */ orig_timeout = rpccli_set_timeout(cli, 35000); - status = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, num_names, - names, domains, 1, sids, types); + status = lookup_names_fn(cli, + mem_ctx, + &lsa_policy, + num_names, + (const char **) names, + domains, + 1, + sids, + types); /* And restore our original timeout. */ rpccli_set_timeout(cli, orig_timeout); -- cgit