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";
|
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
|
||||||
#endif
|
#endif
|
||||||
static const char rcsid[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,11 +115,27 @@ pw_lock()
|
|||||||
* that users can't get at the encrypted passwords while editing.
|
* that users can't get at the encrypted passwords while editing.
|
||||||
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
||||||
*/
|
*/
|
||||||
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
for (;;) {
|
||||||
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
|
struct stat st;
|
||||||
err(1, "%s", _PATH_MASTERPASSWD);
|
|
||||||
if (flock(lockfd, LOCK_EX|LOCK_NB))
|
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||||
errx(1, "the password db file is busy");
|
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);
|
return (lockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
|
static const char sccsid[] = "@(#)pw_util.c 8.3 (Berkeley) 4/2/94";
|
||||||
#endif
|
#endif
|
||||||
static const char rcsid[] =
|
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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,11 +115,27 @@ pw_lock()
|
|||||||
* that users can't get at the encrypted passwords while editing.
|
* that users can't get at the encrypted passwords while editing.
|
||||||
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
||||||
*/
|
*/
|
||||||
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
for (;;) {
|
||||||
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
|
struct stat st;
|
||||||
err(1, "%s", _PATH_MASTERPASSWD);
|
|
||||||
if (flock(lockfd, LOCK_EX|LOCK_NB))
|
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||||
errx(1, "the password db file is busy");
|
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);
|
return (lockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user