Hi,

lately I was reading on misc@ [1] that there's no way to remove a user
from secondary groups but by hand. I also searched for a PR but couldn't
find one. The attached diff remedies the problem:

# id test
uid=1001(test) gid=10(users) groups=10(users), 9(wsrc), 69(network),
117(dialer)
# usermod -G wsrc,network test
# id test
uid=1001(test) gid=10(users) groups=10(users), 9(wsrc), 69(network)
# usermod -G wsrc,network,dialer test
# id test
uid=1001(test) gid=10(users) groups=10(users), 9(wsrc), 69(network),
117(dialer)

I actually copied the code from rm_user_from_groups() which makes it a
bit redundant, but I don't think it's worth writing a own function for
it.

As I am a total C newbie I'm thrilled to hear some comments :-)

[1]  http://marc.info/?l=openbsd-misc&m=130073011016781&w=2

Frank.

Index: usr.sbin/user/user.c
===================================================================
RCS file: /cvs/src/usr.sbin/user/user.c,v
retrieving revision 1.79
diff -u -r1.79 user.c
--- usr.sbin/user/user.c        6 Apr 2011 11:36:26 -0000       1.79
+++ usr.sbin/user/user.c        8 Apr 2011 17:49:45 -0000
@@ -491,28 +491,24 @@
 {
        struct group    *grp;
        struct stat     st;
+       size_t          login_len;
        FILE            *from;
        FILE            *to;
        char            buf[LINE_MAX];
        char            f[MaxFileNameLen];
        char            *colon;
+       char            *cp;
+       char            *ep;
        int             fd;
        int             cc;
        int             i;
        int             j;

+       login_len = strlen(user);
        for (i = 0 ; i < ngroups ; i++) {
-               if ((grp = getgrnam(groups[i])) == NULL) {
+               if ((grp = getgrnam(groups[i])) == NULL)
                        warnx("can't append group `%s' for user `%s'",
                            groups[i], user);
-               } else {
-                       for (j = 0 ; grp->gr_mem[j] ; j++) {
-                               if (strcmp(user, grp->gr_mem[j]) == 0) {
-                                       /* already in it */
-                                       groups[i] = "";
-                               }
-                       }
-               }
        }
        if ((from = fopen(_PATH_GROUP, "r")) == NULL) {
                warn("can't append group for `%s': can't open `%s'", user,
@@ -549,6 +545,35 @@
                        warnx("badly formed entry `%s'", buf);
                        continue;
                }
+
+               /* remove user from group */
+               for (cp = buf, cc = 0; *cp != '\0' && cc < 3; cp++) {
+                       if (*cp == ':')
+                           cc++;
+               }
+               if (cc != 3) {
+                       buf[strcspn(buf, "\n")] = '\0';
+                       warnx("Malformed entry `%s'. Skipping", buf);
+                       continue;
+               }
+               while ((cp = strstr(cp, user)) != NULL) {
+                       if ((cp[-1] == ':' || cp[-1] == ',') &&
+                           (cp[login_len] == ',' || cp[login_len] == '\n')) {
+                               ep = cp + login_len;
+                               if (cp[login_len] == ',')
+                                       ep++;
+                               else if (cp[-1] == ',')
+                                       cp--;
+                               memmove(cp, ep, strlen(ep) + 1);
+                       } else {
+                               if ((cp = strchr(cp, ',')) == NULL)
+                                       break;
+                               cp++;
+                       }
+               }
+               cc = strlen(buf);
+
+               /* add user to groups */
                for (i = 0 ; i < ngroups ; i++) {
                        j = (int)(colon - buf);
                        if (strncmp(groups[i], buf, j) == 0 &&

--
Frank Brodbeck <[email protected]>

Reply via email to