summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd_cm.c3
-rw-r--r--source3/nsswitch/winbindd_group.c11
-rw-r--r--source3/nsswitch/winbindd_pam.c62
-rw-r--r--source3/nsswitch/winbindd_user.c11
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;