s3-winbindd: Fix Bug #6711: trusts to windows 2008 (2008 r2) not working.
authorGünther Deschner <gd@samba.org>
Thu, 17 Sep 2009 07:43:36 +0000 (09:43 +0200)
committerGünther Deschner <gd@samba.org>
Tue, 22 Sep 2009 14:49:31 +0000 (16:49 +0200)
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

source3/winbindd/winbindd.h
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_rpc.c

index c0df6fde3e00d7ec2fac73acd750ea6c3eb75de3..2e7d09f4424986c177eead585be49d95324af750 100644 (file)
@@ -178,6 +178,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;
 
index b430fbb401ab868f32a297e016472fc46c5e27a0..d03a580d78ede3800219450fbf25889910a39fc5 100644 (file)
@@ -1943,6 +1943,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);
index 70eeae6408b6f1a9f07f23f228d404194340ece5..82e782b9db09b131026eb399babd98fb237731c7 100644 (file)
@@ -1178,6 +1178,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,
@@ -1190,12 +1199,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.
@@ -1203,9 +1223,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);
@@ -1217,6 +1242,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,
@@ -1229,12 +1264,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.
@@ -1242,8 +1289,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);