Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Sep 1995 21:23:24 +0100 (MET)
From:      guido@gvr.win.tue.nl (Guido van Rooij)
To:        hackers@freebsd.org
Subject:   pwd_mkdb speed up patches: please review and comment
Message-ID:  <199509242023.VAA06416@gvr.win.tue.nl>

next in thread | raw e-mail | index | archive | help
Underneath are patches that try to touch all passwd related utils as
little as possible while speeding up regular password updates 
dramatically.

I'd like you all to look at them and give comments. 

What it does not solve is speeding up vipw. Chpass, chsh, chfn, passwd,
yppasswd will be quicker: on a 486, 66MHz, a 10.000 line password
file update will be limited by the disk transfer time. In my case
it took 1.5 minute. Now it is 15 seconds.

This isn't a real solution for the basic problem. But it makes the
current problems with large password files a bit less painfull.

What I did not do (yet) is change adduser.

-Guido

--- ./usr.bin/passwd/local_passwd.c.orig	Sun Nov  6 22:08:19 1994
+++ ./usr.bin/passwd/local_passwd.c	Sun Sep 10 20:03:48 1995
@@ -154,7 +154,7 @@
 	pw->pw_change = 0;
 	pw_copy(pfd, tfd, pw);
 
-	if (!pw_mkdb())
+	if (!pw_mkdb(uname))
 		pw_error((char *)NULL, 0, 1);
 	return (0);
 }
--- ./usr.bin/chpass/chpass.c.orig	Tue May 30 08:29:36 1995
+++ ./usr.bin/chpass/chpass.c	Fri Sep 22 19:42:57 1995
@@ -187,7 +187,7 @@
 
 	pw_copy(pfd, tfd, pw);
 
-	if (!pw_mkdb())
+	if (!pw_mkdb(pw->pw_name))
 		pw_error((char *)NULL, 0, 1);
 	exit(0);
 }
--- ./usr.sbin/vipw/vipw.c.orig	Tue May 30 05:52:55 1995
+++ ./usr.sbin/vipw/vipw.c	Sun Sep 10 20:17:53 1995
@@ -96,7 +96,7 @@
 			warnx("no changes made");
 			pw_error((char *)NULL, 0, 0);
 		}
-		if (pw_mkdb())
+		if (pw_mkdb((char *)NULL))
 			break;
 		pw_prompt();
 	}
--- ./usr.sbin/vipw/pw_util.c.orig	Tue May 30 05:52:54 1995
+++ ./usr.sbin/vipw/pw_util.c	Fri Sep 22 19:39:07 1995
@@ -138,7 +138,8 @@
 }
 
 int
-pw_mkdb()
+pw_mkdb(username)
+char *username;
 {
 	int pstat;
 	pid_t pid;
@@ -146,7 +147,12 @@
 	warnx("rebuilding the database...");
 	(void)fflush(stderr);
 	if (!(pid = vfork())) {
-		execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+		if(!username) {
+			execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+		} else {
+			execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, 
+				"-u", username, NULL);
+		}
 		pw_error(_PATH_PWD_MKDB, 1, 1);
 	}
 	pid = waitpid(pid, &pstat, 0);
--- ./usr.sbin/vipw/pw_util.h.orig	Thu May 26 07:23:31 1994
+++ ./usr.sbin/vipw/pw_util.h	Sun Sep 10 20:04:57 1995
@@ -37,6 +37,6 @@
 void	pw_error __P((char *, int, int));
 void	pw_init __P((void));
 int	pw_lock __P((void));
-int	pw_mkdb __P((void));
+int	pw_mkdb __P((char *));
 void	pw_prompt __P((void));
 int	pw_tmp __P((void));
--- ./usr.sbin/pwd_mkdb/pwd_mkdb.c.orig	Tue May 30 05:51:22 1995
+++ ./usr.sbin/pwd_mkdb/pwd_mkdb.c	Sun Sep 10 20:14:32 1995
@@ -79,6 +79,7 @@
 
 void	cleanup __P((void));
 void	error __P((char *));
