]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
Adding new option -rG to usermod 421/head
authorAndy Zaugg <andy.zaugg@gmail.com>
Thu, 23 Sep 2021 03:29:09 +0000 (20:29 -0700)
committerAndy Zaugg <andy.zaugg@gmail.com>
Tue, 14 Dec 2021 05:42:48 +0000 (21:42 -0800)
Adding a new switch -rG, which provides a similar feature set to
-aG, allowing a person to list exactly what groups to remove a
user from.

https://github.com/shadow-maint/shadow/issues/337

AUTHORS.md
man/usermod.8.xml
src/usermod.c

index 97c709b21ba03224ab2cb5b514b47f7a6fa85b85..32baf05e73eae8225188fbe46f8796f7fc2384e5 100644 (file)
@@ -15,6 +15,7 @@ Aleksa Sarai <cyphar@cyphar.com>
 Alexander O. Yuriev <alex@bach.cis.temple.edu>
 Algis Rudys <arudys@rice.edu>
 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+Andy Zaugg <andy.zaugg@gmail.com>
 Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
 Anton Gluck <gluc@midway.uchicago.edu>
 Arkadiusz Miskiewicz <misiek@pld.org.pl>
index 79f1a5b8e10884b091e0e792478294a66372dca8..f8d9a922509002fd13f2b08e83fbf1542df994fe 100644 (file)
          </para>
        </listitem>
       </varlistentry>
+      <varlistentry>
+       <term>
+         <option>-r</option>, <option>--remove</option>
+       </term>
+       <listitem>
+         <para>
+           Remove the user from named supplementary group(s). Use only with the
+           <option>-G</option> option.
+         </para>
+       </listitem>
+      </varlistentry>
       <varlistentry>
        <term>
          <option>-R</option>, <option>--root</option>&nbsp;<replaceable>CHROOT_DIR</replaceable>
index 1069be1e1a14546c36ea1c0565aa7d2e47ee4257..4e0e88cf24b2409d0c2b000fbf4b2a0a4e8918b1 100644 (file)
@@ -147,6 +147,7 @@ static bool
     mflg = false,              /* create user's home directory if it doesn't exist */
     oflg = false,              /* permit non-unique user ID to be specified with -u */
     pflg = false,              /* new encrypted password */
+    rflg = false,              /* remove a user from a single group */
     sflg = false,              /* new shell program */
 #ifdef WITH_SELINUX
     Zflg = false,              /* new selinux user */
@@ -424,6 +425,9 @@ static /*@noreturn@*/void usage (int status)
        (void) fputs (_("  -a, --append                  append the user to the supplemental GROUPS\n"
                        "                                mentioned by the -G option without removing\n"
                        "                                the user from other groups\n"), usageout);
+       (void) fputs (_("  -r, --remove                  remove the user from only the supplemental GROUPS\n"
+                       "                                mentioned by the -G option without removing\n"
+                       "                                the user from other groups\n"), usageout);
        (void) fputs (_("  -h, --help                    display this help message and exit\n"), usageout);
        (void) fputs (_("  -l, --login NEW_LOGIN         new value of the login name\n"), usageout);
        (void) fputs (_("  -L, --lock                    lock the user account\n"), usageout);
@@ -751,6 +755,14 @@ static void update_group (void)
                        continue;
                }
 
+               /*
+               * If rflg+Gflg  is passed in AKA -rG invert is_member flag, which removes
+               * mentioned groups while leaving the others.
+               */
+               if (Gflg && rflg && was_member) {
+                       is_member = !is_member;
+               }
+
                ngrp = __gr_dup (grp);
                if (NULL == ngrp) {
                        fprintf (stderr,
@@ -866,6 +878,14 @@ static void update_gshadow (void)
                        continue;
                }
 
+               /*
+               * If rflg+Gflg  is passed in AKA -rG invert is_member, to remove targeted
+               * groups while leaving the user apart of groups not mentioned
+               */
+               if (Gflg && rflg && was_member) {
+                       is_member = !is_member;
+               }
+
                nsgrp = __sgr_dup (sgrp);
                if (NULL == nsgrp) {
                        fprintf (stderr,
@@ -1014,6 +1034,7 @@ static void process_flags (int argc, char **argv)
                        {"move-home",    no_argument,       NULL, 'm'},
                        {"non-unique",   no_argument,       NULL, 'o'},
                        {"password",     required_argument, NULL, 'p'},
+                       {"remove",       no_argument,       NULL, 'r'},
                        {"root",         required_argument, NULL, 'R'},
                        {"prefix",       required_argument, NULL, 'P'},
                        {"shell",        required_argument, NULL, 's'},
@@ -1031,7 +1052,7 @@ static void process_flags (int argc, char **argv)
                        {NULL, 0, NULL, '\0'}
                };
                while ((c = getopt_long (argc, argv,
-                                        "abc:d:e:f:g:G:hl:Lmop:R:s:u:UP:"
+                                        "abc:d:e:f:g:G:hl:Lmop:rR:s:u:UP:"
 #ifdef ENABLE_SUBIDS
                                         "v:w:V:W:"
 #endif                         /* ENABLE_SUBIDS */
@@ -1141,6 +1162,9 @@ static void process_flags (int argc, char **argv)
                                user_pass = optarg;
                                pflg = true;
                                break;
+                       case 'r':
+                               rflg = true;
+                               break;
                        case 'R': /* no-op, handled in process_root_flag () */
                                break;
                        case 'P': /* no-op, handled in process_prefix_flag () */
@@ -1342,6 +1366,20 @@ static void process_flags (int argc, char **argv)
                usage (E_USAGE);
        }
 
+       if (rflg && (!Gflg)) {
+               fprintf (stderr,
+                        _("%s: %s flag is only allowed with the %s flag\n"),
+                        Prog, "-r", "-G");
+               usage (E_USAGE);
+       }
+
+       if (rflg && aflg) {
+               fprintf (stderr,
+                        _("%s: %s and %s are mutually exclusive flags\n"),
+                        Prog, "-r", "-a");
+               usage (E_USAGE);
+       }
+
        if ((Lflg && (pflg || Uflg)) || (pflg && Uflg)) {
                fprintf (stderr,
                         _("%s: the -L, -p, and -U flags are exclusive\n"),