Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding new switch -rG to usermod #421

Merged
merged 1 commit into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
}
hallyn marked this conversation as resolved.
Show resolved Hide resolved

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)) {
AZaugg marked this conversation as resolved.
Show resolved Hide resolved
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