Handle the race condition where vipw may lock a password file which has
just been replaced. After our lock succeeds we check if st_nlink is 0 and if it is we close the descriptor and retry our open/lock sequence.
This commit is contained in:
parent
0aae7eb02e
commit
f16d2ab2d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=41710
@ -36,7 +36,7 @@
|
||||
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: pw_util.c,v 1.10 1998/10/13 14:52:33 des Exp $";
|
||||
"$Id: pw_util.c,v 1.11 1998/10/20 11:34:11 des Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -115,11 +115,27 @@ pw_lock()
|
||||
* that users can't get at the encrypted passwords while editing.
|
||||
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
||||
*/
|
||||
for (;;) {
|
||||
struct stat st;
|
||||
|
||||
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
|
||||
err(1, "%s", _PATH_MASTERPASSWD);
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB))
|
||||
errx(1, "the password db file is busy");
|
||||
|
||||
/*
|
||||
* If the password file was replaced while we were trying to
|
||||
* get the lock, our hardlink count will be 0 and we have to
|
||||
* close and retry.
|
||||
*/
|
||||
if (fstat(lockfd, &st) < 0)
|
||||
errx(1, "fstat() failed");
|
||||
if (st.st_nlink != 0)
|
||||
break;
|
||||
close(lockfd);
|
||||
lockfd = -1;
|
||||
}
|
||||
return (lockfd);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: pw_util.c,v 1.10 1998/10/13 14:52:33 des Exp $";
|
||||
"$Id: pw_util.c,v 1.11 1998/10/20 11:34:11 des Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
@ -115,11 +115,27 @@ pw_lock()
|
||||
* that users can't get at the encrypted passwords while editing.
|
||||
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
||||
*/
|
||||
for (;;) {
|
||||
struct stat st;
|
||||
|
||||
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
|
||||
err(1, "%s", _PATH_MASTERPASSWD);
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB))
|
||||
errx(1, "the password db file is busy");
|
||||
|
||||
/*
|
||||
* If the password file was replaced while we were trying to
|
||||
* get the lock, our hardlink count will be 0 and we have to
|
||||
* close and retry.
|
||||
*/
|
||||
if (fstat(lockfd, &st) < 0)
|
||||
errx(1, "fstat() failed");
|
||||
if (st.st_nlink != 0)
|
||||
break;
|
||||
close(lockfd);
|
||||
lockfd = -1;
|
||||
}
|
||||
return (lockfd);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user