diff options
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 29 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_pam.c | 39 |
2 files changed, 60 insertions, 8 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index ea50b1ac74..78b0e8c28b 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -344,7 +344,8 @@ static int winbind_auth_request(pam_handle_t * pamh, const char *member, const char *cctype, int process_result, - time_t *pwd_last_set) + time_t *pwd_last_set, + char **user_ret) { struct winbindd_request request; struct winbindd_response response; @@ -388,6 +389,11 @@ static int winbind_auth_request(pam_handle_t * pamh, request.flags |= WBFLAG_PAM_CACHED_LOGIN; } + if (user_ret) { + *user_ret = NULL; + request.flags |= WBFLAG_PAM_UNIX_NAME; + } + if (cctype != NULL) { strncpy(request.data.auth.krb5_cc_type, cctype, sizeof(request.data.auth.krb5_cc_type) - 1); @@ -526,6 +532,12 @@ static int winbind_auth_request(pam_handle_t * pamh, } } + /* If winbindd returned a username, return the pointer to it here. */ + if (user_ret && response.extra_data.data) { + /* We have to trust it's a null terminated string. */ + *user_ret = response.extra_data.data; + } + return ret; } @@ -906,6 +918,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, const char *cctype = NULL; int retval = PAM_AUTH_ERR; dictionary *d; + char *username_ret = NULL; /* parse arguments */ int ctrl = _pam_parse(argc, argv, &d); @@ -948,7 +961,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d); /* Now use the username to look up password */ - retval = winbind_auth_request(pamh, ctrl, username, password, member, cctype, True, NULL); + retval = winbind_auth_request(pamh, ctrl, username, password, member, + cctype, True, NULL, &username_ret); if (retval == PAM_NEW_AUTHTOK_REQD || retval == PAM_AUTHTOK_EXPIRED) { @@ -967,6 +981,11 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, } out: + if (username_ret) { + pam_set_item (pamh, PAM_USER, username_ret); + free(username_ret); + } + if (d) { iniparser_freedict(d); } @@ -1259,7 +1278,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, } /* verify that this is the password for this user */ - retval = winbind_auth_request(pamh, ctrl, user, pass_old, NULL, NULL, False, &pwdlastset_prelim); + retval = winbind_auth_request(pamh, ctrl, user, pass_old, + NULL, NULL, False, &pwdlastset_prelim, NULL); if (retval != PAM_ACCT_EXPIRED && retval != PAM_AUTHTOK_EXPIRED && @@ -1354,7 +1374,8 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags, const char *member = get_member_from_config(argc, argv, ctrl, d); const char *cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d); - retval = winbind_auth_request(pamh, ctrl, user, pass_new, member, cctype, False, NULL); + retval = winbind_auth_request(pamh, ctrl, user, pass_new, + member, cctype, False, NULL, NULL); _pam_overwrite(pass_new); _pam_overwrite(pass_old); pass_old = pass_new = NULL; diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 14975141b2..9bad738d51 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -1306,8 +1306,39 @@ process_result: DEBUG(10,("Failed to get password policies: %s\n", nt_errstr(result))); goto done; } - - } + + if (state->request.flags & WBFLAG_PAM_UNIX_NAME) { + /* 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; + + if (!(nt_username = unistr2_tdup(state->mem_ctx, &info3->uni_user_name))) { + /* If the server didn't give us one, just use the one we sent them */ + nt_username = name_user; + } + + if (!(nt_domain = unistr2_tdup(state->mem_ctx, &info3->uni_logon_dom))) { + /* If the server didn't give us one, just use the one we sent them */ + nt_domain = name_domain; + } + + fill_domain_username(username_out, nt_domain, nt_username, True); + + DEBUG(5, ("Setting unix username to [%s]\n", username_out)); + + SAFE_FREE(state->response.extra_data.data); + state->response.extra_data.data = SMB_STRDUP(username_out); + if (!state->response.extra_data.data) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + state->response.length += + strlen((const char *)state->response.extra_data.data)+1; + } + } + done: /* give us a more useful (more correct?) error code */ @@ -1329,7 +1360,7 @@ done: state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); - if ( NT_STATUS_IS_OK(result) && + if ( NT_STATUS_IS_OK(result) && info3 && (state->request.flags & WBFLAG_PAM_AFS_TOKEN) ) { char *afsname = talloc_strdup(state->mem_ctx, @@ -1389,7 +1420,7 @@ done: no_token: TALLOC_FREE(afsname); } - + return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } |