summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/pam_unix/pam_unix_passwd.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index cfa294f8..a3925895 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -644,7 +644,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
int argc, const char **argv)
{
unsigned int ctrl, lctrl;
- int retval;
+ int retval, i;
int remember = -1;
/* <DO NOT free() THESE> */
@@ -658,7 +658,22 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
/* our current locking system requires that we lock the
entire password database. This avoids both livelock
and deadlock. */
- 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.
+ 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(flags, &remember, argc, argv);