Skip site navigation (1)Skip section navigation (2)
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>