diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 3 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 11 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 62 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 11 |
4 files changed, 69 insertions, 18 deletions
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 9f5bf3f11a..0cb0f0cb99 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -559,6 +559,9 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) { DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller)); } + + if ( sec_channel_type == SEC_CHAN_DOMAIN ) + snprintf(conn->cli->mach_acct, sizeof(conn->cli->mach_acct) - 1, "%s$", lp_workgroup()); result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd); diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index e4b0e78e2e..265297ca08 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -213,6 +213,17 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state) if (!parse_domain_user(tmp, name_domain, name_group)) return WINBINDD_ERROR; + /* don't handle our own domain if we are a DC. This code handles cases where + the account doesn't exist anywhere and gets passed on down the NSS layer */ + + if ( ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role()==ROLE_DOMAIN_BDC)) && + strequal(name_domain, lp_workgroup()) ) + { + DEBUG(7,("winbindd_getgrnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n", + name_domain, name_group)); + return WINBINDD_ERROR; + } + /* Get info for the domain */ if ((domain = find_domain_from_name(name_domain)) == NULL) { diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 7b93015b5d..a3b0849721 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -235,11 +235,52 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid, domain, user)); + + /* check our role as a domain member first */ + if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) { + if ( !lp_allow_trusted_domains() && !strequal(domain, lp_workgroup()) ) { + DEBUG(5,("winbindd_pam_auth_crap: failing autghentication becuase of disallowed trust domains\n")); + result = NT_STATUS_LOGON_FAILURE; + goto done; + } + + contact_domain = domain; - if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) { + /* + * Get the machine account password for the domain to contact. + * This is either our own domain for a workstation, or possibly + * any domain for a PDC with trusted domains. + */ + + if (!secrets_fetch_trust_account_password (contact_domain, + trust_passwd, + &last_change_time, + &sec_channel_type)) { + DEBUG(0, ("winbindd_pam_auth_crap: could not fetch trust account " + "password for domain %s\n", contact_domain)); + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; + } + } + else if ( lp_allow_trusted_domains() ) { + /* if we are not a domain member, then we must be a DC. Must never + see a logon for our domain */ + DOM_SID sid; + char *pwd; contact_domain = domain; - } else { - contact_domain = lp_workgroup(); + + if (!secrets_fetch_trusted_domain_password (contact_domain, + &pwd, &sid, + &last_change_time)) { + DEBUG(0, ("winbindd_pam_auth_crap: could not fetch trust account " + "password for domain %s\n", contact_domain)); + result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + goto done; + } + sec_channel_type = SEC_CHAN_DOMAIN; + E_md4hash(pwd, trust_passwd); + SAFE_FREE(pwd); + } if (*state->request.data.auth_crap.workstation) { @@ -264,21 +305,6 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state) lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len); nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len); - /* - * Get the machine account password for the domain to contact. - * This is either our own domain for a workstation, or possibly - * any domain for a PDC with trusted domains. - */ - - if (!secrets_fetch_trust_account_password ( - contact_domain, trust_passwd, &last_change_time, - &sec_channel_type)) { - DEBUG(0, ("winbindd_pam_auth: could not fetch trust account " - "password for domain %s\n", contact_domain)); - result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - goto done; - } - do { ZERO_STRUCT(info3); ZERO_STRUCT(ret_creds); diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index ccfddc83ba..518f335f27 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -115,6 +115,17 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state) name_user)) return WINBINDD_ERROR; + /* don't handle our own domain if we are a DC. This code handles cases where + the account doesn't exist anywhere and gets passed on down the NSS layer */ + + if ( ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role()==ROLE_DOMAIN_BDC)) && + strequal(name_domain, lp_workgroup()) ) + { + DEBUG(7,("winbindd_getpwnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n", + name_domain, name_user)); + return WINBINDD_ERROR; + } + if ((domain = find_domain_from_name(name_domain)) == NULL) { DEBUG(5, ("no such domain: %s\n", name_domain)); return WINBINDD_ERROR; |