r23225: Attached find a patch that makes use of NetSamLogonEx in
authorVolker Lendecke <vlendec@samba.org>
Tue, 29 May 2007 19:31:57 +0000 (19:31 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:22:56 +0000 (12:22 -0500)
winbind. With this and W2k3 DCs around it is possible to use
more than one winbind on the same machine account, because
NetSamLogonEx does not use the credentials chain.

I added the flag domain->can_do_samlogon_ex because this
only works against W2k3 and with schannel. The theory is to
try if we're AD and have schannel, and fall back to
NetSamLogon if this fails. can_do_samlogon_ex is thus a
protection against multiple failures.

Only checking into 3_0, this needs more review before going
into a production release.

Feel free to comment :-)

source/nsswitch/winbindd.h
source/nsswitch/winbindd_cm.c
source/nsswitch/winbindd_pam.c

index 4679a1330cba15691c784ebbcdb12f14a5fa85d9..e98c85940569eb95da3201388b063d55aaafa8e6 100644 (file)
@@ -169,6 +169,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 b8b11b8466aa9638d4d165409124c1c0afbe8246..cea2ff844573959100515d4d4ad18b8e59738b46 100644 (file)
@@ -2201,6 +2201,12 @@ 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;
@@ -2232,6 +2238,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 52039ad420a8e69518c286ba6458935bf883ec6a..9653e6c87678a9cc50abca1b01149828703a766d 100644 (file)
@@ -1200,6 +1200,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,
+                                    NET_USER_INFO_3 *info3);
 
                ZERO_STRUCTP(my_info3);
                retry = False;
@@ -1211,7 +1222,11 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+               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 */
@@ -1222,6 +1237,16 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
                                                           lm_resp,
                                                           nt_resp,
                                                           my_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;
 
                /* We have to try a second time as cm_connect_netlogon
@@ -1807,6 +1832,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,
+                                    NET_USER_INFO_3 *info3);
+
                ZERO_STRUCT(info3);
                retry = False;
 
@@ -1819,7 +1856,11 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                        goto done;
                }
 
-               result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+               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,
@@ -1832,6 +1873,15 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
                                                           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;
 
                /* We have to try a second time as cm_connect_netlogon