PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags , int argc, const char **argv) { const char *service=NULL, *tty=NULL; const char *user=NULL; int retval; unsigned setting; /* only interested in establishing credentials */ setting = flags; if (!(setting & PAM_ESTABLISH_CRED)) { D(("ignoring call - not for establishing credentials")); return PAM_SUCCESS; /* don't fail because of this */ } /* set service name */ if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service) != PAM_SUCCESS || service == NULL) { _log_err("cannot find the current service name"); return PAM_ABORT; } /* set username */ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL || *user == '\0') { _log_err("cannot determine the user's name"); return PAM_USER_UNKNOWN; } /* set tty name */ if (pam_get_item(pamh, PAM_TTY, (const void **)&tty) != PAM_SUCCESS || tty == NULL) { D(("PAM_TTY not set, probing stdin")); tty = ttyname(STDIN_FILENO); if (tty == NULL) { _log_err("couldn't get the tty name"); return PAM_ABORT; } if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) { _log_err("couldn't set tty name"); return PAM_ABORT; } } if (strncmp("/dev/",tty,5) == 0) { /* strip leading /dev/ */ tty += 5; } /* good, now we have the service name, the user and the terminal name */ D(("service=%s", service)); D(("user=%s", user)); D(("tty=%s", tty)); #ifdef WANT_PWDB /* We initialize the pwdb library and check the account */ retval = pwdb_start(); /* initialize */ if (retval == PWDB_SUCCESS) { retval = check_account(service,tty,user); /* get groups */ (void) pwdb_end(); /* tidy up */ } else { D(("failed to initialize pwdb; %s", pwdb_strerror(retval))); _log_err("unable to initialize libpwdb"); retval = PAM_ABORT; } #else /* WANT_PWDB */ retval = check_account(service,tty,user); /* get groups */ #endif /* WANT_PWDB */ return retval; }
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, const char *sent_nt_username, const char *domain, struct auth_serversupplied_info **server_info, const struct netr_SamInfo3 *info3) { static const char zeros[16] = {0, }; NTSTATUS nt_status = NT_STATUS_OK; char *found_username = NULL; const char *nt_domain; const char *nt_username; struct dom_sid user_sid; struct dom_sid group_sid; bool username_was_mapped; struct passwd *pwd; struct auth_serversupplied_info *result; TALLOC_CTX *tmp_ctx = talloc_stackframe(); /* Here is where we should check the list of trusted domains, and verify that the SID matches. */ if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) { nt_status = NT_STATUS_INVALID_PARAMETER; goto out; } if (!sid_compose(&group_sid, info3->base.domain_sid, info3->base.primary_gid)) { nt_status = NT_STATUS_INVALID_PARAMETER; goto out; } nt_username = talloc_strdup(tmp_ctx, info3->base.account_name.string); if (!nt_username) { /* If the server didn't give us one, just use the one we sent * them */ nt_username = sent_nt_username; } nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string); if (!nt_domain) { /* If the server didn't give us one, just use the one we sent * them */ nt_domain = domain; } /* If getpwnam() fails try the add user script (2.2.x behavior). We use the _unmapped_ username here in an attempt to provide consistent username mapping behavior between kerberos and NTLM[SSP] authentication in domain mode security. I.E. Username mapping should be applied to the fully qualified username (e.g. DOMAIN\user) and not just the login name. Yes this means we called map_username() unnecessarily in make_user_info_map() but that is how the current code is designed. Making the change here is the least disruptive place. -- jerry */ /* this call will try to create the user if necessary */ nt_status = check_account(tmp_ctx, nt_domain, nt_username, &found_username, &pwd, &username_was_mapped); if (!NT_STATUS_IS_OK(nt_status)) { /* Handle 'map to guest = Bad Uid */ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) && (lp_security() == SEC_ADS || lp_security() == SEC_DOMAIN) && lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) { DBG_NOTICE("Try to map %s to guest account", nt_username); nt_status = make_server_info_guest(tmp_ctx, &result); if (NT_STATUS_IS_OK(nt_status)) { *server_info = talloc_move(mem_ctx, &result); } } goto out; } result = make_server_info(tmp_ctx); if (result == NULL) { DEBUG(4, ("make_server_info failed!\n")); nt_status = NT_STATUS_NO_MEMORY; goto out; } result->unix_name = talloc_strdup(result, found_username); /* copy in the info3 */ result->info3 = copy_netr_SamInfo3(result, info3); if (result->info3 == NULL) { nt_status = NT_STATUS_NO_MEMORY; goto out; } /* Fill in the unix info we found on the way */ result->utok.uid = pwd->pw_uid; result->utok.gid = pwd->pw_gid; /* ensure we are never given NULL session keys */ if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) { result->session_key = data_blob_null; } else { result->session_key = data_blob_talloc( result, info3->base.key.key, sizeof(info3->base.key.key)); } if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) { result->lm_session_key = data_blob_null; } else { result->lm_session_key = data_blob_talloc( result, info3->base.LMSessKey.key, sizeof(info3->base.LMSessKey.key)); } result->nss_token |= username_was_mapped; result->guest = (info3->base.user_flags & NETLOGON_GUEST); *server_info = talloc_move(mem_ctx, &result); nt_status = NT_STATUS_OK; out: talloc_free(tmp_ctx); return nt_status; }