We can use uid_from_user(3) and gid_from_group(3) in utilities that
do repeated passwd/group lookups.

This is the final diff.

 - todd

Index: bin/chmod/chmod.c
===================================================================
RCS file: /cvs/src/bin/chmod/chmod.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 chmod.c
--- bin/chmod/chmod.c   28 May 2017 08:03:36 -0000      1.42
+++ bin/chmod/chmod.c   10 Sep 2018 00:46:49 -0000
@@ -293,7 +293,6 @@ done:
 uid_t
 a_uid(const char *s, int silent)
 {
-       struct passwd *pw;
        const char *errstr;
        uid_t uid;
 
@@ -301,8 +300,8 @@ a_uid(const char *s, int silent)
                return ((uid_t)-1);
 
        /* User name was given. */
-       if ((pw = getpwnam(s)) != NULL)
-               return (pw->pw_uid);
+       if (uid_from_user(s, &uid) != -1)
+               return (uid);
 
        /* UID was given. */
        uid = (uid_t)strtonum(s, 0, UID_MAX, &errstr);
@@ -323,7 +322,6 @@ a_uid(const char *s, int silent)
 gid_t
 a_gid(const char *s)
 {
-       struct group *gr;
        const char *errstr;
        gid_t gid;
 
@@ -331,8 +329,8 @@ a_gid(const char *s)
                return ((gid_t)-1);
 
        /* Group name was given. */
-       if ((gr = getgrnam(s)) != NULL)
-               return (gr->gr_gid);
+       if (gid_from_group(s, &gid) != -1)
+               return (gid);
 
        /* GID was given. */
        gid = (gid_t)strtonum(s, 0, GID_MAX, &errstr);
Index: bin/ps/ps.c
===================================================================
RCS file: /cvs/src/bin/ps/ps.c,v
retrieving revision 1.72
diff -u -p -u -r1.72 ps.c
--- bin/ps/ps.c 8 Aug 2018 14:38:31 -0000       1.72
+++ bin/ps/ps.c 10 Sep 2018 00:46:49 -0000
@@ -92,7 +92,6 @@ main(int argc, char *argv[])
        struct kinfo_proc *kp, **kinfo;
        struct varent *vent;
        struct winsize ws;
-       struct passwd *pwd;
        dev_t ttydev;
        pid_t pid;
        uid_t uid;
@@ -217,11 +216,8 @@ main(int argc, char *argv[])
                        break;
                }
                case 'U':
-                       pwd = getpwnam(optarg);
-                       if (pwd == NULL)
+                       if (uid_from_user(optarg, &uid) == -1)
                                errx(1, "%s: no such user", optarg);
-                       uid = pwd->pw_uid;
-                       endpwent();
                        Uflag = xflg = 1;
                        break;
                case 'u':
Index: sbin/fsdb/fsdb.c
===================================================================
RCS file: /cvs/src/sbin/fsdb/fsdb.c,v
retrieving revision 1.31
diff -u -p -u -r1.31 fsdb.c
--- sbin/fsdb/fsdb.c    9 Sep 2016 15:37:14 -0000       1.31
+++ sbin/fsdb/fsdb.c    10 Sep 2018 01:59:26 -0000
@@ -760,7 +760,6 @@ CMDFUNCSTART(chowner)
        int rval = 1;
        uid_t uid;
        char *cp;
-       struct passwd *pwd;
 
        if (!checkactive())
                return 1;
@@ -768,9 +767,7 @@ CMDFUNCSTART(chowner)
        uid = strtoul(argv[1], &cp, 0);
        if (cp == argv[1] || *cp != '\0' ) {
                /* try looking up name */
-               if ((pwd = getpwnam(argv[1]))) {
-                       uid = pwd->pw_uid;
-               } else {
+               if (uid_from_user(argv[1], &uid) == -1) {
                        warnx("bad uid `%s'", argv[1]);
                        return 1;
                }
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.683
diff -u -p -u -r1.683 parse.y
--- sbin/pfctl/parse.y  6 Sep 2018 15:07:33 -0000       1.683
+++ sbin/pfctl/parse.y  10 Sep 2018 02:12:51 -0000
@@ -2965,14 +2965,14 @@ uid             : STRING                        {
                        if (!strcmp($1, "unknown"))
                                $$ = UID_MAX;
                        else {
-                               struct passwd   *pw;
+                               uid_t uid;
 
-                               if ((pw = getpwnam($1)) == NULL) {
+                               if (uid_from_user($1, &uid) == -1) {
                                        yyerror("unknown user %s", $1);
                                        free($1);
                                        YYERROR;
                                }
-                               $$ = pw->pw_uid;
+                               $$ = uid;
                        }
                        free($1);
                }
@@ -3043,14 +3043,14 @@ gid             : STRING                        {
                        if (!strcmp($1, "unknown"))
                                $$ = GID_MAX;
                        else {
-                               struct group    *grp;
+                               gid_t gid;
 
-                               if ((grp = getgrnam($1)) == NULL) {
+                               if (gid_from_group($1, &gid) == -1) {
                                        yyerror("unknown group %s", $1);
                                        free($1);
                                        YYERROR;
                                }
-                               $$ = grp->gr_gid;
+                               $$ = gid;
                        }
                        free($1);
                }
Index: usr.bin/find/function.c
===================================================================
RCS file: /cvs/src/usr.bin/find/function.c,v
retrieving revision 1.45
diff -u -p -u -r1.45 function.c
--- usr.bin/find/function.c     3 Jan 2017 21:31:16 -0000       1.45
+++ usr.bin/find/function.c     10 Sep 2018 00:46:49 -0000
@@ -933,20 +933,17 @@ PLAN *
 c_group(char *gname, char ***ignored, int unused)
 {
        PLAN *new;
-       struct group *g;
        gid_t gid;
     
        ftsoptions &= ~FTS_NOSTAT;
 
-       g = getgrnam(gname);
-       if (g == NULL) {
+       if (gid_from_group(gname, &gid) == -1) {
                const char *errstr;
 
                gid = strtonum(gname, 0, GID_MAX, &errstr);
                if (errstr)
                        errx(1, "-group: %s: no such group", gname);
-       } else
-               gid = g->gr_gid;
+       }
     
        new = palloc(N_GROUP, f_group);
        new->g_data = gid;
@@ -1543,20 +1540,17 @@ PLAN *
 c_user(char *username, char ***ignored, int unused)
 {
        PLAN *new;
-       struct passwd *p;
        uid_t uid;
     
        ftsoptions &= ~FTS_NOSTAT;
 
-       p = getpwnam(username);
-       if (p == NULL) {
+       if (uid_from_user(username, &uid) == -1) {
                const char *errstr;
 
                uid = strtonum(username, 0, UID_MAX, &errstr);
                if (errstr)
                        errx(1, "-user: %s: no such user", username);
-       } else
-               uid = p->pw_uid;
+       }
 
        new = palloc(N_USER, f_user);
        new->u_data = uid;
Index: usr.bin/fstat/fstat.c
===================================================================
RCS file: /cvs/src/usr.bin/fstat/fstat.c,v
retrieving revision 1.93
diff -u -p -u -r1.93 fstat.c
--- usr.bin/fstat/fstat.c       10 Apr 2018 11:09:14 -0000      1.93
+++ usr.bin/fstat/fstat.c       10 Sep 2018 16:52:24 -0000
@@ -159,6 +159,9 @@ main(int argc, char *argv[])
                optstr = "fnop:su:vN:M:";
        }
 
+       /* Keep passwd file open for faster lookups. */
+       setpassent(1);
+
        /*
         * fuser and fstat share three flags: -f, -s and -u.  In both cases
         * -f is a boolean, but for -u fstat wants an argument while fuser
@@ -217,15 +220,17 @@ main(int argc, char *argv[])
                        if (uflg++)
                                usage();
                        if (!fuser) {
-                               if (!(passwd = getpwnam(optarg))) {
-                                       arg = strtonum(optarg, 0, UID_MAX,
+                               uid_t uid;
+
+                               if (uid_from_user(optarg, &uid) == -1) {
+                                       uid = strtonum(optarg, 0, UID_MAX,
                                            &errstr);
                                        if (errstr != NULL) {
                                                errx(1, "%s: unknown uid",
                                                    optarg);
                                        }
-                               } else
-                                       arg = passwd->pw_uid;
+                               }
+                               arg = uid;
                                what = KERN_FILE_BYUID;
                        }
                        break;
Index: usr.bin/newsyslog/newsyslog.c
===================================================================
RCS file: /cvs/src/usr.bin/newsyslog/newsyslog.c,v
retrieving revision 1.108
diff -u -p -u -r1.108 newsyslog.c
--- usr.bin/newsyslog/newsyslog.c       24 Jul 2017 12:57:01 -0000      1.108
+++ usr.bin/newsyslog/newsyslog.c       10 Sep 2018 15:10:55 -0000
@@ -191,6 +191,10 @@ main(int argc, char **argv)
        TAILQ_INIT(&config);
        TAILQ_INIT(&runlist);
 
+       /* Keep passwd and group files open for faster lookups. */
+       setpassent(1);
+       setgroupent(1);
+
        ret = parse_file(&config, &listlen);
        if (argc == 0)
                TAILQ_CONCAT(&runlist, &config, next);
@@ -468,8 +472,6 @@ parse_file(struct entrylist *list, int *
 {
        char line[BUFSIZ], *parse, *q, *errline, *group, *tmp, *ep;
        struct conf_entry *working;
-       struct passwd *pwd;
-       struct group *grp;
        struct stat sb;
        int lineno = 0;
        int ret = 0;
@@ -510,36 +512,28 @@ nextline:
                if ((group = strchr(q, ':')) != NULL ||
                    (group = strrchr(q, '.')) != NULL)  {
                        *group++ = '\0';
-                       if (*q) {
-                               if (!(isnumberstr(q))) {
-                                       if ((pwd = getpwnam(q)) == NULL) {
-                                               warnx("%s:%d: unknown user"
-                                                   " %s --> skipping",
-                                                   conf, lineno, q);
-                                               ret = 1;
-                                               goto nextline;
-                                       }
-                                       working->uid = pwd->pw_uid;
-                               } else
-                                       working->uid = atoi(q);
-                       } else
+                       if (*q == '\0') {
                                working->uid = (uid_t)-1;
+                       } else if (isnumberstr(q)) {
+                               working->uid = atoi(q);
+                       } else if (uid_from_user(q, &working->uid) == -1) {
+                               warnx("%s:%d: unknown user %s --> skipping",
+                                   conf, lineno, q);
+                               ret = 1;
+                               goto nextline;
+                       }
 
                        q = group;
-                       if (*q) {
-                               if (!(isnumberstr(q))) {
-                                       if ((grp = getgrnam(q)) == NULL) {
-                                               warnx("%s:%d: unknown group"
-                                                   " %s --> skipping",
-                                                   conf, lineno, q);
-                                               ret = 1;
-                                               goto nextline;
-                                       }
-                                       working->gid = grp->gr_gid;
-                               } else
-                                       working->gid = atoi(q);
-                       } else
+                       if (*q == '\0') {
                                working->gid = (gid_t)-1;
+                       } else if (isnumberstr(q)) {
+                               working->gid = atoi(q);
+                       } else if (gid_from_group(q, &working->gid) == -1) {
+                               warnx("%s:%d: unknown group %s --> skipping",
+                                   conf, lineno, q);
+                               ret = 1;
+                               goto nextline;
+                       }
 
                        q = parse = missing_field(sob(++parse), errline, 
lineno);
                        *(parse = son(parse)) = '\0';
Index: usr.bin/pkill/pkill.c
===================================================================
RCS file: /cvs/src/usr.bin/pkill/pkill.c,v
retrieving revision 1.39
diff -u -p -u -r1.39 pkill.c
--- usr.bin/pkill/pkill.c       10 Oct 2016 02:22:59 -0000      1.39
+++ usr.bin/pkill/pkill.c       10 Sep 2018 16:15:18 -0000
@@ -544,10 +544,10 @@ static void
 makelist(struct listhead *head, enum listtype type, char *src)
 {
        struct list *li;
-       struct passwd *pw;
-       struct group *gr;
        struct stat st;
        char *sp, *p, buf[PATH_MAX];
+       uid_t uid;
+       gid_t gid;
        int empty;
 
        empty = 1;
@@ -588,14 +588,14 @@ makelist(struct listhead *head, enum lis
 
                switch (type) {
                case LT_USER:
-                       if ((pw = getpwnam(sp)) == NULL)
+                       if (uid_from_user(sp, &uid) == -1)
                                errx(STATUS_BADUSAGE, "unknown user `%s'", sp);
-                       li->li_number = pw->pw_uid;
+                       li->li_number = uid;
                        break;
                case LT_GROUP:
-                       if ((gr = getgrnam(sp)) == NULL)
+                       if (gid_from_group(sp, &gid) == -1)
                                errx(STATUS_BADUSAGE, "unknown group `%s'", sp);
-                       li->li_number = gr->gr_gid;
+                       li->li_number = gid;
                        break;
                case LT_TTY:
                        if (strcmp(sp, "-") == 0) {
Index: usr.bin/top/username.c
===================================================================
RCS file: /cvs/src/usr.bin/top/username.c,v
retrieving revision 1.17
diff -u -p -u -r1.17 username.c
--- usr.bin/top/username.c      26 Oct 2015 13:56:18 -0000      1.17
+++ usr.bin/top/username.c      10 Sep 2018 15:40:26 -0000
@@ -50,10 +50,7 @@ username(uid_t uid)
 uid_t
 userid(char *username)
 {
-       struct passwd *pwd;
+       uid_t uid;
 
-       if ((pwd = getpwnam(username)) == NULL)
-               return ((uid_t)-1);
-
-       return (pwd->pw_uid);
+       return uid_from_user(username, &uid);
 }
Index: usr.bin/xinstall/xinstall.c
===================================================================
RCS file: /cvs/src/usr.bin/xinstall/xinstall.c,v
retrieving revision 1.66
diff -u -p -u -r1.66 xinstall.c
--- usr.bin/xinstall/xinstall.c 21 Aug 2017 21:41:13 -0000      1.66
+++ usr.bin/xinstall/xinstall.c 10 Sep 2018 00:46:49 -0000
@@ -60,14 +60,12 @@
 #define NOCHANGEBITS   (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
 #define BACKUP_SUFFIX  ".old"
 
-struct passwd *pp;
-struct group *gp;
 int dobackup, docompare, dodest, dodir, dopreserve, dostrip, safecopy;
 int mode = S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
 char pathbuf[PATH_MAX], tempfile[PATH_MAX];
 char *suffix = BACKUP_SUFFIX;
-uid_t uid;
-gid_t gid;
+uid_t uid = (uid_t)-1;
+gid_t gid = (gid_t)-1;
 
 void   copy(int, char *, int, char *, off_t, int);
 int    compare(int, const char *, off_t, int, const char *, off_t);
@@ -89,6 +87,7 @@ main(int argc, char *argv[])
        u_int iflags;
        int ch, no_target;
        char *flags, *to_name, *group = NULL, *owner = NULL;
+       const char *errstr;
 
        iflags = 0;
        while ((ch = getopt(argc, argv, "B:bCcDdFf:g:m:o:pSs")) != -1)
@@ -161,12 +160,16 @@ main(int argc, char *argv[])
                safecopy = 1;
 
        /* get group and owner id's */
-       if (group && !(gp = getgrnam(group)) && !isdigit((unsigned char)*group))
-               errx(1, "unknown group %s", group);
-       gid = (group) ? ((gp) ? gp->gr_gid : (gid_t)strtoul(group, NULL, 10)) : 
(gid_t)-1;
-       if (owner && !(pp = getpwnam(owner)) && !isdigit((unsigned char)*owner))
-               errx(1, "unknown user %s", owner);
-       uid = (owner) ? ((pp) ? pp->pw_uid : (uid_t)strtoul(owner, NULL, 10)) : 
(uid_t)-1;
+       if (group != NULL && gid_from_group(group, &gid) == -1) {
+               gid = strtonum(group, 0, GID_MAX, &errstr);
+               if (errstr != NULL)
+                       errx(1, "unknown group %s", group);
+       }
+       if (owner != NULL && uid_from_user(owner, &uid) == -1) {
+               uid = strtonum(owner, 0, UID_MAX, &errstr);
+               if (errstr != NULL)
+                       errx(1, "unknown user %s", owner);
+       }
 
        if (dodir) {
                for (; *argv != NULL; ++argv)
Index: usr.sbin/edquota/edquota.c
===================================================================
RCS file: /cvs/src/usr.sbin/edquota/edquota.c,v
retrieving revision 1.58
diff -u -p -u -r1.58 edquota.c
--- usr.sbin/edquota/edquota.c  26 Apr 2018 12:42:51 -0000      1.58
+++ usr.sbin/edquota/edquota.c  13 Sep 2018 12:36:01 -0000
@@ -191,14 +191,11 @@ main(int argc, char *argv[])
 int
 getentry(char *name, int quotatype, u_int *idp)
 {
-       struct passwd *pw;
-       struct group *gr;
        u_int id;
 
        switch(quotatype) {
        case USRQUOTA:
-               if ((pw = getpwnam(name))) {
-                       *idp = pw->pw_uid;
+               if (uid_from_user(name, idp) != -1) {
                        return 0;
                } else if (alldigits(name)) {
                        if ((id = strtoul(name, NULL, 10)) <= UID_MAX) {
@@ -209,8 +206,7 @@ getentry(char *name, int quotatype, u_in
                warnx("%s: no such user", name);
                break;
        case GRPQUOTA:
-               if ((gr = getgrnam(name))) {
-                       *idp = gr->gr_gid;
+               if (gid_from_group(name, idp) != -1) {
                        return 0;
                } else if (alldigits(name)) {
                        if ((id = strtoul(name, NULL, 10)) <= GID_MAX) {

Reply via email to