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; }