Adding new option -rG to usermod
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
This commit is contained in:
parent
9a9c9231db
commit
aaaaf21b6f
@ -15,6 +15,7 @@ Aleksa Sarai <cyphar@cyphar.com>
|
|||||||
Alexander O. Yuriev <alex@bach.cis.temple.edu>
|
Alexander O. Yuriev <alex@bach.cis.temple.edu>
|
||||||
Algis Rudys <arudys@rice.edu>
|
Algis Rudys <arudys@rice.edu>
|
||||||
Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||||
|
Andy Zaugg <andy.zaugg@gmail.com>
|
||||||
Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
|
Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
|
||||||
Anton Gluck <gluc@midway.uchicago.edu>
|
Anton Gluck <gluc@midway.uchicago.edu>
|
||||||
Arkadiusz Miskiewicz <misiek@pld.org.pl>
|
Arkadiusz Miskiewicz <misiek@pld.org.pl>
|
||||||
|
@ -326,6 +326,17 @@
|
|||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term>
|
<term>
|
||||||
<option>-R</option>, <option>--root</option> <replaceable>CHROOT_DIR</replaceable>
|
<option>-R</option>, <option>--root</option> <replaceable>CHROOT_DIR</replaceable>
|
||||||
|
@ -147,6 +147,7 @@ static bool
|
|||||||
mflg = false, /* create user's home directory if it doesn't exist */
|
mflg = false, /* create user's home directory if it doesn't exist */
|
||||||
oflg = false, /* permit non-unique user ID to be specified with -u */
|
oflg = false, /* permit non-unique user ID to be specified with -u */
|
||||||
pflg = false, /* new encrypted password */
|
pflg = false, /* new encrypted password */
|
||||||
|
rflg = false, /* remove a user from a single group */
|
||||||
sflg = false, /* new shell program */
|
sflg = false, /* new shell program */
|
||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
Zflg = false, /* new selinux user */
|
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"
|
(void) fputs (_(" -a, --append append the user to the supplemental GROUPS\n"
|
||||||
" mentioned by the -G option without removing\n"
|
" mentioned by the -G option without removing\n"
|
||||||
" the user from other groups\n"), usageout);
|
" 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 (_(" -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, --login NEW_LOGIN new value of the login name\n"), usageout);
|
||||||
(void) fputs (_(" -L, --lock lock the user account\n"), usageout);
|
(void) fputs (_(" -L, --lock lock the user account\n"), usageout);
|
||||||
@ -751,6 +755,14 @@ static void update_group (void)
|
|||||||
continue;
|
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);
|
ngrp = __gr_dup (grp);
|
||||||
if (NULL == ngrp) {
|
if (NULL == ngrp) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@ -866,6 +878,14 @@ static void update_gshadow (void)
|
|||||||
continue;
|
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);
|
nsgrp = __sgr_dup (sgrp);
|
||||||
if (NULL == nsgrp) {
|
if (NULL == nsgrp) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
@ -1014,6 +1034,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
{"move-home", no_argument, NULL, 'm'},
|
{"move-home", no_argument, NULL, 'm'},
|
||||||
{"non-unique", no_argument, NULL, 'o'},
|
{"non-unique", no_argument, NULL, 'o'},
|
||||||
{"password", required_argument, NULL, 'p'},
|
{"password", required_argument, NULL, 'p'},
|
||||||
|
{"remove", no_argument, NULL, 'r'},
|
||||||
{"root", required_argument, NULL, 'R'},
|
{"root", required_argument, NULL, 'R'},
|
||||||
{"prefix", required_argument, NULL, 'P'},
|
{"prefix", required_argument, NULL, 'P'},
|
||||||
{"shell", required_argument, NULL, 's'},
|
{"shell", required_argument, NULL, 's'},
|
||||||
@ -1031,7 +1052,7 @@ static void process_flags (int argc, char **argv)
|
|||||||
{NULL, 0, NULL, '\0'}
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
while ((c = getopt_long (argc, argv,
|
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
|
#ifdef ENABLE_SUBIDS
|
||||||
"v:w:V:W:"
|
"v:w:V:W:"
|
||||||
#endif /* ENABLE_SUBIDS */
|
#endif /* ENABLE_SUBIDS */
|
||||||
@ -1141,6 +1162,9 @@ static void process_flags (int argc, char **argv)
|
|||||||
user_pass = optarg;
|
user_pass = optarg;
|
||||||
pflg = true;
|
pflg = true;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
rflg = true;
|
||||||
|
break;
|
||||||
case 'R': /* no-op, handled in process_root_flag () */
|
case 'R': /* no-op, handled in process_root_flag () */
|
||||||
break;
|
break;
|
||||||
case 'P': /* no-op, handled in process_prefix_flag () */
|
case 'P': /* no-op, handled in process_prefix_flag () */
|
||||||
@ -1342,6 +1366,20 @@ static void process_flags (int argc, char **argv)
|
|||||||
usage (E_USAGE);
|
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)) {
|
if ((Lflg && (pflg || Uflg)) || (pflg && Uflg)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: the -L, -p, and -U flags are exclusive\n"),
|
_("%s: the -L, -p, and -U flags are exclusive\n"),
|
||||||
|
Loading…
Reference in New Issue
Block a user