diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/nsswitch/winbindd.h | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 11 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 54 |
3 files changed, 71 insertions, 2 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index 4679a1330c..e98c859405 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -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; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index b8b11b8466..cea2ff8445 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -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; } diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 52039ad420..9653e6c876 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -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 |