Skip to content

Commit

Permalink
userdel: --force: Allow the flag to be specified twice, for more gran…
Browse files Browse the repository at this point in the history
…ularity

Previously, with a single --force, one could only chose between not
forcing, and forcing (which could destroy one's system entirely).

Now one can pass --force, with only a small danger, to skip some checks,
and a double --force --force with the meaning of the previous --force,
which will possibly destroy the entire system.

Closes: <shadow-maint#1050>
Reported-by: Matthew Horsfall <wolfsage@gmail.com>
Cc: Lennart Poettering <lennart@poettering.net>
Cc: Serge Hallyn <serge@hallyn.com>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
  • Loading branch information
alejandro-colomar committed Oct 15, 2024
1 parent 0d1faaf commit 372fdbe
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
11 changes: 10 additions & 1 deletion man/userdel.8.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,16 @@
<para>
This option forces the removal of the user account
and any other requested actions,
skipping any safety checks.
skipping safety checks.
</para>
<para>
If specified once,
a user is removed
even if it's still logged in,
and its primary group is removed
even if it's the primary group of another user.
If specified twice,
it skips all safety checks.
</para>
<para>
<emphasis>Note:</emphasis> This option is dangerous and may leave
Expand Down
16 changes: 8 additions & 8 deletions src/userdel.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static uid_t user_id;
static gid_t user_gid;
static char *user_home;

static bool fflg = false;
static int fflg = 0;
static bool rflg = false;
#ifdef WITH_SELINUX
static bool Zflg = false;
Expand Down Expand Up @@ -312,7 +312,7 @@ static void remove_usergroup (void)
return;
}

if (!fflg) {
if (fflg < 1) {
/*
* Scan the passwd file to check if this group is still
* used as a primary group.
Expand Down Expand Up @@ -832,7 +832,7 @@ static int remove_mailbox (void)
}
}

if (fflg) {
if (fflg >= 2) {
if (unlink (mailfile) != 0) {
fprintf (stderr,
_("%s: warning: can't remove %s: %s\n"),
Expand Down Expand Up @@ -997,8 +997,8 @@ int main (int argc, char **argv)
#endif /* !WITH_SELINUX */
long_options, NULL)) != -1) {
switch (c) {
case 'f': /* force remove even if not owned by user */
fflg = true;
case 'f':
fflg++;
break;
case 'h':
usage (E_SUCCESS);
Expand Down Expand Up @@ -1131,7 +1131,7 @@ int main (int argc, char **argv)
* a cron job may be started on her behalf, etc.
*/
if ((prefix[0] == '\0') && !Rflg && user_busy (user_name, user_id) != 0) {
if (!fflg) {
if (fflg < 1) {
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_USER, Prog,
"deleting user logged in",
Expand Down Expand Up @@ -1160,7 +1160,7 @@ int main (int argc, char **argv)
_("%s: %s home directory (%s) not found\n"),
Prog, user_name, user_home);
rflg = 0;
} else if ((0 == home_owned) && !fflg) {
} else if ((0 == home_owned) && fflg < 2) {
fprintf (stderr,
_("%s: %s not owned by %s, not removing\n"),
Prog, user_home, user_name);
Expand All @@ -1172,7 +1172,7 @@ int main (int argc, char **argv)

#ifdef EXTRA_CHECK_HOME_DIR
/* This may be slow, the above should be good enough. */
if (rflg && !fflg) {
if (rflg && fflg < 2) {
struct passwd *pwd;
/*
* For safety, refuse to remove the home directory if it
Expand Down

0 comments on commit 372fdbe

Please sign in to comment.