Merge dd9e0bea31751 from 3-0-ctdb -- use NetSamLogonEx when possible
authorVolker Lendecke <vl@samba.org>
Wed, 19 Mar 2008 15:09:37 +0000 (16:09 +0100)
committerVolker Lendecke <vl@samba.org>
Wed, 19 Mar 2008 16:00:53 +0000 (17:00 +0100)
NetSamLogonEx has the advantage that it does not use the credential chain
(This used to be commit cfceb063f559f8549b8f24ce347be213c89303b0)

source3/winbindd/winbindd.h
source3/winbindd/winbindd_cm.c
source3/winbindd/winbindd_pam.c

index b812d69aebccc6004144edaa0ce7c62c12bae19c..0840e581fe6ae1dbe92341cb2b389be2509d0af2 100644 (file)
@@ -176,6 +176,14 @@ struct winbindd_domain {
        time_t startup_time;                   /* When we set "startup" true. */
        bool startup;                          /* are we in the first 30 seconds after startup_time ? */
 
+       bool can_do_samlogon_ex; /* Due to the lack of finer control what type
+                                 * of DC we have, let us try to do a
+                                 * credential-chain less samlogon_ex call
+                                 * with AD and schannel. If this fails with
+                                 * DCERPC_FAULT_OP_RNG_ERROR, then set this
+                                 * to False. This variable is around so that
+                                 * we don't have to try _ex every time. */
+
        /* Lookup methods for this domain (LDAP or RPC) */
        struct winbindd_methods *methods;
 
index 072b4ee98f6e62e3b7842aef91cd3cbdf659a430..c715ac08d82e5b05c451305909c2f75e9786dc2d 100644 (file)
@@ -2403,6 +2403,11 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
  no_schannel:
        if ((lp_client_schannel() == False) ||
                        ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+               /*
+                * NetSamLogonEx only works for schannel
+                */
+               domain->can_do_samlogon_ex = False;
+
                /* We're done - just keep the existing connection to NETLOGON
                 * open */
                conn->netlogon_pipe = netlogon_pipe;
@@ -2434,6 +2439,11 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
                return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
        }
 
+       /*
+        * Try NetSamLogonEx for AD domains
+        */
+       domain->can_do_samlogon_ex = domain->active_directory;
+
        *cli = conn->netlogon_pipe;
        return NT_STATUS_OK;
 }
index ef5a312eea960467af582795e0577925c94c47c7..c56eb1b3f89ab69496d99947bc1236bcc7c5760a 100644 (file)
@@ -1283,6 +1283,17 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
        /* check authentication loop */
 
        do {
+               NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint32 logon_parameters,
+                                    const char *server,
+                                    const char *username,
+                                    const char *domain,
+                                    const char *workstation,
+                                    const uint8 chal[8],
+                                    DATA_BLOB lm_response,
+                                    DATA_BLOB nt_response,
+                                    struct netr_SamInfo3 **info3);
 
                ZERO_STRUCTP(my_info3);
                retry = False;
@@ -1294,19 +1305,32 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
-                                                          state->mem_ctx,
-                                                          0,
-                                                          contact_domain->dcname, /* server name */
-                                                          name_user,              /* user name */
-                                                          name_domain,            /* target domain */
-                                                          global_myname(),        /* workstation */
-                                                          chal,
-                                                          lm_resp,
-                                                          nt_resp,
-                                                          &my_info3);
+               logon_fn = contact_domain->can_do_samlogon_ex
+                       ? rpccli_netlogon_sam_network_logon_ex
+                       : rpccli_netlogon_sam_network_logon;
+
+               result = logon_fn(netlogon_pipe,
+                                 state->mem_ctx,
+                                 0,
+                                 contact_domain->dcname, /* server name */
+                                 name_user,              /* user name */
+                                 name_domain,            /* target domain */
+                                 global_myname(),        /* workstation */
+                                 chal,
+                                 lm_resp,
+                                 nt_resp,
+                                 &my_info3);
                attempts += 1;
 
+               if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
+                   && contact_domain->can_do_samlogon_ex) {
+                       DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
+                                 "retrying with NetSamLogon\n"));
+                       contact_domain->can_do_samlogon_ex = False;
+                       retry = True;
+                       continue;
+               }
+
                /* We have to try a second time as cm_connect_netlogon
                   might not yet have noticed that the DC has killed
                   our connection. */
@@ -1804,6 +1828,18 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
        }
 
        do {
+               NTSTATUS (*logon_fn)(struct rpc_pipe_client *cli,
+                                    TALLOC_CTX *mem_ctx,
+                                    uint32 logon_parameters,
+                                    const char *server,
+                                    const char *username,
+                                    const char *domain,
+                                    const char *workstation,
+                                    const uint8 chal[8],
+                                    DATA_BLOB lm_response,
+                                    DATA_BLOB nt_response,
+                                    struct netr_SamInfo3 **info3);
+
                retry = False;
 
                netlogon_pipe = NULL;
@@ -1815,18 +1851,31 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
-                                                          state->mem_ctx,
-                                                          state->request.data.auth_crap.logon_parameters,
-                                                          contact_domain->dcname,
-                                                          name_user,
-                                                          name_domain, 
-                                                                       /* Bug #3248 - found by Stefan Burkei. */
-                                                          workstation, /* We carefully set this above so use it... */
-                                                          state->request.data.auth_crap.chal,
-                                                          lm_resp,
-                                                          nt_resp,
-                                                          &info3);
+               logon_fn = contact_domain->can_do_samlogon_ex
+                       ? rpccli_netlogon_sam_network_logon_ex
+                       : rpccli_netlogon_sam_network_logon;
+
+               result = logon_fn(netlogon_pipe,
+                                 state->mem_ctx,
+                                 state->request.data.auth_crap.logon_parameters,
+                                 contact_domain->dcname,
+                                 name_user,
+                                 name_domain, 
+                                 /* Bug #3248 - found by Stefan Burkei. */
+                                 workstation, /* We carefully set this above so use it... */
+                                 state->request.data.auth_crap.chal,
+                                 lm_resp,
+                                 nt_resp,
+                                 &info3);
+
+               if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
+                   && contact_domain->can_do_samlogon_ex) {
+                       DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
+                                 "retrying with NetSamLogon\n"));
+                       contact_domain->can_do_samlogon_ex = False;
+                       retry = True;
+                       continue;
+               }
 
                attempts += 1;