Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/pwd_mkdb Speed things up a bit. Parts dredged from ...



details:   https://anonhg.NetBSD.org/src/rev/c75e1bc21d88
branches:  trunk
changeset: 513959:c75e1bc21d88
user:      ad <ad%NetBSD.org@localhost>
date:      Sat Aug 18 19:29:31 2001 +0000

description:
Speed things up a bit. Parts dredged from OpenBSD/FreeBSD.

- Add -u option, to update one user's records only.
- Add -s option, to update the secure database only.
- Give us roughly 1MB of cache per 50kB of password file, but keep within
  a 2MB minimum and 8MB maximum.
- Tidy a little.

diffstat:

 usr.sbin/pwd_mkdb/pwd_mkdb.8 |   40 ++-
 usr.sbin/pwd_mkdb/pwd_mkdb.c |  533 +++++++++++++++++++++++++++++++++---------
 2 files changed, 444 insertions(+), 129 deletions(-)

diffs (truncated from 795 to 300 lines):

diff -r 54e9db5a0c5d -r c75e1bc21d88 usr.sbin/pwd_mkdb/pwd_mkdb.8
--- a/usr.sbin/pwd_mkdb/pwd_mkdb.8      Sat Aug 18 17:10:04 2001 +0000
+++ b/usr.sbin/pwd_mkdb/pwd_mkdb.8      Sat Aug 18 19:29:31 2001 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: pwd_mkdb.8,v 1.16 2001/07/06 18:07:15 abs Exp $
+.\"    $NetBSD: pwd_mkdb.8,v 1.17 2001/08/18 19:29:31 ad Exp $
 .\"
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -41,8 +41,9 @@
 .Nd "generate the password databases"
 .Sh SYNOPSIS
 .Nm
-.Op Fl pBL
+.Op Fl BLps
 .Op Fl d Ar directory
+.Op Fl u Ar username
 .Ar file
 .Sh DESCRIPTION
 .Nm
@@ -63,18 +64,28 @@
 .Pp
 The options are as follows:
 .Bl -tag -width flag
-.It Fl p
-Create a Version 7 style password file and install it into
-.Dq Pa /etc/passwd .
+.It Fl B
+Store data in big-endian format.
+.It Fl L
+Store data in little-endian format.
 .It Fl d Ar directory
 Change the root directory of the generated files from
 .Dq Pa /
 to
 .Ar directory .
-.It Fl B
-Store data in big-endian format.
-.It Fl L
-Store data in little-endian format.
+.It Fl p
+Create a Version 7 style password file and install it into
+.Dq Pa /etc/passwd .
+.It Fl s
+Update the secure database only.  This is useful when only encrypted
+passwords have changed.  This option negates the effect of any
+.Fl p
+option.
+.It Fl u Ar name
+Don't re-build the database files, but instead modify or add entries for the
+specified user only.  This option may only be used when the line number and
+user name in the password file have not changed, or when adding new user
+from the last line in the password file.
 .El
 .Pp
 The two databases differ in that the secure version contains the user's 
@@ -146,3 +157,14 @@
 .Xr userdel 8 ,
 .Xr usermod 8 ,
 .Xr vipw 8
