diff --git a/usr.sbin/pw/edgroup.c b/usr.sbin/pw/edgroup.c index c927b06cc30a..6116fa6854ac 100644 --- a/usr.sbin/pw/edgroup.c +++ b/usr.sbin/pw/edgroup.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] = - "$Id$"; + "$Id: edgroup.c,v 1.5 1997/10/10 06:23:30 charnier Exp $"; #endif /* not lint */ #include @@ -64,7 +64,7 @@ editgroups(char *name, char **groups) int rc = 0; int infd; - if ((infd = open(groupfile, O_RDWR | O_CREAT | O_EXLOCK, 0644)) != -1) { + if ((infd = open(groupfile, O_RDWR | O_CREAT, 0644)) != -1) { FILE *infp; if ((infp = fdopen(infd, "r+")) == NULL) diff --git a/usr.sbin/pw/fileupd.c b/usr.sbin/pw/fileupd.c index 3782bf7d1da4..fe46480048d1 100644 --- a/usr.sbin/pw/fileupd.c +++ b/usr.sbin/pw/fileupd.c @@ -26,7 +26,7 @@ #ifndef lint static const char rcsid[] = - "$Id$"; + "$Id: fileupd.c,v 1.5 1997/10/10 06:23:31 charnier Exp $"; #endif /* not lint */ #include @@ -76,7 +76,7 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const if (pfxlen <= 1) errno = EINVAL; else { - int infd = open(filename, O_RDWR | O_CREAT | O_EXLOCK, fmode); + int infd = open(filename, O_RDWR | O_CREAT, fmode); if (infd != -1) { FILE *infp = fdopen(infd, "r+"); @@ -168,9 +168,20 @@ fileupdate(char const * filename, mode_t fmode, char const * newline, char const fputs(line, infp); /* + * If there was a problem with copying + * we will just rename 'file.new' + * to 'file'. * This is a gross hack, but we may have * corrupted the original file - * Unfortunately, it will lose the inode. + * Unfortunately, it will lose the inode + * and hence the lock. + * + * The implications of this is that this invocation of pw + * won't have the file locked and concurrent copies + * of pw, vipw etc could clobber what this one is doing. + * + * It should probably just return an error instead + * of going on like nothing is wrong. */ if (fflush(infp) == EOF || ferror(infp)) rc = rename(file, filename) == 0; diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index 634716e5208d..5daa213c880b 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -26,11 +26,12 @@ #ifndef lint static const char rcsid[] = - "$Id$"; + "$Id: pw.c,v 1.7 1997/10/10 06:23:34 charnier Exp $"; #endif /* not lint */ #include "pw.h" #include +#include #include #include @@ -49,6 +50,7 @@ static struct cargs arglist; static int getindex(const char *words[], const char *word); static void cmdhelp(int mode, int which); +static int filelock(const char *filename); int @@ -147,7 +149,20 @@ main(int argc, char *argv[]) * Now, let's do the common initialisation */ cnf = read_userconfig(getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL); - ch = funcs[which] (cnf, mode, &arglist); + + + /* + * Be pessimistic and lock the master passowrd and group + * files right away. Keep it locked for the duration. + */ + if (-1 == filelock(_PATH_GROUP) || -1 == filelock(_PATH_MASTERPASSWD)) + { + ch = EX_IOERR; + } + else + { + ch = funcs[which] (cnf, mode, &arglist); + } /* * If everything went ok, and we've been asked to update @@ -177,6 +192,12 @@ main(int argc, char *argv[]) return ch; } +static int +filelock(const char *filename) +{ + return open(filename, O_RDONLY | O_EXLOCK, 0); +} + static int getindex(const char *words[], const char *word) {