Date: Sun, 23 Jun 2002 13:58:40 -0500 From: "Matthew D. Fuller" <fullermd@over-yonder.net> To: "Geoffrey C. Speicher" <geoff@sea-incorporated.com> Cc: freebsd-hackers@freebsd.org, Matt Simerson <freebsd@blockads.com>, Paul Herman <pherman@frenchfries.net>, Oliver Fromme <olli@secnetix.de> Subject: Re: Locking the passwd subsystem (was Re: bug in pw, -STABLE [patch]) Message-ID: <20020623185840.GI81018@over-yonder.net> In-Reply-To: <20020623165602.GF81018@over-yonder.net> References: <20020623135441.GC81018@over-yonder.net> <20020623105835.E29860-300000@sea-incorporated.com> <20020623165602.GF81018@over-yonder.net>
next in thread | previous in thread | raw e-mail | index | archive | help
--Sr1nOIr3CvdE5hEN Content-Type: text/plain; charset=us-ascii Content-Disposition: inline And here's a run at Stage 2. This adapts a subset of programs to use the pid_*() locking supplied. The attached patch updates: <pwd.h>, libutil (libutil.h and pw_util.c), chpass (chpass.c), pw (pw.c), pwd_mkdb (Makefile, pwd_mkdb.8, pwd_mkdb.c), vipw (vipw.c). This does NOT include passwd(1), since that does its dirty work in PAM, which I definately don't feel like delving into. Note that this patch MAY be a little off when applied over the previous patch; I'm working on them in seperate trees, to try and keep the stages discrete. But a little manual fiddling should get them reconciled in short order. -- Matthew Fuller (MF4839) | fullermd@over-yonder.net Systems/Network Administrator | http://www.over-yonder.net/~fullermd/ "The only reason I'm burning my candle at both ends, is because I haven't figured out how to light the middle yet" --Sr1nOIr3CvdE5hEN Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=diffs Index: include/pwd.h =================================================================== RCS file: /usr/cvs/src/include/pwd.h,v retrieving revision 1.12 diff -u -r1.12 pwd.h --- include/pwd.h 9 Jun 2002 19:39:18 -0000 1.12 +++ include/pwd.h 23 Jun 2002 18:16:21 -0000 @@ -66,6 +66,9 @@ #define _PATH_MASTERPASSWD "/etc/master.passwd" #define _MASTERPASSWD "master.passwd" +#define _PATH_PWDLOCK "/var/run/pwd.lock" +#define _MODE_PWDLOCK (S_IRUSR | S_IWUSR) + #define _PATH_MP_DB "/etc/pwd.db" #define _MP_DB "pwd.db" #define _PATH_SMP_DB "/etc/spwd.db" Index: lib/libutil/libutil.h =================================================================== RCS file: /usr/cvs/src/lib/libutil/libutil.h,v retrieving revision 1.37 diff -u -r1.37 libutil.h --- lib/libutil/libutil.h 8 May 2002 00:50:07 -0000 1.37 +++ lib/libutil/libutil.h 23 Jun 2002 18:38:18 -0000 @@ -95,6 +95,8 @@ int pw_init(const char *_dir, const char *_master); char *pw_make(struct passwd *_pw); int pw_mkdb(const char *_user); +int pw_globlock(int); +int pw_globunlock(void); int pw_lock(void); struct passwd *pw_scan(const char *_line, int _flags); const char *pw_tempname(void); @@ -124,6 +126,9 @@ #define FPARSELN_UNESCCOMM 0x04 #define FPARSELN_UNESCREST 0x08 #define FPARSELN_UNESCALL 0x0f + +/* pw_globlock() */ +#define PW_NOBLOCK PID_NOBLOCK /* pw_scan() */ #define PWSCAN_MASTER 0x01 Index: lib/libutil/pw_util.c =================================================================== RCS file: /usr/cvs/src/lib/libutil/pw_util.c,v retrieving revision 1.25 diff -u -r1.25 pw_util.c --- lib/libutil/pw_util.c 8 May 2002 14:52:32 -0000 1.25 +++ lib/libutil/pw_util.c 23 Jun 2002 18:46:19 -0000 @@ -79,6 +79,7 @@ static char passwd_dir[PATH_MAX]; static char tempname[PATH_MAX]; static int initialized; +static int globlocked = 0; void pw_cont(int sig) @@ -163,6 +164,28 @@ } /* + * Lock the password subsystem globally. + */ +int +pw_globlock(int flags) +{ + int retval; + + if( (retval=pid_begin(_PATH_PWDLOCK, _MODE_PWDLOCK, flags)) == 0 ); + globlocked=1; + return(retval); +} + +/* + * Unlock the global lock + */ +int pw_globunlock(void) +{ + + return(pid_end(_PATH_PWDLOCK)); +} + +/* * Lock the master password file. */ int @@ -258,10 +281,10 @@ case 0: /* child */ if (user == NULL) - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-n", "-d", passwd_dir, tempname, NULL); else - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", + execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-n", "-d", passwd_dir, "-u", user, tempname, NULL); _exit(1); default: @@ -353,6 +376,11 @@ } if (lockfd != -1) close(lockfd); + if (globlocked != 0) + { + globlocked=0; + pid_end(_PATH_PWDLOCK); + } errno = serrno; } Index: usr.bin/chpass/chpass.c =================================================================== RCS file: /usr/cvs/src/usr.bin/chpass/chpass.c,v retrieving revision 1.23 diff -u -r1.23 chpass.c --- usr.bin/chpass/chpass.c 8 May 2002 00:54:28 -0000 1.23 +++ usr.bin/chpass/chpass.c 23 Jun 2002 18:42:25 -0000 @@ -258,6 +258,8 @@ case _PWF_FILES: if (pw_init(NULL, NULL)) err(1, "pw_init()"); + if (pw_globlock(PW_NOBLOCK) < 0) + err(1, "pw_globlock()"); if ((pfd = pw_lock()) == -1) { pw_fini(); err(1, "pw_lock()"); Index: usr.sbin/pw/pw.c =================================================================== RCS file: /usr/cvs/src/usr.sbin/pw/pw.c,v retrieving revision 1.26 diff -u -r1.26 pw.c --- usr.sbin/pw/pw.c 9 Jul 2001 09:24:01 -0000 1.26 +++ usr.sbin/pw/pw.c 23 Jun 2002 18:35:28 -0000 @@ -31,8 +31,10 @@ #include <err.h> #include <fcntl.h> +#include <libutil.h> #include <locale.h> #include <paths.h> +#include <pwd.h> #include <sys/wait.h> #include "pw.h" @@ -202,6 +204,12 @@ errx(EX_NOPERM, "you must be root to run this program"); /* + * Grab global lock before doing anything + */ + if(pid_begin(_PATH_PWDLOCK, _MODE_PWDLOCK, PID_NOBLOCK) < 0) + err(EX_UNAVAILABLE, "%s", _PATH_PWDLOCK); + + /* * We should immediately look for the -q 'quiet' switch so that we * don't bother with extraneous errors */ @@ -259,6 +267,10 @@ pw_log(cnf, mode, which, "NIS maps updated"); } } + + /* Release the lock */ + pid_end(_PATH_PWDLOCK); + return ch; } Index: usr.sbin/pwd_mkdb/Makefile =================================================================== RCS file: /usr/cvs/src/usr.sbin/pwd_mkdb/Makefile,v retrieving revision 1.8 diff -u -r1.8 Makefile --- usr.sbin/pwd_mkdb/Makefile 20 Jul 2001 06:20:15 -0000 1.8 +++ usr.sbin/pwd_mkdb/Makefile 23 Jun 2002 18:37:06 -0000 @@ -8,5 +8,9 @@ SRCS= pw_scan.c pwd_mkdb.c CFLAGS+= -I${.CURDIR}/../../lib/libc/gen # for pw_scan.h +DPADD= ${LIBUTIL} +LDADD= -lutil +LDADD= -lutil +DPADD= ${LIBUTIL} .include <bsd.prog.mk> Index: usr.sbin/pwd_mkdb/pwd_mkdb.8 =================================================================== RCS file: /usr/cvs/src/usr.sbin/pwd_mkdb/pwd_mkdb.8,v retrieving revision 1.19 diff -u -r1.19 pwd_mkdb.8 --- usr.sbin/pwd_mkdb/pwd_mkdb.8 16 May 2002 02:28:35 -0000 1.19 +++ usr.sbin/pwd_mkdb/pwd_mkdb.8 23 Jun 2002 18:48:48 -0000 @@ -42,6 +42,7 @@ .Nm .Op Fl C .Op Fl N +.Op Fl n .Op Fl p .Op Fl d Ar directory .Op Fl s Ar cachesize @@ -76,6 +77,13 @@ to exit with an error if it cannot obtain a lock on the file. By default, we block waiting for a lock on the source file. The lock is held through the rebuilding of the database. +.It Fl n +Tell +.Nm +to not attempt to grab the auth subsystem lock. This is really intended +only to be used internally by programs such as +.Xr vipw 8 ; +use with caution. .It Fl p Create a Version 7 style password file and install it into .Pa /etc/passwd . Index: usr.sbin/pwd_mkdb/pwd_mkdb.c =================================================================== RCS file: /usr/cvs/src/usr.sbin/pwd_mkdb/pwd_mkdb.c,v retrieving revision 1.38 diff -u -r1.38 pwd_mkdb.c --- usr.sbin/pwd_mkdb/pwd_mkdb.c 9 Mar 2002 03:52:14 -0000 1.38 +++ usr.sbin/pwd_mkdb/pwd_mkdb.c 23 Jun 2002 18:38:01 -0000 @@ -59,6 +59,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <libutil.h> #include "pw_scan.h" @@ -111,6 +112,7 @@ u_int method, methoduid; int Cflag; int nblock = 0; + int nolock = 0; Cflag = 0; strcpy(prefix, _PATH_PWD); @@ -138,6 +140,9 @@ case 'N': /* do not wait for lock */ nblock = LOCK_NB; break; + case 'n': /* do not globlock */ + nolock = 1; + break; default: usage(); } @@ -178,6 +183,9 @@ if (!(fp = fopen(pname, "r"))) error(pname); + if (nolock != 1) + if(pw_globlock(PW_NOBLOCK) < 0) + error("pw_globlock"); if (flock(fileno(fp), LOCK_EX|nblock) < 0) error("flock"); if (fstat(fileno(fp), &st) < 0) @@ -484,6 +492,10 @@ */ if (fclose(fp) == EOF) error("close fp"); + + if (nolock != 1) + if(pw_globunlock() < 0) + error("pw_globunlock"); exit(0); } Index: usr.sbin/vipw/vipw.c =================================================================== RCS file: /usr/cvs/src/usr.sbin/vipw/vipw.c,v retrieving revision 1.13 diff -u -r1.13 vipw.c --- usr.sbin/vipw/vipw.c 8 May 2002 00:54:28 -0000 1.13 +++ usr.sbin/vipw/vipw.c 23 Jun 2002 18:40:50 -0000 @@ -96,6 +96,10 @@ pw_fini(); err(1, "pw_lock()"); } + if (pw_globlock(PW_NOBLOCK) < 0) { + pw_fini(); + err(1, "pw_globlock()"); + } if ((tfd = pw_tmp(pfd)) == -1) { pw_fini(); err(1, "pw_tmp()"); --Sr1nOIr3CvdE5hEN-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020623185840.GI81018>