On 5/19/23 12:24, Todd C. Miller wrote: > If /etc/usermgmt.conf has a line like: > > group =uid > > where a new user's group ID in the passwd file is the same as their > user ID, remove that group when the user is removed. The group is > only removed if it matches the login name, has a gid that matches > the user's uid, and has no other members. > > This makes our userdel(8) behave more like the version on other > systems. > > Opinions? This is something that has always bothered me and can > result in uid/gid mismatches if you remove a user, then re-add them > without removing the login group first. > > Thoughts or strong opinions?
Will this not potentially break people's setups? I like this change though. This would also make the post pkg_delete output simpler by just asking the admin to delete the user, instead of both user and group. > > - todd > > Index: usr.sbin/user/user.c > =================================================================== > RCS file: /cvs/src/usr.sbin/user/user.c,v > retrieving revision 1.131 > diff -u -p -u -r1.131 user.c > --- usr.sbin/user/user.c 18 May 2023 18:29:28 -0000 1.131 > +++ usr.sbin/user/user.c 19 May 2023 16:16:02 -0000 > @@ -193,7 +193,7 @@ static int is_local(char *, const char * > static int modify_gid(char *, char *); > static int moduser(char *, char *, user_t *); > static int removehomedir(const char *, uid_t, const char *); > -static int rm_user_from_groups(char *); > +static int rm_user_from_groups(char *, int); > static int save_range(user_t *, char *); > static int scantime(time_t *, char *); > static int setdefaults(user_t *); > @@ -1308,9 +1308,9 @@ adduser(char *login_name, user_t *up) > return 1; > } > > -/* remove a user from the groups file */ > +/* remove a user from the groups file, optionally removing the login group */ > static int > -rm_user_from_groups(char *login_name) > +rm_user_from_groups(char *login_name, int rm_login_group) > { > struct stat st; > size_t login_len; > @@ -1366,6 +1366,15 @@ rm_user_from_groups(char *login_name) > warnx("Malformed entry `%s'. Skipping", buf); > continue; > } > + if (rm_login_group && strncmp(buf, login_name, login_len) == 0 > + && buf[login_len] == ':') { > + /* remove login group if empty or user is only member */ > + if (*cp == '\n') > + continue; > + if (strncmp(cp, login_name, login_len) == 0 && > + cp [login_len] == '\n') > + continue; > + } > while ((cp = strstr(cp, login_name)) != NULL) { > if ((cp[-1] == ':' || cp[-1] == ',') && > (cp[login_len] == ',' || cp[login_len] == '\n')) { > @@ -1745,7 +1754,7 @@ moduser(char *login_name, char *newlogin > up->u_groupv[i]); > } > } > - if (!rm_user_from_groups(newlogin)) { > + if (!rm_user_from_groups(newlogin, 0)) { > close(ptmpfd); > pw_abort(); > errx(EXIT_FAILURE, > @@ -2101,8 +2110,10 @@ int > userdel(int argc, char **argv) > { > struct passwd *pwp; > + struct group *grp; > user_t u; > int defaultfield; > + int rm_login_group; > int rmhome; > int bigD; > int c; > @@ -2164,7 +2175,15 @@ userdel(int argc, char **argv) > openlog("userdel", LOG_PID, LOG_USER); > return moduser(*argv, *argv, &u) ? EXIT_SUCCESS : EXIT_FAILURE; > } > - if (!rm_user_from_groups(*argv)) { > + rm_login_group = 0; > + if (strcmp(u.u_primgrp, "=uid") == 0 && pwp->pw_uid == pwp->pw_gid) { > + /* remove primary group if it matches the username */ > + grp = getgrgid(pwp->pw_gid); > + if (grp != NULL && strcmp(grp->gr_name, *argv) == 0) { > + rm_login_group = 1; > + } > + } > + if (!rm_user_from_groups(*argv, rm_login_group)) { > return 0; > } > openlog("userdel", LOG_PID, LOG_USER); >