diff options
author | Günther Deschner <gd@samba.org> | 2006-01-13 11:11:23 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:06:06 -0500 |
commit | 29ba5c17cda35f4277e9d84e9ce2893685f3c683 (patch) | |
tree | ff3c3a7fd991c05f2202ef63f8ff6fea0b4a3ea6 /source3 | |
parent | dbac6701664d3d08495469c734dc47bca649da68 (diff) | |
download | samba-29ba5c17cda35f4277e9d84e9ce2893685f3c683.tar.gz samba-29ba5c17cda35f4277e9d84e9ce2893685f3c683.tar.bz2 samba-29ba5c17cda35f4277e9d84e9ce2893685f3c683.zip |
r12900: Merge from trunk:
Correctly handle the case where users logon with an expired password.
In that case pam_sm_authenticate has to return PAM_SUCESS instead of
PAM_NEW_AUTHTOK_REQD or PAM_AUTHTOK_EXPIRED and pam_sm_acct_mgmt has to
take care of requesting an immediate password change. (see the Linux PAM
documentation).
Fixes Bugzilla #1524, #3205. Tested with login, sshd, kdm and gdm on
Linux.
Thanks to Scott Barker <Scott_Barker@mtechIT.com>.
Guenther
(This used to be commit 4cb662ffd76dbe30003c618c94ccf6ebd4afb48c)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 44 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.h | 2 |
2 files changed, 45 insertions, 1 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index a87ccb4972..61c01daa16 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -57,6 +57,11 @@ static int _pam_parse(int argc, const char **argv) return ctrl; } +static void _pam_winbind_cleanup_func(pam_handle_t *pamh, void *data, int error_status) +{ + SAFE_FREE(data); +} + /* --- authentication management functions --- */ /* Attempt a conversation */ @@ -508,7 +513,22 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, } /* Now use the username to look up password */ - return winbind_auth_request(username, password, member, ctrl); + retval = winbind_auth_request(username, password, member, ctrl); + if (retval == PAM_NEW_AUTHTOK_REQD || + retval == PAM_AUTHTOK_EXPIRED) { + + char *buf; + + if (!asprintf(&buf, "%d", retval)) { + return PAM_BUF_ERR; + } + + pam_set_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (void *)buf, _pam_winbind_cleanup_func); + + return PAM_SUCCESS; + } + + return retval; } PAM_EXTERN @@ -527,6 +547,8 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { const char *username; + void *tmp = NULL; + int retval = PAM_USER_UNKNOWN; /* parse arguments */ @@ -555,6 +577,26 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, return PAM_IGNORE; return PAM_USER_UNKNOWN; case 0: + pam_get_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (const void **)&tmp); + + if (tmp != NULL) { + retval = atoi(tmp); + switch (retval) { + case PAM_AUTHTOK_EXPIRED: + /* fall through, since new token is required in this case */ + case PAM_NEW_AUTHTOK_REQD: + _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success but %s is set", + PAM_WINBIND_NEW_AUTHTOK_REQD); + _pam_log(LOG_NOTICE, "user '%s' needs new password", username); + /* PAM_AUTHTOKEN_REQD does not exist, but is documented in the manpage */ + return PAM_NEW_AUTHTOK_REQD; + default: + _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success"); + _pam_log(LOG_NOTICE, "user '%s' granted access", username); + return PAM_SUCCESS; + } + } + /* Otherwise, the authentication looked good */ _pam_log(LOG_NOTICE, "user '%s' granted access", username); return PAM_SUCCESS; diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 7cae477714..86ba977287 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -84,6 +84,8 @@ do { \ #define WINBIND__OLD_PASSWORD (1<<5) #define WINBIND_REQUIRED_MEMBERSHIP (1<<6) +#define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD" + /* * here is the string to inform the user that the new passwords they * typed were not the same. |