1 /* vi: set sw=4 ts=4: */
3 * deluser/delgroup implementation for busybox
5 * Copyright (C) 1999 by Lineo, inc. and John Beppu
6 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
9 * Licensed under GPLv2, see file LICENSE in this source tree.
11 //config:config DELUSER
12 //config: bool "deluser (9.3 kb)"
15 //config: Utility for deleting a user account.
17 //config:config DELGROUP
18 //config: bool "delgroup (6.6 kb)"
21 //config: Utility for deleting a group account.
23 //config:config FEATURE_DEL_USER_FROM_GROUP
24 //config: bool "Support removing users from groups"
26 //config: depends on DELGROUP
28 //config: If called with two non-option arguments, deluser
29 //config: or delgroup will remove an user from a specified group.
31 // APPLET_NOEXEC:name main location suid_type help
32 //applet:IF_DELUSER( APPLET_NOEXEC(deluser, deluser, BB_DIR_USR_SBIN, BB_SUID_DROP, deluser))
33 //applet:IF_DELGROUP(APPLET_NOEXEC(delgroup, deluser, BB_DIR_USR_SBIN, BB_SUID_DROP, delgroup))
35 //kbuild:lib-$(CONFIG_DELUSER) += deluser.o
36 //kbuild:lib-$(CONFIG_DELGROUP) += deluser.o
38 //usage:#define deluser_trivial_usage
39 //usage: IF_LONG_OPTS("[--remove-home] ") "USER"
40 //usage:#define deluser_full_usage "\n\n"
41 //usage: "Delete USER from the system"
42 // --remove-home is self-explanatory enough to put it in --help
44 //usage:#define delgroup_trivial_usage
45 //usage: IF_FEATURE_DEL_USER_FROM_GROUP("[USER] ")"GROUP"
46 //usage:#define delgroup_full_usage "\n\n"
47 //usage: "Delete group GROUP from the system"
48 //usage: IF_FEATURE_DEL_USER_FROM_GROUP(" or user USER from group GROUP")
52 int deluser_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
53 int deluser_main(int argc
, char **argv
)
55 /* User or group name */
57 /* Username (non-NULL only in "delgroup USER GROUP" case) */
59 /* Name of passwd or group file */
61 /* Name of shadow or gshadow file */
63 /* Are we deluser or delgroup? */
64 int do_deluser
= (ENABLE_DELUSER
&& (!ENABLE_DELGROUP
|| applet_name
[3] == 'u'));
67 const int opt_delhome
= 0;
71 opt_delhome
= getopt32long(argv
, "",
72 "remove-home\0" No_argument
"\xff");
79 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root
);
86 if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP
|| do_deluser
)
88 /* It's "delgroup USER GROUP" */
98 pw
= xgetpwnam(name
); /* bail out if USER is wrong */
99 pfile
= bb_path_passwd_file
;
100 if (ENABLE_FEATURE_SHADOWPASSWDS
)
101 sfile
= bb_path_shadow_file
;
105 /* Make sure home is an actual directory before
106 * removing it (e.g. users with /dev/null as home) */
107 if (stat(pw
->pw_dir
, &st
) == 0 && S_ISDIR(st
.st_mode
))
108 remove_file(pw
->pw_dir
, FILEUTILS_RECUR
);
113 /* "delgroup GROUP" or "delgroup USER GROUP" */
114 if (do_deluser
< 0) { /* delgroup after deluser? */
119 gr
= xgetgrnam(name
); /* bail out if GROUP is wrong */
122 /* "delgroup GROUP" */
124 /* Check if the group is in use */
125 while ((pw
= getpwent()) != NULL
) {
126 if (pw
->pw_gid
== gr
->gr_gid
)
127 bb_error_msg_and_die("'%s' still has '%s' as their primary group!",
132 pfile
= bb_path_group_file
;
133 if (ENABLE_FEATURE_SHADOWPASSWDS
)
134 sfile
= bb_path_gshadow_file
;
137 /* Modify pfile, then sfile */
139 if (update_passwd(pfile
, name
, NULL
, member
) == -1)
141 if (ENABLE_FEATURE_SHADOWPASSWDS
) {
145 } while (ENABLE_FEATURE_SHADOWPASSWDS
&& pfile
);
147 if (do_deluser
> 0) {
148 /* Delete user from all groups */
149 if (update_passwd(bb_path_group_file
, NULL
, NULL
, name
) == -1)
152 if (ENABLE_DELGROUP
) {
153 /* "deluser USER" also should try to delete
154 * same-named group. IOW: do "delgroup USER"
156 // On debian deluser is a perl script that calls userdel.
158 // If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will
159 // delete the group with the same name as the user.
166 /* Reached only if number of command line args is wrong */