summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/pam_winbind.c29
-rw-r--r--source3/nsswitch/winbindd_pam.c39
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;
}