Skip to content

Commit

Permalink
Merge pull request #421 from AZaugg/issue337
Browse files Browse the repository at this point in the history
Adding new switch -rG to usermod
  • Loading branch information
hallyn committed Dec 14, 2021
2 parents 9a9c923 + aaaaf21 commit f2e8294
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS.md
Expand Up @@ -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>
Expand Down
11 changes: 11 additions & 0 deletions man/usermod.8.xml
Expand Up @@ -326,6 +326,17 @@
</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>
Expand Down
40 changes: 39 additions & 1 deletion src/usermod.c
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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'},
Expand All @@ -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 */
Expand Down Expand Up @@ -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 () */
Expand Down Expand Up @@ -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"),
Expand Down

0 comments on commit f2e8294

Please sign in to comment.