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) {