+.Sh BUGS
+The database format should be changed so that inserting or removing records
+from arbitrary locations in the password file is possible.
+.Pp
+Strange things can happen when the
+.Fl u
+option is used and multiple users share the same UID.
+.Pp
+The database files are copied when the
+.Fl u
+option is used.  Locking would make this unnecessary.
diff -r 54e9db5a0c5d -r c75e1bc21d88 usr.sbin/pwd_mkdb/pwd_mkdb.c
--- a/usr.sbin/pwd_mkdb/pwd_mkdb.c      Sat Aug 18 17:10:04 2001 +0000
+++ b/usr.sbin/pwd_mkdb/pwd_mkdb.c      Sat Aug 18 19:29:31 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pwd_mkdb.c,v 1.21 2000/11/20 14:09:36 tron Exp $       */
+/*     $NetBSD: pwd_mkdb.c,v 1.22 2001/08/18 19:29:32 ad Exp $ */
 
 /*
  * Copyright (c) 1991, 1993, 1994
@@ -41,7 +41,7 @@
 Copyright (c) 1991, 1993, 1994\n\
        The Regents of the University of California.  All rights reserved.\n");
 __SCCSID("from: @(#)pwd_mkdb.c 8.5 (Berkeley) 4/20/94");
-__RCSID("$NetBSD: pwd_mkdb.c,v 1.21 2000/11/20 14:09:36 tron Exp $");
+__RCSID("$NetBSD: pwd_mkdb.c,v 1.22 2001/08/18 19:29:32 ad Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -60,58 +60,81 @@
 #include <unistd.h>
 #include <util.h>
 
-#define        INSECURE        1
-#define        SECURE          2
+#define        MAX_CACHESIZE   8*1024*1024
+#define        MIN_CACHESIZE   2*1024*1024
+
 #define        PERM_INSECURE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
 #define        PERM_SECURE     (S_IRUSR | S_IWUSR)
 
-/* pull this out of the C library. */
+/* Pull this out of the C library. */
 extern const char __yp_token[];
 
 HASHINFO openinfo = {
        4096,           /* bsize */
        32,             /* ffactor */
        256,            /* nelem */
-       2048 * 1024,    /* cachesize */
+       0,              /* cachesize */
        NULL,           /* hash() */
        0               /* lorder */
 };
 
-static enum { FILE_INSECURE, FILE_SECURE, FILE_ORIG } clean;
-static char *pname;                            /* password file name */
-static char prefix[MAXPATHLEN];
-static char oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)];
-static char pwd_db_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
-static char pwd_Sdb_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
-static int lorder = BYTE_ORDER;
+#define        FILE_INSECURE   0x01
+#define        FILE_SECURE     0x02
+#define        FILE_ORIG       0x04
+
+static char    *pname;                         /* password file name */
+static char    prefix[MAXPATHLEN];
+static char    oldpwdfile[MAX(MAXPATHLEN, LINE_MAX * 2)];
+static char    pwd_db_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
+static char    pwd_Sdb_tmp[MAX(MAXPATHLEN, LINE_MAX * 2)];
+static int     lorder = BYTE_ORDER;
+static int     clean;
 
-void   cleanup(void);
+void   bailout(void);
+void   cp(const char *, const char *, mode_t);
+int    deldbent(DB *, const char *, int, void *);
 void   error(const char *);
-void   wr_error(const char *);
+int    getdbent(DB *, const char *, int, void *, struct passwd **);
+void   inconsistancy(void);
+void   install(const char *, const char *);
 int    main(int, char **);
-void   install(const char *, const char *);
+void   putdbents(DB *, struct passwd *, const char *, int, const char *, int,
+                 int, int);
+void   putyptoken(DB *, const char *);
 void   rm(const char *);
 int    scan(FILE *, struct passwd *, int *, int *);
 void   usage(void);
