diff options
author | Tito Ragusa <farmatito@tiscali.it> | 2010-11-06 22:14:55 +0100 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-11-06 22:14:55 +0100 |
commit | 1586c7a92c9fd69967706c13b68eb8eb8fba54ed (patch) | |
tree | 3c2f2a6b25110bba4b7a517731a98b0828dbf724 | |
parent | 0ebafcc5b14b8c22a4a10f13328b996f8d85c2a5 (diff) | |
download | busybox-w32-1586c7a92c9fd69967706c13b68eb8eb8fba54ed.tar.gz busybox-w32-1586c7a92c9fd69967706c13b68eb8eb8fba54ed.tar.bz2 busybox-w32-1586c7a92c9fd69967706c13b68eb8eb8fba54ed.zip |
deluser: 2nd attempt at deluser/delgroup size reduction and improvements
Signed-off-by: Tito Ragusa <farmatito@tiscali.it>
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
-rw-r--r-- | loginutils/deluser.c | 99 |
1 files changed, 70 insertions, 29 deletions
diff --git a/loginutils/deluser.c b/loginutils/deluser.c index 08ca266d0..5a159b205 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c | |||
@@ -14,41 +14,82 @@ | |||
14 | int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 14 | int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
15 | int deluser_main(int argc, char **argv) | 15 | int deluser_main(int argc, char **argv) |
16 | { | 16 | { |
17 | if (argc != 2 | 17 | /* User or group name */ |
18 | && (!ENABLE_FEATURE_DEL_USER_FROM_GROUP | 18 | char *name; |
19 | || applet_name[3] != 'g' | 19 | /* Username (non-NULL only in "delgroup USER GROUP" case) */ |
20 | || argc != 3) | 20 | char *member; |
21 | ) { | 21 | /* Name of passwd or group file */ |
22 | bb_show_usage(); | 22 | const char *pfile; |
23 | } | 23 | /* Name of shadow or gshadow file */ |
24 | const char *sfile; | ||
25 | /* Are we deluser or delgroup? */ | ||
26 | bool do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u')); | ||
24 | 27 | ||
25 | if (geteuid()) | 28 | if (geteuid() != 0) |
26 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | 29 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
27 | 30 | ||
28 | if (ENABLE_DELUSER && applet_name[3] == 'u') { | 31 | name = argv[1]; |
29 | /* deluser USER */ | 32 | member = NULL; |
30 | if (update_passwd(bb_path_passwd_file, argv[1], NULL, NULL) < 0) | 33 | |
31 | return EXIT_FAILURE; | 34 | switch (argc) { |
32 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 35 | case 3: |
33 | if (update_passwd(bb_path_shadow_file, argv[1], NULL, NULL) < 0) | 36 | if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser) |
34 | return EXIT_FAILURE; | 37 | break; |
35 | } else if (ENABLE_DELGROUP) { | 38 | /* It's "delgroup USER GROUP" */ |
36 | /* delgroup ... */ | 39 | member = name; |
37 | if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || argc != 3) { | 40 | name = argv[2]; |
38 | /* delgroup GROUP */ | 41 | /* Fallthrough */ |
39 | if (update_passwd(bb_path_group_file, argv[1], NULL, NULL) < 0) | 42 | |
40 | return EXIT_FAILURE; | 43 | case 2: |
44 | if (do_deluser) { | ||
45 | /* "deluser USER" */ | ||
46 | xgetpwnam(name); /* bail out if USER is wrong */ | ||
47 | pfile = bb_path_passwd_file; | ||
41 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 48 | if (ENABLE_FEATURE_SHADOWPASSWDS) |
42 | if (update_passwd(bb_path_gshadow_file, argv[1], NULL, NULL) < 0) | 49 | sfile = bb_path_shadow_file; |
43 | return EXIT_FAILURE; | ||
44 | } else { | 50 | } else { |
45 | /* delgroup USER GROUP */ | 51 | do_delgroup: |
46 | if (update_passwd(bb_path_group_file, argv[2], NULL, argv[1]) < 0) | 52 | /* "delgroup GROUP" or "delgroup USER GROUP" */ |
47 | return EXIT_FAILURE; | 53 | xgetgrnam(name); /* bail out if GROUP is wrong */ |
54 | if (!member) { | ||
55 | /* "delgroup GROUP". | ||
56 | * If user with tha same name exists, | ||
57 | * bail out. | ||
58 | */ | ||
59 | //BUG: check should be done by GID, not by matching name! | ||
60 | //1. find GROUP's GID | ||
61 | //2. check that /etc/passwd doesn't have lines of the form | ||
62 | // user:pwd:uid:GID:... | ||
63 | //3. bail out if at least one such line exists | ||
64 | if (getpwnam(name) != NULL) | ||
65 | bb_error_msg_and_die("'%s' still has '%s' as their primary group!", name, name); | ||
66 | } | ||
67 | pfile = bb_path_group_file; | ||
48 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 68 | if (ENABLE_FEATURE_SHADOWPASSWDS) |
49 | if (update_passwd(bb_path_gshadow_file, argv[2], NULL, argv[1]) < 0) | 69 | sfile = bb_path_gshadow_file; |
50 | return EXIT_FAILURE; | 70 | } |
71 | |||
72 | /* Modify pfile, then sfile */ | ||
73 | do { | ||
74 | if (update_passwd(pfile, name, NULL, member) == -1) | ||
75 | return EXIT_FAILURE; | ||
76 | if (ENABLE_FEATURE_SHADOWPASSWDS) { | ||
77 | pfile = sfile; | ||
78 | sfile = NULL; | ||
79 | } | ||
80 | } while (ENABLE_FEATURE_SHADOWPASSWDS && pfile); | ||
81 | |||
82 | if (ENABLE_DELGROUP && do_deluser) { | ||
83 | /* "deluser USER" also should try to delete | ||
84 | * same-named group. IOW: do "delgroup USER" | ||
85 | */ | ||
86 | //TODO: check how it actually works in upstream. | ||
87 | //I suspect it is only done if group has no more members. | ||
88 | do_deluser = 0; | ||
89 | goto do_delgroup; | ||
51 | } | 90 | } |
91 | return EXIT_SUCCESS; | ||
52 | } | 92 | } |
53 | return EXIT_SUCCESS; | 93 | /* Reached only if number of command line args is wrong */ |
94 | bb_show_usage(); | ||
54 | } | 95 | } |