summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/winbindd/winbindd.h8
-rw-r--r--source3/winbindd/winbindd_cm.c10
-rw-r--r--source3/winbindd/winbindd_pam.c95
3 files changed, 90 insertions, 23 deletions
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index b812d69aeb..0840e581fe 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -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;
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 072b4ee98f..c715ac08d8 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -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;
}
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index ef5a312eea..c56eb1b3f8 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -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;