diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-14 00:51:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-14 00:51:05 +0000 |
commit | 829bbd3b5701f656c94f1cc672faa39946675d13 (patch) | |
tree | dbe6672228a3cb51eb8031ba714bb4abb96decf4 /loginutils/deluser.c | |
parent | f2b39e088d6ccbf4a540c741059c2f661eebc9ac (diff) | |
download | busybox-w32-829bbd3b5701f656c94f1cc672faa39946675d13.tar.gz busybox-w32-829bbd3b5701f656c94f1cc672faa39946675d13.tar.bz2 busybox-w32-829bbd3b5701f656c94f1cc672faa39946675d13.zip |
*: unify concurrent-safe update of /etc/{passwd,group,[g]shadow}
by Tito (farmatito AT tiscali.it)
function old new delta
update_passwd 743 1171 +428
bb_perror_nomsg - 9 +9
find_main 436 444 +8
passwd_main 1023 1027 +4
nameval 202 206 +4
chpasswd_main 315 319 +4
bb__parsespent 119 117 -2
adduser_main 654 650 -4
addgroup_main 345 341 -4
sv_main 1228 1222 -6
deluser_main 173 160 -13
bb_internal_putpwent 69 - -69
add_user_to_group 231 - -231
del_line_matching 460 31 -429
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 5/6 up/down: 457/-758) Total: -301 bytes
Diffstat (limited to 'loginutils/deluser.c')
-rw-r--r-- | loginutils/deluser.c | 133 |
1 files changed, 32 insertions, 101 deletions
diff --git a/loginutils/deluser.c b/loginutils/deluser.c index 56253712e..293e324b0 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c | |||
@@ -9,117 +9,48 @@ | |||
9 | * Licensed under GPL version 2, see file LICENSE in this tarball for details. | 9 | * Licensed under GPL version 2, see file LICENSE in this tarball for details. |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | |||
13 | #include "libbb.h" | 12 | #include "libbb.h" |
14 | 13 | ||
15 | /* Status */ | 14 | static int del_line_matching(char **args, const char *filename) |
16 | #define STATUS_OK 0 | ||
17 | #define NAME_NOT_FOUND 1 | ||
18 | #define MEMBER_NOT_FOUND 2 | ||
19 | |||
20 | static void del_line_matching(char **args, | ||
21 | const char *filename, | ||
22 | FILE* FAST_FUNC (*fopen_func)(const char *fileName, const char *mode)) | ||
23 | { | 15 | { |
24 | FILE *passwd; | 16 | if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) { |
25 | smallint error = NAME_NOT_FOUND; | 17 | return update_passwd(filename, args[2], NULL, args[1]); |
26 | char *name = (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) ? args[2] : args[1]; | ||
27 | char *line, *del; | ||
28 | char *new = xzalloc(1); | ||
29 | |||
30 | passwd = fopen_func(filename, "r"); | ||
31 | if (passwd) { | ||
32 | while ((line = xmalloc_fgets(passwd))) { | ||
33 | int len = strlen(name); | ||
34 | |||
35 | if (strncmp(line, name, len) == 0 | ||
36 | && line[len] == ':' | ||
37 | ) { | ||
38 | error = STATUS_OK; | ||
39 | if (ENABLE_FEATURE_DEL_USER_FROM_GROUP) { | ||
40 | struct group *gr; | ||
41 | char *p; | ||
42 | if (args[2] | ||
43 | /* There were two args on commandline */ | ||
44 | && (gr = getgrnam(name)) | ||
45 | /* The group was not deleted in the meanwhile */ | ||
46 | && (p = strrchr(line, ':')) | ||
47 | /* We can find a pointer to the last ':' */ | ||
48 | ) { | ||
49 | error = MEMBER_NOT_FOUND; | ||
50 | /* Move past ':' (worst case to '\0') and cut the line */ | ||
51 | p[1] = '\0'; | ||
52 | /* Reuse p */ | ||
53 | for (p = xzalloc(1); *gr->gr_mem != NULL; gr->gr_mem++) { | ||
54 | /* Add all the other group members */ | ||
55 | if (strcmp(args[1], *gr->gr_mem) != 0) { | ||
56 | del = p; | ||
57 | p = xasprintf("%s%s%s", p, p[0] ? "," : "", *gr->gr_mem); | ||
58 | free(del); | ||
59 | } else | ||
60 | error = STATUS_OK; | ||
61 | } | ||
62 | /* Recompose the line */ | ||
63 | line = xasprintf("%s%s\n", line, p); | ||
64 | if (ENABLE_FEATURE_CLEAN_UP) free(p); | ||
65 | } else | ||
66 | goto skip; | ||
67 | } | ||
68 | } | ||
69 | del = new; | ||
70 | new = xasprintf("%s%s", new, line); | ||
71 | free(del); | ||
72 | skip: | ||
73 | free(line); | ||
74 | } | ||
75 | |||
76 | if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); | ||
77 | |||
78 | if (error) { | ||
79 | if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && error == MEMBER_NOT_FOUND) { | ||
80 | /* Set the correct values for error message */ | ||
81 | filename = name; | ||
82 | name = args[1]; | ||
83 | } | ||
84 | bb_error_msg("can't find %s in %s", name, filename); | ||
85 | } else { | ||
86 | passwd = fopen_func(filename, "w"); | ||
87 | if (passwd) { | ||
88 | fputs(new, passwd); | ||
89 | if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); | ||
90 | } | ||
91 | } | ||
92 | } | 18 | } |
93 | free(new); | 19 | return update_passwd(filename, args[1], NULL, NULL); |
94 | } | 20 | } |
95 | 21 | ||
96 | int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 22 | int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
97 | int deluser_main(int argc, char **argv) | 23 | int deluser_main(int argc, char **argv) |
98 | { | 24 | { |
99 | if (argc == 2 | 25 | if (argc != 2 |
100 | || (ENABLE_FEATURE_DEL_USER_FROM_GROUP | 26 | && (!ENABLE_FEATURE_DEL_USER_FROM_GROUP |
101 | && (applet_name[3] == 'g' && argc == 3)) | 27 | || (applet_name[3] != 'g' || argc != 3)) |
102 | ) { | 28 | ) { |
103 | if (geteuid()) | 29 | bb_show_usage(); |
104 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | 30 | } |
105 | 31 | ||
106 | if ((ENABLE_FEATURE_DEL_USER_FROM_GROUP && argc != 3) | 32 | if (geteuid()) |
107 | || ENABLE_DELUSER | 33 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
108 | || (ENABLE_DELGROUP && ENABLE_DESKTOP) | 34 | |
35 | if ((ENABLE_FEATURE_DEL_USER_FROM_GROUP && argc != 3) | ||
36 | || ENABLE_DELUSER | ||
37 | || (ENABLE_DELGROUP && ENABLE_DESKTOP) | ||
38 | ) { | ||
39 | if (ENABLE_DELUSER | ||
40 | && (!ENABLE_DELGROUP || applet_name[3] == 'u') | ||
109 | ) { | 41 | ) { |
110 | if (ENABLE_DELUSER | 42 | if (del_line_matching(argv, bb_path_passwd_file) < 0) |
111 | && (!ENABLE_DELGROUP || applet_name[3] == 'u') | 43 | return EXIT_FAILURE; |
112 | ) { | 44 | if (ENABLE_FEATURE_SHADOWPASSWDS) { |
113 | del_line_matching(argv, bb_path_passwd_file, xfopen); | 45 | del_line_matching(argv, bb_path_shadow_file); |
114 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 46 | } |
115 | del_line_matching(argv, bb_path_shadow_file, fopen_or_warn); | 47 | } else if (ENABLE_DESKTOP && ENABLE_DELGROUP && getpwnam(argv[1])) |
116 | } else if (ENABLE_DESKTOP && ENABLE_DELGROUP && getpwnam(argv[1])) | 48 | bb_error_msg_and_die("can't remove primary group of user %s", argv[1]); |
117 | bb_error_msg_and_die("can't remove primary group of user %s", argv[1]); | 49 | } |
118 | } | 50 | if (del_line_matching(argv, bb_path_group_file) < 0) |
119 | del_line_matching(argv, bb_path_group_file, xfopen); | 51 | return EXIT_FAILURE; |
120 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 52 | if (ENABLE_FEATURE_SHADOWPASSWDS) { |
121 | del_line_matching(argv, bb_path_gshadow_file, fopen_or_warn); | 53 | del_line_matching(argv, bb_path_gshadow_file); |
122 | return EXIT_SUCCESS; | 54 | } |
123 | } else | 55 | return EXIT_SUCCESS; |
124 | bb_show_usage(); | ||
125 | } | 56 | } |