From owner-freebsd-hackers Wed May 15 11: 1:29 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from sea-incorporated.com (caribbean.sea-incorporated.com [209.74.10.130]) by hub.freebsd.org (Postfix) with ESMTP id E9BA737BB2B for ; Wed, 15 May 2002 10:59:50 -0700 (PDT) Received: from localhost (geoff@localhost) by sea-incorporated.com (8.9.3/8.9.3) with ESMTP id NAA59769; Wed, 15 May 2002 13:58:21 -0400 (EDT) (envelope-from geoff@sea-incorporated.com) Date: Wed, 15 May 2002 13:58:21 -0400 (EDT) From: "Geoffrey C. Speicher" To: "Matthew D. Fuller" Cc: Matt Simerson , freebsd-hackers@freebsd.org Subject: Re: bug in pw, freebsd 4.5 [patch] In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Mon, 13 May 2002, Geoffrey C. Speicher wrote: > On Thu, 2 May 2002, Matthew D. Fuller wrote: > > > I'll see if I can put some time over the next few days into delving into > > it and at least getting the first step (of making the locking work more > > usefully) work. > > Hi Matt. Just wondering if you've made any progress on making pw use a > lockfile. Is there anything I can do to help? OK, I'm answering my own question. Please review the two patches below and provide feedback. They appear to work for me. Some notes: 1. The lock isn't very fine-grained. We grab one giant lock before doing any operations at all, and let it go right before we exit. The alternative is to lock /etc/master.passwd and /etc/group individually, only when they're updated, but I saw no point in going that far. 2. The lockfile is /var/run/pw.lock and it always contains the pid of the pw process that most recently grabbed the lock. 3. The lockfile is never deleted, because doing so seemed to cause a race condition between the time the file is closed and unlinked, leading to password file corruption again. If anyone has a solution to this, please speak up. 4. Should this thread be moved to -stable? 5. To test, backup your /etc/master.passwd and /etc/group, and then try something like this, several times with the old pw to verify consistent breakage, and then several times with the new pw to verify that it doesn't break anymore. # in one terminal, run this first i=0 while [ $i -le 1000 ]; do pw add user testuser$i i=$(($i+1)) done # in another terminal, wait about 10-15 seconds and then run this # (or tail -f /etc/master.passwd and run it when testuser500 shows up) i=0 while [ $i -le 500 ]; do pw del user testuser$i i=$(($i+1)) done Geoff --- pwupd.h.orig Tue May 14 22:06:37 2002 +++ pwupd.h Wed May 15 13:35:14 2002 @@ -110,6 +110,12 @@ #ifndef _GROUP #define _GROUP "group" #endif +#ifndef _PWLOCK +#define _PWLOCK "/var/run/pw.lock" +#endif +#ifndef _LOCK_FILE_MODE +#define _LOCK_FILE_MODE (S_IRUSR | S_IWUSR) +#endif __BEGIN_DECLS int addpwent __P((struct passwd * pwd)); --- pw.c.orig Wed May 15 13:35:21 2002 +++ pw.c Wed May 15 13:37:53 2002 @@ -98,10 +98,12 @@ main(int argc, char *argv[]) { int ch; + int lockfd; int mode = -1; int which = -1; char *config = NULL; struct userconf *cnf; + char *pidstr; static const char *opts[W_NUM][M_NUM] = { @@ -202,6 +204,17 @@ errx(EX_NOPERM, "you must be root to run this program"); /* + * Gain exclusive lock before updating any files + */ + lockfd = open(_PWLOCK, O_WRONLY | O_CREAT | O_EXLOCK, _LOCK_FILE_MODE); + if (lockfd == -1) + err(EX_UNAVAILABLE, "%s", _PWLOCK); + + ftruncate(lockfd,0); + write(lockfd, pidstr, asprintf(&pidstr, "%d", getpid())); + free(pidstr); + + /* * We should immediately look for the -q 'quiet' switch so that we * don't bother with extraneous errors */ @@ -226,7 +239,7 @@ setgrdir(etcpath); } } - + /* * Now, let's do the common initialisation */ @@ -259,6 +272,12 @@ pw_log(cnf, mode, which, "NIS maps updated"); } } + + /* + * Release the lock + */ + close(lockfd); + return ch; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message