#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+#define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000
+
static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx,
struct winbindd_cli_state *state,
struct netr_SamInfo3 *info3)
/* We've been asked to return the unix username, per
'winbind use default domain' settings and the like */
- fstring username_out;
const char *nt_username, *nt_domain;
nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
nt_username = name_user;
}
- fill_domain_username(username_out, nt_domain, nt_username,
- True);
-
- DEBUG(5,("Setting unix username to [%s]\n", username_out));
+ fill_domain_username(state->response.data.auth.unix_username,
+ nt_domain, nt_username, True);
- SAFE_FREE(state->response.extra_data.data);
- state->response.extra_data.data = SMB_STRDUP(username_out);
- if (!state->response.extra_data.data) {
- return NT_STATUS_NO_MEMORY;
- }
- state->response.length +=
- strlen((const char *)state->response.extra_data.data)+1;
+ DEBUG(5,("Setting unix username to [%s]\n",
+ state->response.data.auth.unix_username));
return NT_STATUS_OK;
}
static bool check_request_flags(uint32_t flags)
{
uint32_t flags_edata = WBFLAG_PAM_AFS_TOKEN |
- WBFLAG_PAM_UNIX_NAME |
WBFLAG_PAM_INFO3_TEXT |
WBFLAG_PAM_INFO3_NDR;
if ( ( (flags & flags_edata) == WBFLAG_PAM_AFS_TOKEN) ||
( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) ||
( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)||
- ( (flags & flags_edata) == WBFLAG_PAM_UNIX_NAME) ||
!(flags & flags_edata) ) {
return True;
}
/* 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;
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. */
* caller, we look up the account flags ourselve - gd */
if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) &&
- (my_info3->base.acct_flags == 0) && NT_STATUS_IS_OK(result)) {
+ NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) {
struct rpc_pipe_client *samr_pipe;
POLICY_HND samr_domain_handle, user_pol;
if (state->request.flags & WBFLAG_PAM_GET_PWD_POLICY) {
- result = fillup_password_policy(domain, state);
-
+ struct winbindd_domain *our_domain = find_our_domain();
+
+ /* This is not entiurely correct I believe, but it is
+ consistent. Only apply the password policy settings
+ too warn users for our own domain. Cannot obtain these
+ from trusted DCs all the time so don't do it at all.
+ -- jerry */
+
+ result = NT_STATUS_NOT_SUPPORTED;
+ if (our_domain == domain ) {
+a result = fillup_password_policy(our_domain, state);
+ }
+
if (!NT_STATUS_IS_OK(result)
&& !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) )
{
- DEBUG(10,("Failed to get password policies: %s\n", nt_errstr(result)));
+ DEBUG(10,("Failed to get password policies for domain %s: %s\n",
+ domain->name, nt_errstr(result)));
goto done;
}
}
}
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;
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;