+void	cp __P((char *, char *, mode_t mode));
 void	mv __P((char *, char *));
 int	scan __P((FILE *, struct passwd *));
 void	usage __P((void));
@@ -96,10 +97,12 @@
 	char *p, *t;
 	char buf[MAX(MAXPATHLEN, LINE_MAX * 2)], tbuf[1024];
 	char buf2[MAXPATHLEN];
+	char *username;
+	u_int method;
 
 	strcpy(prefix, _PATH_PWD);
 	makeold = 0;
-	while ((ch = getopt(argc, argv, "d:pv")) != EOF)
+	while ((ch = getopt(argc, argv, "d:pu:v")) != EOF)
 		switch(ch) {
 		case 'd':
 			strcpy(prefix, optarg);
@@ -107,6 +110,9 @@
 		case 'p':			/* create V7 "file.orig" */
 			makeold = 1;
 			break;
+		case 'u':			/* only update this record */
+			username = optarg;
+			break;
 		case 'v':                       /* backward compatible */
 			break;
 		case '?':
@@ -141,8 +147,17 @@
 
 	/* Open the temporary insecure password database. */
 	(void)snprintf(buf, sizeof(buf), "%s/%s.tmp", prefix, _MP_DB);
-	dp = dbopen(buf,
-	    O_RDWR|O_CREAT|O_EXCL, PERM_INSECURE, DB_HASH, &openinfo);
+	if(username) {
+		(void)snprintf(buf2, sizeof(buf2), "%s/%s", prefix, _MP_DB);
+		cp(buf2, buf, PERM_INSECURE);
+		dp = dbopen(buf,
+		    O_RDWR|O_EXCL, PERM_INSECURE, DB_HASH, &openinfo);
+		method = 0;
+	} else {
+		dp = dbopen(buf,
+		    O_RDWR|O_CREAT|O_EXCL, PERM_INSECURE, DB_HASH, &openinfo);
+		method = R_NOOVERWRITE;
+	}
 	if (dp == NULL)
 		error(buf);
 	clean = FILE_INSECURE;
@@ -182,47 +197,49 @@
 		if(pwd.pw_name[0] == '+' || pwd.pw_name[0] == '-')
 			yp_enabled = 1;
 #define	COMPACT(e)	t = e; while (*p++ = *t++);
-		/* Create insecure data. */
-		p = buf;
-		COMPACT(pwd.pw_name);
-		COMPACT("*");
-		memmove(p, &pwd.pw_uid, sizeof(int));
-		p += sizeof(int);
-		memmove(p, &pwd.pw_gid, sizeof(int));
-		p += sizeof(int);
-		memmove(p, &pwd.pw_change, sizeof(time_t));
-		p += sizeof(time_t);
-		COMPACT(pwd.pw_class);
-		COMPACT(pwd.pw_gecos);
-		COMPACT(pwd.pw_dir);
-		COMPACT(pwd.pw_shell);
-		memmove(p, &pwd.pw_expire, sizeof(time_t));
-		p += sizeof(time_t);
-		memmove(p, &pwd.pw_fields, sizeof pwd.pw_fields);
-		p += sizeof pwd.pw_fields;
-		data.size = p - buf;
-
-		/* Store insecure by name. */
-		tbuf[0] = _PW_KEYBYNAME;
-		len = strlen(pwd.pw_name);
-		memmove(tbuf + 1, pwd.pw_name, len);
-		key.size = len + 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
+		if(!username || (strcmp(username, pwd.pw_name) == 0)) {
+			/* Create insecure data. */
+			p = buf;
+			COMPACT(pwd.pw_name);
+			COMPACT("*");
+			memmove(p, &pwd.pw_uid, sizeof(int));
+			p += sizeof(int);
+			memmove(p, &pwd.pw_gid, sizeof(int));
+			p += sizeof(int);
+			memmove(p, &pwd.pw_change, sizeof(time_t));
+			p += sizeof(time_t);
+			COMPACT(pwd.pw_class);
+			COMPACT(pwd.pw_gecos);
+			COMPACT(pwd.pw_dir);
+			COMPACT(pwd.pw_shell);
+			memmove(p, &pwd.pw_expire, sizeof(time_t));
+			p += sizeof(time_t);
+			memmove(p, &pwd.pw_fields, sizeof pwd.pw_fields);
+			p += sizeof pwd.pw_fields;
+			data.size = p - buf;
+
+			/* Store insecure by name. */
+			tbuf[0] = _PW_KEYBYNAME;
+			len = strlen(pwd.pw_name);
+			memmove(tbuf + 1, pwd.pw_name, len);
+			key.size = len + 1;
+			if ((dp->put)(dp, &key, &data, method) == -1)
+				error("put");
 
-		/* Store insecure by number. */
-		tbuf[0] = _PW_KEYBYNUM;
-		memmove(tbuf + 1, &cnt, sizeof(cnt));
-		key.size = sizeof(cnt) + 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
+			/* Store insecure by number. */
+			tbuf[0] = _PW_KEYBYNUM;
+			memmove(tbuf + 1, &cnt, sizeof(cnt));
+			key.size = sizeof(cnt) + 1;
+			if ((dp->put)(dp, &key, &data, method) == -1)
+				error("put");
 
-		/* Store insecure by uid. */
-		tbuf[0] = _PW_KEYBYUID;
-		memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
-		key.size = sizeof(pwd.pw_uid) + 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
+			/* Store insecure by uid. */
+			tbuf[0] = _PW_KEYBYUID;
+			memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
+			key.size = sizeof(pwd.pw_uid) + 1;
+			if ((dp->put)(dp, &key, &data, method) == -1)
+				error("put");
+		}
 
 		/* Store insecure special plus and special minus */
 		if (pwd.pw_name[0] == '+' || pwd.pw_name[0] == '-') {
@@ -235,7 +252,7 @@
 			else
 				minuscnt++;
 			key.size = sizeof(cnt) + 1;
-			if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
+			if ((dp->put)(dp, &key, &data, method) == -1)
 				error("put");
 		}
 
@@ -251,7 +268,7 @@
 		data.size = 1;
 		tbuf[0] = _PW_KEYYPENABLED;
 		key.size = 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((dp->put)(dp, &key, &data, method) == -1)
 			error("put");
 	}
 	/* If we have +@netgroup entries, store the plus counter */
