diff options
author | Tomas Mraz <tm@t8m.info> | 2005-04-08 13:18:09 +0000 |
---|---|---|
committer | Tomas Mraz <tm@t8m.info> | 2005-04-08 13:18:09 +0000 |
commit | b484271729ebfc86cee8ec7386e0ac11b111c188 (patch) | |
tree | f1f9e43f80c037ca9c8fb492ba71161e74f37ec4 | |
parent | 8ebbc8468fb42237a36f8aaba2434f72ec152ef5 (diff) | |
download | pam-b484271729ebfc86cee8ec7386e0ac11b111c188.tar.gz pam-b484271729ebfc86cee8ec7386e0ac11b111c188.tar.bz2 pam-b484271729ebfc86cee8ec7386e0ac11b111c188.zip |
Relevant BUGIDs: Red Hat bz #88127
Purpose of commit:
Commit summary:
---------------
pam_unix: fix regression introduced in 0.78 - both NIS and local password
should be changed if possible - see the analysis in the RH bugzilla
-rw-r--r-- | CHANGELOG | 2 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 76 |
2 files changed, 52 insertions, 26 deletions
@@ -63,6 +63,8 @@ BerliOS Bugs are marked with (BerliOS #XXXX). 0.80: please submit patches for this section with actual code/doc patches! * pam_tally: test for NULL data before dereferencing them (t8m) +* pam_unix: fix regression introduced in 0.78 - both NIS and local password + should be changed if possible (t8m) 0.79: Thu Mar 31 16:48:45 CEST 2005 * pam_tally: added audit option (toady) diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index 2ea57cc6..b48539a0 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -532,6 +532,8 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, { struct passwd *pwd = NULL; int retval = 0; + int unlocked = 0; + char *master = NULL; D(("called")); @@ -541,26 +543,12 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, retval = PAM_AUTHTOK_ERR; goto done; } - - if (_unix_comesfromsource(pamh, forwho, 1, 0)) { - /* first, save old password */ - if (save_old_password(pamh, forwho, fromwhat, remember)) { - retval = PAM_AUTHTOK_ERR; - goto done; - } - if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) { - retval = _update_shadow(pamh, forwho, towhat); - if (retval == PAM_SUCCESS) - if (!_unix_shadowed(pwd)) - retval = _update_passwd(pamh, forwho, "x"); - } else { - retval = _update_passwd(pamh, forwho, towhat); - } - } else if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { + + if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) { + if ((master=getNISserver(pamh)) != NULL) { struct timeval timeout; struct yppasswd yppwd; CLIENT *clnt; - char *master; int status; int err = 0; @@ -568,9 +556,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, #ifdef USE_LCKPWDF ulckpwdf(); #endif - /* Make RPC call to NIS server */ - if ((master = getNISserver(pamh)) == NULL) - return PAM_TRY_AGAIN; + unlocked = 1; /* Initialize password information */ yppwd.newpw.pw_passwd = pwd->pw_passwd; @@ -601,11 +587,10 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, timeout); if (err) { - clnt_perrno(err); - retval = PAM_TRY_AGAIN; + _make_remark(pamh, ctrl, PAM_TEXT_INFO, + clnt_sperrno(err)); } else if (status) { D(("Error while changing NIS password.\n")); - retval = PAM_TRY_AGAIN; } D(("The password has%s been changed on %s.", (err || status) ? " not" : "", master)); @@ -614,16 +599,55 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat, auth_destroy(clnt->cl_auth); clnt_destroy(clnt); - if ((err || status) != 0) { + if (err || status) { + _make_remark(pamh, ctrl, PAM_TEXT_INFO, + "NIS password could not be changed."); retval = PAM_TRY_AGAIN; } #ifdef DEBUG sleep(5); #endif - return retval; + } else { + retval = PAM_TRY_AGAIN; + } } -done: + if (_unix_comesfromsource(pamh, forwho, 1, 0)) { +#ifdef USE_LCKPWDF + if(unlocked) { + int i = 0; + /* These values for the number of attempts and the sleep time + are, of course, completely arbitrary. + My reading of the PAM docs is that, once pam_chauthtok() has been + called with PAM_UPDATE_AUTHTOK, we are obliged to take any + reasonable steps to make sure the token is updated; so retrying + for 1/10 sec. isn't overdoing it. */ + while((retval = lckpwdf()) != 0 && i < 100) { + usleep(1000); + i++; + } + if(retval != 0) { + return PAM_AUTHTOK_LOCK_BUSY; + } + } +#endif + /* first, save old password */ + if (save_old_password(pamh, forwho, fromwhat, remember)) { + retval = PAM_AUTHTOK_ERR; + goto done; + } + if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) { + retval = _update_shadow(pamh, forwho, towhat); + if (retval == PAM_SUCCESS) + if (!_unix_shadowed(pwd)) + retval = _update_passwd(pamh, forwho, "x"); + } else { + retval = _update_passwd(pamh, forwho, towhat); + } + } + + +done: #ifdef USE_LCKPWDF ulckpwdf(); #endif |