On Sat, 13 Oct 2018 16:57:46 +0200, Moritz Buhl wrote:

> I belief this is due to the changes to getpwnam etc.
> Sadly I am unable to figure out, why exactly the call to getpwuid
> segfaults. But replacing it with a call to user_from_uid helped.
> I could not crash the program with other flags that use getpw{nam,uid}.

I think it is safest to use user_from_uid, uid_from_user, group_from_gid
and gid_from_group in all places where the return value of getpw*
and getgr* is unused.

 - todd

Index: usr.sbin/user/user.c
===================================================================
RCS file: /cvs/src/usr.sbin/user/user.c,v
retrieving revision 1.122
diff -u -p -u -r1.122 user.c
--- usr.sbin/user/user.c        26 Sep 2018 14:54:58 -0000      1.122
+++ usr.sbin/user/user.c        14 Oct 2018 03:13:41 -0000
@@ -331,8 +331,9 @@ creategid(char *group, gid_t gid, const 
        int             fd, ret;
        int             wroteit = 0;
        size_t          len;
+       gid_t           tgid;
 
-       if (getgrnam(group) != NULL) {
+       if (gid_from_group(group, &tgid) != -1) {
                warnx("group `%s' already exists", group);
                return 0;
        }
@@ -673,7 +674,7 @@ static int
 getnextgid(uid_t *gidp, uid_t lo, uid_t hi)
 {
        for (*gidp = lo ; *gidp < hi ; *gidp += 1) {
-               if (getgrgid((gid_t)*gidp) == NULL) {
+               if (group_from_gid((gid_t)*gidp, 1) == NULL) {
                        return 1;
                }
        }
@@ -862,9 +863,10 @@ static int
 getnextuid(int sync_uid_gid, uid_t *uid, uid_t low_uid, uid_t high_uid)
 {
        for (*uid = low_uid ; *uid <= high_uid ; (*uid)++) {
-               if (getpwuid((uid_t)(*uid)) == NULL && *uid != NOBODY_UID) {
+               if (user_from_uid((uid_t)(*uid), 1) == NULL &&
+                   *uid != NOBODY_UID) {
                        if (sync_uid_gid) {
-                               if (getgrgid((gid_t)(*uid)) == NULL) {
+                               if (group_from_gid((gid_t)(*uid), 1) == NULL) {
                                        return 1;
                                }
                        } else {
@@ -958,7 +960,8 @@ adduser(char *login_name, user_t *up)
        int             sync_uid_gid;
        int             masterfd;
        int             ptmpfd;
-       gid_t           gid;
+       gid_t           gid, tgid;
+       uid_t           uid;
        int             cc;
        int             i, yp = 0;
        FILE            *fp;
@@ -1048,14 +1051,15 @@ adduser(char *login_name, user_t *up)
                }
        }
        /* check uid isn't already allocated */
-       if (!(up->u_flags & F_DUPUID) && getpwuid((uid_t)(up->u_uid)) != NULL) {
+       if (!(up->u_flags & F_DUPUID) &&
+           user_from_uid((uid_t)(up->u_uid), 1) != NULL) {
                close(ptmpfd);
                pw_abort();
                errx(EXIT_FAILURE, "uid %u is already in use", up->u_uid);
        }
        /* if -g=uid was specified, check gid is unused */
        if (sync_uid_gid) {
-               if (getgrgid((gid_t)(up->u_uid)) != NULL) {
+               if (group_from_gid((gid_t)(up->u_uid), 1) != NULL) {
                        close(ptmpfd);
                        pw_abort();
                        errx(EXIT_FAILURE, "gid %u is already in use", 
up->u_uid);
@@ -1070,7 +1074,8 @@ adduser(char *login_name, user_t *up)
                gid = grp->gr_gid;
        }
        /* check name isn't already in use */
-       if (!(up->u_flags & F_DUPUID) && getpwnam(login_name) != NULL) {
+       if (!(up->u_flags & F_DUPUID) &&
+           uid_from_user(login_name, &uid) != -1) {
                close(ptmpfd);
                pw_abort();
                errx(EXIT_FAILURE, "already a `%s' user", login_name);
@@ -1187,7 +1192,7 @@ adduser(char *login_name, user_t *up)
                }
        }
        if (strcmp(up->u_primgrp, "=uid") == 0 &&
-           getgrnam(login_name) == NULL &&
+           gid_from_group(login_name, &tgid) == -1 &&
            !creategid(login_name, gid, "")) {
                close(ptmpfd);
                pw_abort();
@@ -1369,7 +1374,8 @@ moduser(char *login_name, char *newlogin
        int             ptmpfd;
        int             rval;
        int             i;
-       uid_t   uid;
+       uid_t           uid;
+       gid_t           gid;
 
        if (!valid_login(newlogin)) {
                errx(EXIT_FAILURE, "`%s' is not a valid login name", 
login_name);
@@ -1515,7 +1521,8 @@ moduser(char *login_name, char *newlogin
                }
                if (up->u_flags & F_UID) {
                        /* check uid isn't already allocated */
-                       if (!(up->u_flags & F_DUPUID) && 
getpwuid((uid_t)(up->u_uid)) != NULL) {
+                       if (!(up->u_flags & F_DUPUID) &&
+                           user_from_uid((uid_t)(up->u_uid), 1) != NULL) {
                                close(ptmpfd);
                                pw_abort();
                                errx(EXIT_FAILURE, "uid %u is already in use", 
up->u_uid);
@@ -1525,7 +1532,7 @@ moduser(char *login_name, char *newlogin
                if (up->u_flags & F_GROUP) {
                        /* if -g=uid was specified, check gid is unused */
                        if (strcmp(up->u_primgrp, "=uid") == 0) {
-                               if (getgrgid((gid_t)(pwp->pw_uid)) != NULL) {
+                               if (group_from_gid((gid_t)pwp->pw_uid, 1) != 
NULL) {
                                        close(ptmpfd);
                                        pw_abort();
                                        errx(EXIT_FAILURE, "gid %u is already "
@@ -1639,7 +1646,7 @@ moduser(char *login_name, char *newlogin
                }
                if (up->u_flags & F_SETSECGROUP) {
                        for (i = 0 ; i < up->u_groupc ; i++) {
-                               if (getgrnam(up->u_groupv[i]) == NULL) {
+                               if (gid_from_group(up->u_groupv[i], &gid) == 
-1) {
                                        close(ptmpfd);
                                        pw_abort();
                                        errx(EXIT_FAILURE,
@@ -2117,7 +2124,7 @@ groupadd(int argc, char **argv)
        if (gid < 0 && !getnextgid(&gid, LowGid, HighGid)) {
                errx(EXIT_FAILURE, "can't add group: can't get next gid");
        }
-       if (!dupgid && getgrgid((gid_t) gid) != NULL) {
+       if (!dupgid && group_from_gid((gid_t)gid, 1) != NULL) {
                errx(EXIT_FAILURE, "can't add group: gid %d is a duplicate", 
gid);
        }
        openlog("groupadd", LOG_PID, LOG_USER);
@@ -2133,6 +2140,7 @@ int
 groupdel(int argc, char **argv)
 {
        int     c;
+       gid_t   gid;
 
        while ((c = getopt(argc, argv, "v")) != -1) {
                switch(c) {
@@ -2150,7 +2158,7 @@ groupdel(int argc, char **argv)
        }
        checkeuid();
        openlog("groupdel", LOG_PID, LOG_USER);
-       if (getgrnam(*argv) == NULL) {
+       if (gid_from_group(*argv, &gid) == -1) {
                warnx("No such group: `%s'", *argv);
                return EXIT_FAILURE;
        }

Reply via email to