#include <err.h>
#include <fcntl.h>
#include <inttypes.h>
-#include <libgen.h>
#include <paths.h>
#include <pwd.h>
#include <signal.h>
for (;;) {
struct stat st;
- lockfd = open(masterpasswd, O_RDONLY, 0);
- if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1)
- err(1, "%s", masterpasswd);
- /* XXX vulnerable to race conditions */
- if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
+ lockfd = flopen(masterpasswd, O_RDONLY|O_NONBLOCK|O_CLOEXEC, 0);
+ if (lockfd == -1) {
if (errno == EWOULDBLOCK) {
errx(1, "the password db file is busy");
} else {
errno = ENAMETOOLONG;
return (-1);
}
- if ((tfd = mkstemp(tempname)) == -1)
+ if ((tfd = mkostemp(tempname, O_SYNC)) == -1)
return (-1);
if (mfd != -1) {
while ((nr = read(mfd, buf, sizeof(buf))) > 0)
(void)setuid(getuid());
}
errno = 0;
- execlp(editor, basename(editor), tempname, (char *)NULL);
+ execlp(editor, editor, tempname, (char *)NULL);
_exit(errno);
default:
/* parent */
sigprocmask(SIG_SETMASK, &oldsigset, NULL);
if (stat(tempname, &st2) == -1)
return (-1);
- return (st1.st_mtime != st2.st_mtime);
+ return (st1.st_mtim.tv_sec != st2.st_mtim.tv_sec ||
+ st1.st_mtim.tv_nsec != st2.st_mtim.tv_nsec);
}
/*
size_t len;
int eof, readlen;
- spw = pw;
+ if (old_pw == NULL && pw == NULL)
+ return (-1);
+
+ spw = old_pw;
+ /* deleting a user */
if (pw == NULL) {
line = NULL;
- if (old_pw == NULL)
+ } else {
+ if ((line = pw_make(pw)) == NULL)
return (-1);
- spw = old_pw;
- } else if ((line = pw_make(pw)) == NULL)
- return (-1);
+ }
+
+ /* adding a user */
+ if (spw == NULL)
+ spw = pw;
eof = 0;
len = 0;
*/
*q = t;
- if (fpw == NULL || fpw->pw_uid != spw->pw_uid) {
+ if (fpw == NULL || strcmp(fpw->pw_name, spw->pw_name) != 0) {
/* nope */
if (fpw != NULL)
free(fpw);