@@ -260,7 +277,7 @@
 		data.size = sizeof(pluscnt);
 		tbuf[0] = _PW_KEYPLUSCNT;
 		key.size = 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((dp->put)(dp, &key, &data, method) == -1)
 			error("put");
 	}
 	/* If we have -@netgroup entries, store the minus counter */
@@ -269,7 +286,7 @@
 		data.size = sizeof(minuscnt);
 		tbuf[0] = _PW_KEYMINUSCNT;
 		key.size = 1;
-		if ((dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((dp->put)(dp, &key, &data, method) == -1)
 			error("put");
 	}
 
@@ -281,8 +298,15 @@
 
 	/* Open the temporary encrypted password database. */
 	(void)snprintf(buf, sizeof(buf), "%s/%s.tmp", prefix, _SMP_DB);
-	edp = dbopen(buf,
-	    O_RDWR|O_CREAT|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
+	if(username) {
+		(void)snprintf(buf2, sizeof(buf2), "%s/%s", prefix, _SMP_DB);
+		cp(buf2, buf, PERM_SECURE);
+		edp = dbopen(buf,
+		    O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
+	} else {
+		edp = dbopen(buf,
+		    O_RDWR|O_CREAT|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
+	}
 	if (!edp)
 		error(buf);
 	clean = FILE_SECURE;
@@ -291,61 +315,63 @@
 	minuscnt = pluscnt = 0;
 	for (cnt = 1; scan(fp, &pwd); ++cnt) {
 
-		/* Create secure data. */
-		p = buf;
-		COMPACT(pwd.pw_name);
-		COMPACT(pwd.pw_passwd);
-		memmove(p, &pwd.pw_uid, sizeof(int));
-		p += sizeof(int);
-		memmove(p, &pwd.pw_gid, sizeof(int));
-		p += sizeof(int);
-		memmove(p, &pwd.pw_change, sizeof(time_t));
-		p += sizeof(time_t);
-		COMPACT(pwd.pw_class);
-		COMPACT(pwd.pw_gecos);
-		COMPACT(pwd.pw_dir);
-		COMPACT(pwd.pw_shell);
-		memmove(p, &pwd.pw_expire, sizeof(time_t));
-		p += sizeof(time_t);
-		memmove(p, &pwd.pw_fields, sizeof pwd.pw_fields);
-		p += sizeof pwd.pw_fields;
-		data.size = p - buf;
-
-		/* Store secure by name. */
-		tbuf[0] = _PW_KEYBYNAME;
-		len = strlen(pwd.pw_name);
-		memmove(tbuf + 1, pwd.pw_name, len);
-		key.size = len + 1;
-		if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
-
-		/* Store secure by number. */
-		tbuf[0] = _PW_KEYBYNUM;
-		memmove(tbuf + 1, &cnt, sizeof(cnt));
-		key.size = sizeof(cnt) + 1;
-		if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
-
-		/* Store secure by uid. */
-		tbuf[0] = _PW_KEYBYUID;
-		memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
-		key.size = sizeof(pwd.pw_uid) + 1;
-		if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
-			error("put");
+		if(!username || (strcmp(username, pwd.pw_name) == 0)) {
+			/* Create secure data. */
+			p = buf;
+			COMPACT(pwd.pw_name);
+			COMPACT(pwd.pw_passwd);
+			memmove(p, &pwd.pw_uid, sizeof(int));
+			p += sizeof(int);
+			memmove(p, &pwd.pw_gid, sizeof(int));
+			p += sizeof(int);
+			memmove(p, &pwd.pw_change, sizeof(time_t));
+			p += sizeof(time_t);
+			COMPACT(pwd.pw_class);
+			COMPACT(pwd.pw_gecos);
+			COMPACT(pwd.pw_dir);
+			COMPACT(pwd.pw_shell);
+			memmove(p, &pwd.pw_expire, sizeof(time_t));
+			p += sizeof(time_t);
+			memmove(p, &pwd.pw_fields, sizeof pwd.pw_fields);
+			p += sizeof pwd.pw_fields;
+			data.size = p - buf;
+
+			/* Store secure by name. */
+			tbuf[0] = _PW_KEYBYNAME;
+			len = strlen(pwd.pw_name);
+			memmove(tbuf + 1, pwd.pw_name, len);
+			key.size = len + 1;
+			if ((dp->put)(edp, &key, &data, method) == -1)
+				error("put");
 
-		/* Store secure special plus and special minus */
-		if (pwd.pw_name[0] == '+' || pwd.pw_name[0] == '-') {
-			tbuf[0] = (pwd.pw_name[0] == '+') ?
-				_PW_KEYPLUSBYNUM : _PW_KEYMINUSBYNUM;
-			memmove(tbuf + 1, (pwd.pw_name[0] == '+') ?
-				&pluscnt : &minuscnt, sizeof(cnt));
-			if (pwd.pw_name[0] == '+')
-				pluscnt++;
-			else
-				minuscnt++;
+			/* Store secure by number. */
+			tbuf[0] = _PW_KEYBYNUM;
+			memmove(tbuf + 1, &cnt, sizeof(cnt));
 			key.size = sizeof(cnt) + 1;
-			if ((dp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
+			if ((dp->put)(edp, &key, &data, method) == -1)
 				error("put");
+
+			/* Store secure by uid. */
+			tbuf[0] = _PW_KEYBYUID;
+			memmove(tbuf + 1, &pwd.pw_uid, sizeof(pwd.pw_uid));
+			key.size = sizeof(pwd.pw_uid) + 1;
+			if ((dp->put)(edp, &key, &data, method) == -1)
+				error("put");
+
+			/* Store secure special plus and special minus */
+			if (pwd.pw_name[0] == '+' || pwd.pw_name[0] == '-') {
+				tbuf[0] = (pwd.pw_name[0] == '+') ?
+					_PW_KEYPLUSBYNUM : _PW_KEYMINUSBYNUM;
+				memmove(tbuf + 1, (pwd.pw_name[0] == '+') ?
+					&pluscnt : &minuscnt, sizeof(cnt));
+				if (pwd.pw_name[0] == '+')
+					pluscnt++;
+				else
+					minuscnt++;
+				key.size = sizeof(cnt) + 1;
+				if ((dp->put)(edp, &key, &data, method) == -1)
+					error("put");
+			}
 		}
 	}
 	/* If YP enabled, set flag. */
@@ -354,7 +380,7 @@
 		data.size = 1;
 		tbuf[0] = _PW_KEYYPENABLED;
 		key.size = 1;
-		if ((edp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((edp->put)(edp, &key, &data, method) == -1)
 			error("put");
 	}
 	/* If we have +@netgroup entries, store the plus counter */
@@ -363,7 +389,7 @@
 		data.size = sizeof(pluscnt);
 		tbuf[0] = _PW_KEYPLUSCNT;
 		key.size = 1;
-		if ((edp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((edp->put)(edp, &key, &data, method) == -1)
 			error("put");
 	}
 	/* If we have -@netgroup entries, store the minus counter */
@@ -372,7 +398,7 @@
 		data.size = sizeof(minuscnt);
 		tbuf[0] = _PW_KEYMINUSCNT;
 		key.size = 1;
-		if ((edp->put)(edp, &key, &data, R_NOOVERWRITE) == -1)
+		if ((edp->put)(edp, &key, &data, method) == -1)
 			error("put");
 	}
 	(void)(edp->close)(edp);
@@ -437,6 +463,37 @@
 }
 
 void
+cp(from, to, mode)
+	char *from, *to;
+	mode_t mode;
+{
+	static char buf[MAXBSIZE];
+	int from_fd, rcount, to_fd, wcount;
+
+	if ((from_fd = open(from, O_RDONLY, 0)) < 0)
+		error(from);
+	if ((to_fd = open(to, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0)
+		error(to);
+	while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) {
+		wcount = write(to_fd, buf, rcount);
+		if (rcount != wcount || wcount == -1) {
+			int sverrno = errno;
+
+			(void)snprintf(buf, sizeof(buf), "%s to %s", from, to);
+			errno = sverrno;
+			error(buf);
+		}
+	}
+	if (rcount < 0) {
+		int sverrno = errno;
+
+		(void)snprintf(buf, sizeof(buf), "%s to %s", from, to);
+		errno = sverrno;
+		error(buf);
+	}
+}
+
+void
 mv(from, to)
 	char *from, *to;
 {
@@ -484,6 +541,6 @@
 usage()
 {
 
-	(void)fprintf(stderr, "usage: pwd_mkdb [-p] [-d <dest dir>] file\n");
+	(void)fprintf(stderr, "usage: pwd_mkdb [-p] [-d <dest dir>] [-u username] file\n");
 	exit(1);
 }
--- ./gnu/usr.sbin/yppasswdd/pw_util.c.orig	Tue May 30 07:05:28 1995
+++ ./gnu/usr.sbin/yppasswdd/pw_util.c	Sun Sep 10 21:06:06 1995
@@ -132,7 +132,8 @@
 }
 
 int
-pw_mkdb()
+pw_mkdb(username)
+char *username;
 {
 	int pstat;
 	pid_t pid;
@@ -140,7 +141,12 @@
 	warnx("rebuilding the database...");
 	(void)fflush(stderr);
 	if (!(pid = vfork())) {
-		execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+		if(!username) {
+			execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
+		} else {
+			execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, 
+				"-u", username, NULL);
+		}
 		pw_error(_PATH_PWD_MKDB, 1, 1);
 	}
 	pid = waitpid(pid, &pstat, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199509242023.VAA06416>