Delta from 1.12 to 1.13 from Linux-PAM pam_unix_passwd.c made to work with our changes. Index: Linux-PAM/modules/pam_unix/pam_unix_passwd.c =================================================================== RCS file: /afs/sipb/project/debian/cvs/pam/Linux-PAM/modules/pam_unix/pam_unix_passwd.c,v retrieving revision 1.10 diff -u -r1.10 pam_unix_passwd.c --- Linux-PAM/modules/pam_unix/pam_unix_passwd.c 12 Jan 2004 06:43:14 -0000 1.10 +++ Linux-PAM/modules/pam_unix/pam_unix_passwd.c 12 Jan 2004 06:44:03 -0000 @@ -88,7 +88,7 @@ */ #ifdef NEED_LCKPWDF -#include "./lckpwdf.-c" +# include "./lckpwdf.-c" #endif extern char *bigcrypt(const char *key, const char *salt); @@ -494,10 +494,7 @@ D(("called")); - setpwent(); pwd = getpwnam(forwho); - endpwent(); - if (pwd == NULL) return PAM_AUTHTOK_ERR; @@ -569,6 +566,24 @@ if (save_old_password(forwho, fromwhat, remember)) { return PAM_AUTHTOK_ERR; } + +#ifdef USE_LCKPWDF + /* + * 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. + */ + + retval = lckpwdf(); + if (retval != 0) { + return PAM_AUTHTOK_LOCK_BUSY; + } +#endif /* def USE_LCKPWDF */ + if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) { retval = _update_shadow(forwho, towhat); if (retval == PAM_SUCCESS) @@ -580,6 +595,10 @@ if (retval == PAM_SUCCESS) _log_err(LOG_NOTICE, pamh, "Password for %s was changed", forwho); +#ifdef USE_LCKPWDF + ulckpwdf(); +#endif /* def USE_LCKPWDF */ + return retval; } @@ -708,7 +727,7 @@ int argc, const char **argv) { unsigned int ctrl, lctrl; - int retval, i; + int retval; int remember = -1; /* */ @@ -718,33 +737,12 @@ D(("called.")); -#ifdef USE_LCKPWDF - /* our current locking system requires that we lock the - entire password database. This avoids both livelock - and deadlock. */ - /* 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. - The other possibility is to call lckpwdf() on the first - pam_chauthtok() pass, and hold the lock until released in the - second pass--but is this guaranteed to work? -SRL */ - i=0; - while((retval = lckpwdf()) != 0 && i < 100) { - usleep(1000); - } - if(retval != 0) { - return PAM_AUTHTOK_LOCK_BUSY; - } -#endif ctrl = _set_ctrl(pamh, flags, &remember, argc, argv); /* * First get the name of a user */ - retval = pam_get_user(pamh, &user, "Username: "); + retval = pam_get_user(pamh, &user, NULL); if (retval == PAM_SUCCESS) { /* * Various libraries at various times have had bugs related to @@ -754,9 +752,6 @@ */ if (user == NULL || !isalnum(*user)) { _log_err(LOG_ERR, pamh, "bad username [%s]", user); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return PAM_USER_UNKNOWN; } if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) @@ -766,9 +761,6 @@ if (on(UNIX_DEBUG, ctrl)) _log_err(LOG_DEBUG, pamh, "password - could not identify user"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } @@ -790,9 +782,6 @@ D(("prelim check")); if (_unix_blankpasswd(ctrl, user)) { -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return PAM_SUCCESS; } else if (off(UNIX__IAMROOT, ctrl) || on(UNIX_NIS, ctrl)) { @@ -802,9 +791,6 @@ if (Announce == NULL) { _log_err(LOG_CRIT, pamh, "password - out of memory"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return PAM_BUF_ERR; } (void) strcpy(Announce, greeting); @@ -826,9 +812,6 @@ if (retval != PAM_SUCCESS) { _log_err(LOG_NOTICE, pamh ,"password - (old) token not obtained"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } /* verify that this is the password for this user @@ -846,9 +829,6 @@ if (retval != PAM_SUCCESS) { D(("Authentication failed")); pass_old = NULL; -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old); @@ -901,17 +881,11 @@ if (retval != PAM_SUCCESS) { _log_err(LOG_NOTICE, pamh, "user not authenticated"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } retval = _unix_verify_shadow(user, ctrl); if (retval != PAM_SUCCESS) { _log_err(LOG_NOTICE, pamh, "user not authenticated 2"); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } D(("get new password now")); @@ -942,9 +916,6 @@ ,"password - new password not obtained"); } pass_old = NULL; /* tidy up */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } D(("returned to _unix_chauthtok")); @@ -965,9 +936,6 @@ _log_err(LOG_NOTICE, pamh, "new password not acceptable"); pass_new = pass_old = NULL; /* tidy up */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; } /* @@ -1008,9 +976,6 @@ _log_err(LOG_CRIT, pamh, "out of memory for password"); pass_new = pass_old = NULL; /* tidy up */ -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return PAM_BUF_ERR; } /* copy first 8 bytes of password */ @@ -1032,6 +997,7 @@ retval = _do_setpass(pamh, user, pass_old, tpass, ctrl, remember); + _pam_delete(tpass); pass_old = pass_new = NULL; } else { /* something has broken with the module */ @@ -1042,9 +1008,6 @@ D(("retval was %d", retval)); -#ifdef USE_LCKPWDF - ulckpwdf(); -#endif return retval; }