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) | [EMAIL PROTECTED]
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"
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()");