-void   putdbent(DB *, struct passwd *, const char *, int, const char *, int);
-void   putyptoken(DB *dp, const char *fn);
+void   wr_error(const char *);
 
 int
 main(int argc, char *argv[])
 {
+       int ch, makeold, tfd, lineno, found, rv, hasyp, secureonly;
+       struct passwd pwd, *tpwd;
+       char *username;
        DB *dp, *edp;
        FILE *fp, *oldfp;
        sigset_t set;
-       int ch, makeold, tfd, hasyp, flags, lineno;
-       struct passwd pwd;
+       int dbflg, uid_dbflg, newuser, olduid, flags;
+       char buf[MAXPATHLEN];
+       struct stat st;
+       u_int cachesize;
 
-       hasyp = 0;
-       oldfp = NULL;
        prefix[0] = '\0';
        makeold = 0;
-       
-       while ((ch = getopt(argc, argv, "d:pvBL")) != -1)
-               switch(ch) {
+       oldfp = NULL;
+       username = NULL;
+       hasyp = 0;
+       secureonly = 0;
+
+       while ((ch = getopt(argc, argv, "BLd:psu:v")) != -1)
+               switch (ch) {
+               case 'B':                       /* big-endian output */
+                       lorder = BIG_ENDIAN;
+                       break;
+               case 'L':                       /* little-endian output */
+                       lorder = LITTLE_ENDIAN;
+                       break;
                case 'd':                       /* set prefix */
                        strncpy(prefix, optarg, sizeof(prefix));
                        prefix[sizeof(prefix)-1] = '\0';
@@ -119,13 +142,13 @@
                case 'p':                       /* create V7 "file.orig" */
                        makeold = 1;
                        break;
-               case 'v':                       /* backward compatible */
+               case 's':                       /* modify secure db only */
+                       secureonly = 1;
                        break;
-               case 'B':                       /* big-endian output */
-                       lorder = BIG_ENDIAN;
+               case 'u':                       /* modify one user only */
+                       username = optarg;
                        break;
-               case 'L':                       /* little-endian output */
-                       lorder = LITTLE_ENDIAN;
+               case 'v':                       /* backward compatible */
                        break;
                case '?':
                default:
@@ -136,6 +159,11 @@
 
        if (argc != 1)
                usage();
+       if (username != NULL)
+               if (username[0] == '+' || username[0] == '-')
+                       usage();
+       if (secureonly)
+               makeold = 0;
 
        /*
         * This could be changed to allow the user to interrupt.
@@ -152,6 +180,11 @@
        /* We don't care what the user wants. */
        (void)umask(0);
 
+       if (username == NULL)
+               flags = O_RDWR | O_CREAT | O_EXCL;
+       else
+               flags = O_RDWR;
+
        pname = *argv;
        /* Open the original password file */
        if ((fp = fopen(pname, "r")) == NULL)
@@ -159,14 +192,43 @@
 
        openinfo.lorder = lorder;
 
+       if (fstat(fileno(fp), &st) == -1)
+               error(pname);
+
+       /* Tweak openinfo values for large passwd files. */
+       cachesize = st.st_size * 20;
+       if (cachesize > MAX_CACHESIZE)
+               cachesize = MAX_CACHESIZE;
+       else if (cachesize < MIN_CACHESIZE)
+               cachesize = MIN_CACHESIZE;
+       openinfo.cachesize = cachesize;
+
        /* Open the temporary insecure password database. */
-       (void)snprintf(pwd_db_tmp, sizeof(pwd_db_tmp), "%s%s.tmp", prefix,
-           _PATH_MP_DB);
-       dp = dbopen(pwd_db_tmp, O_RDWR | O_CREAT | O_EXCL, PERM_INSECURE,
-           DB_HASH, &openinfo);
-       if (dp == NULL)
-               error(pwd_db_tmp);
-       clean = FILE_INSECURE;
+       if (!secureonly) {
+               (void)snprintf(pwd_db_tmp, sizeof(pwd_db_tmp), "%s%s.tmp",
+                   prefix, _PATH_MP_DB);
+               if (username != NULL) {
+                       snprintf(buf, sizeof(buf), "%s" _PATH_MP_DB, prefix);
+                       cp(buf, pwd_db_tmp, PERM_INSECURE);
+               }
+               dp = dbopen(pwd_db_tmp, flags, PERM_INSECURE, DB_HASH,
+                   &openinfo);
+               if (dp == NULL)
+                       error(pwd_db_tmp);
+               clean |= FILE_INSECURE;
+       }
+
+       /* Open the temporary encrypted password database. */
+       (void)snprintf(pwd_Sdb_tmp, sizeof(pwd_Sdb_tmp), "%s%s.tmp", prefix,
+               _PATH_SMP_DB);
+       if (username != NULL) {
+               snprintf(buf, sizeof(buf), "%s" _PATH_SMP_DB, prefix);
+               cp(buf, pwd_Sdb_tmp, PERM_SECURE);
+       }
+       edp = dbopen(pwd_Sdb_tmp, flags, PERM_SECURE, DB_HASH, &openinfo);
+       if (!edp)
+               error(pwd_Sdb_tmp);
+       clean |= FILE_SECURE;
 
        /*
         * Open file for old password file.  Minor trickiness -- don't want to
@@ -181,9 +243,29 @@
                if ((tfd = open(oldpwdfile, O_WRONLY | O_CREAT | O_EXCL,
                    PERM_INSECURE)) < 0)
                        error(oldpwdfile);
+               clean |= FILE_ORIG;
                if ((oldfp = fdopen(tfd, "w")) == NULL)
                        error(oldpwdfile);
-               clean = FILE_ORIG;
+       }
+
+       if (username != NULL) {
+               uid_dbflg = 0;



Home | Main Index | Thread Index | Old Index