run at the same time.
Notes:
The fileupdate function is still somewhat broken. Instead of
returning a failure code if it can't modify the original file it
renames the .new file and continues as though nothing is wrong.
This will cause the lock on the original file to be lost and could
lead to a similar race condition. I left that portion of the code
alone since I feel that the maintainer of the code would have a
better concept of how he wants to handle errors in that function
than I do.
PR: bin/6787
Submitted by: Craig Spannring <cts@internetcds.com>
#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 <stdio.h>
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)
#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 <stdio.h>
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+");
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;
#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 <err.h>
+#include <fcntl.h>
#include <paths.h>
#include <sys/wait.h>
static int getindex(const char *words[], const char *word);
static void cmdhelp(int mode, int which);
+static int filelock(const char *filename);
int
* 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
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)
{