Author: gd Date: 2006-01-13 11:11:23 +0000 (Fri, 13 Jan 2006) New Revision: 12900
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12900 Log: 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 <[EMAIL PROTECTED]>. Guenther Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.c branches/SAMBA_3_0/source/nsswitch/pam_winbind.h Changeset: Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.c =================================================================== --- branches/SAMBA_3_0/source/nsswitch/pam_winbind.c 2006-01-13 10:37:14 UTC (rev 12899) +++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.c 2006-01-13 11:11:23 UTC (rev 12900) @@ -57,6 +57,11 @@ 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 @@ } /* 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 argc, const char **argv) { const char *username; + void *tmp = NULL; + int retval = PAM_USER_UNKNOWN; /* parse arguments */ @@ -555,6 +577,26 @@ 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; Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.h =================================================================== --- branches/SAMBA_3_0/source/nsswitch/pam_winbind.h 2006-01-13 10:37:14 UTC (rev 12899) +++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.h 2006-01-13 11:11:23 UTC (rev 12900) @@ -84,6 +84,8 @@ #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.