summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-09-05 05:28:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:43:24 -0500
commitd2465b17300168c37230de34f71e99d5b02d306d (patch)
tree5a7c78cec0334b3d58ecd943e1ce68ee1810816b
parenta21693fac6c769ab67b05c1fdc001d01d83309cd (diff)
downloadsamba-d2465b17300168c37230de34f71e99d5b02d306d.tar.gz
samba-d2465b17300168c37230de34f71e99d5b02d306d.tar.bz2
samba-d2465b17300168c37230de34f71e99d5b02d306d.zip
r18062: Fix to ensure the name used by pam matches the
name that will be returned by winbindd. This (should) fix the bug where the user logs in with DOMAIN\user but winbindd returns only "user" for the username due to 'winbind use default domain' being set. Jeremy. (This used to be commit 1b2aa17354d50740902010f4a1e0217c8b1f7bdd)
-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;
}