blob: ee60efcb2180c6f42995aadfbd0c4edc7ba3e5dc
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * deluser/delgroup implementation for busybox |
4 | * |
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> |
8 | * |
9 | * Licensed under GPLv2, see file LICENSE in this source tree. |
10 | * |
11 | */ |
12 | |
13 | //usage:#define deluser_trivial_usage |
14 | //usage: "USER" |
15 | //usage:#define deluser_full_usage "\n\n" |
16 | //usage: "Delete USER from the system" |
17 | |
18 | //usage:#define delgroup_trivial_usage |
19 | //usage: IF_FEATURE_DEL_USER_FROM_GROUP("[USER] ")"GROUP" |
20 | //usage:#define delgroup_full_usage "\n\n" |
21 | //usage: "Delete group GROUP from the system" |
22 | //usage: IF_FEATURE_DEL_USER_FROM_GROUP(" or user USER from group GROUP") |
23 | |
24 | #include "libbb.h" |
25 | |
26 | int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
27 | int deluser_main(int argc, char **argv) |
28 | { |
29 | /* User or group name */ |
30 | char *name; |
31 | /* Username (non-NULL only in "delgroup USER GROUP" case) */ |
32 | char *member; |
33 | /* Name of passwd or group file */ |
34 | const char *pfile; |
35 | /* Name of shadow or gshadow file */ |
36 | const char *sfile; |
37 | /* Are we deluser or delgroup? */ |
38 | int do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u')); |
39 | |
40 | if (geteuid() != 0) |
41 | bb_error_msg_and_die("%s", bb_msg_perm_denied_are_you_root); |
42 | |
43 | name = argv[1]; |
44 | member = NULL; |
45 | |
46 | switch (argc) { |
47 | case 3: |
48 | if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser) |
49 | break; |
50 | /* It's "delgroup USER GROUP" */ |
51 | member = name; |
52 | name = argv[2]; |
53 | /* Fallthrough */ |
54 | |
55 | case 2: |
56 | if (do_deluser) { |
57 | /* "deluser USER" */ |
58 | xgetpwnam(name); /* bail out if USER is wrong */ |
59 | pfile = bb_path_passwd_file; |
60 | if (ENABLE_FEATURE_SHADOWPASSWDS) |
61 | sfile = bb_path_shadow_file; |
62 | } else { |
63 | struct group *gr; |
64 | do_delgroup: |
65 | /* "delgroup GROUP" or "delgroup USER GROUP" */ |
66 | if (do_deluser < 0) { /* delgroup after deluser? */ |
67 | gr = getgrnam(name); |
68 | if (!gr) |
69 | return EXIT_SUCCESS; |
70 | } else { |
71 | gr = xgetgrnam(name); /* bail out if GROUP is wrong */ |
72 | } |
73 | if (!member) { |
74 | /* "delgroup GROUP" */ |
75 | struct passwd *pw; |
76 | struct passwd pwent; |
77 | /* Check if the group is in use */ |
78 | #define passwd_buf bb_common_bufsiz1 |
79 | while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) { |
80 | if (pwent.pw_gid == gr->gr_gid) |
81 | bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name); |
82 | } |
83 | //endpwent(); |
84 | } |
85 | pfile = bb_path_group_file; |
86 | if (ENABLE_FEATURE_SHADOWPASSWDS) |
87 | sfile = bb_path_gshadow_file; |
88 | } |
89 | |
90 | /* Modify pfile, then sfile */ |
91 | do { |
92 | if (update_passwd(pfile, name, NULL, member) == -1) |
93 | return EXIT_FAILURE; |
94 | if (ENABLE_FEATURE_SHADOWPASSWDS) { |
95 | pfile = sfile; |
96 | sfile = NULL; |
97 | } |
98 | } while (ENABLE_FEATURE_SHADOWPASSWDS && pfile); |
99 | |
100 | if (ENABLE_DELGROUP && do_deluser > 0) { |
101 | /* "deluser USER" also should try to delete |
102 | * same-named group. IOW: do "delgroup USER" |
103 | */ |
104 | // On debian deluser is a perl script that calls userdel. |
105 | // From man userdel: |
106 | // If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will |
107 | // delete the group with the same name as the user. |
108 | do_deluser = -1; |
109 | goto do_delgroup; |
110 | } |
111 | return EXIT_SUCCESS; |
112 | } |
113 | /* Reached only if number of command line args is wrong */ |
114 | bb_show_usage(); |
115 | } |
116 |