diff options
-rw-r--r-- | include/usage.h | 5 | ||||
-rw-r--r-- | loginutils/Config.in | 8 | ||||
-rw-r--r-- | loginutils/deluser.c | 148 | ||||
-rw-r--r-- | scripts/defconfig | 1 |
4 files changed, 107 insertions, 55 deletions
diff --git a/include/usage.h b/include/usage.h index 2fb8112b0..afcc4b3d7 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -571,9 +571,10 @@ | |||
571 | "Deallocate unused virtual terminal /dev/ttyN" | 571 | "Deallocate unused virtual terminal /dev/ttyN" |
572 | 572 | ||
573 | #define delgroup_trivial_usage \ | 573 | #define delgroup_trivial_usage \ |
574 | "GROUP" | 574 | USE_FEATURE_DEL_USER_FROM_GROUP("[USER] ")"GROUP" |
575 | #define delgroup_full_usage \ | 575 | #define delgroup_full_usage \ |
576 | "Delete group GROUP from the system" | 576 | "Delete group GROUP from the system" \ |
577 | USE_FEATURE_DEL_USER_FROM_GROUP(" or user USER from group GROUP") | ||
577 | 578 | ||
578 | #define deluser_trivial_usage \ | 579 | #define deluser_trivial_usage \ |
579 | "USER" | 580 | "USER" |
diff --git a/loginutils/Config.in b/loginutils/Config.in index 1d52cdfe5..e8ab9ec3c 100644 --- a/loginutils/Config.in +++ b/loginutils/Config.in | |||
@@ -74,6 +74,14 @@ config DELGROUP | |||
74 | help | 74 | help |
75 | Utility for deleting a group account. | 75 | Utility for deleting a group account. |
76 | 76 | ||
77 | config FEATURE_DEL_USER_FROM_GROUP | ||
78 | bool "Support for removing users from groups." | ||
79 | default n | ||
80 | depends on DELGROUP | ||
81 | help | ||
82 | If called with two non-option arguments, deluser | ||
83 | or delgroup will remove an user from a specified group. | ||
84 | |||
77 | config ADDUSER | 85 | config ADDUSER |
78 | bool "adduser" | 86 | bool "adduser" |
79 | default n | 87 | default n |
diff --git a/loginutils/deluser.c b/loginutils/deluser.c index e9bde00bd..2781df319 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * deluser (remove lusers from the system ;) for TinyLogin | 3 | * deluser/delgroup implementation for busybox |
4 | * | 4 | * |
5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu | 5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu |
6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> | 6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> |
7 | * Unified with delgroup by Tito Ragusa <farmatito@tiscali.it> | 7 | * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it> |
8 | * | 8 | * |
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 | * |
@@ -12,72 +12,114 @@ | |||
12 | 12 | ||
13 | #include "busybox.h" | 13 | #include "busybox.h" |
14 | 14 | ||
15 | static void del_line_matching(const char *login, const char *filename) | 15 | /* Status */ |
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 *(*fopen_func)(const char *fileName, const char *mode)) | ||
16 | { | 23 | { |
17 | char *line; | ||
18 | FILE *passwd; | 24 | FILE *passwd; |
19 | int len = strlen(login); | 25 | smallint error = NAME_NOT_FOUND; |
20 | int found = 0; | 26 | char *name = (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) ? args[2] : args[1]; |
21 | llist_t *plist = NULL; | 27 | char *line, *del; |
28 | char *new = xzalloc(1); | ||
22 | 29 | ||
23 | passwd = fopen_or_warn(filename, "r"); | 30 | passwd = fopen_func(filename, "r"); |
24 | if (!passwd) return; | 31 | if (passwd) { |
32 | while ((line = xmalloc_fgets(passwd))) { | ||
33 | int len = strlen(name); | ||
25 | 34 | ||
26 | while ((line = xmalloc_fgets(passwd))) { | 35 | if (strncmp(line, name, len) == 0 |
27 | if (!strncmp(line, login, len) | 36 | && line[len] == ':' |
28 | && line[len] == ':' | 37 | ) { |
29 | ) { | 38 | error = STATUS_OK; |
30 | found++; | 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: | ||
31 | free(line); | 73 | free(line); |
32 | } else { | ||
33 | llist_add_to_end(&plist, line); | ||
34 | } | 74 | } |
35 | } | ||
36 | 75 | ||
37 | if (!ENABLE_FEATURE_CLEAN_UP) { | 76 | if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); |
38 | if (!found) { | 77 | |
39 | bb_error_msg("can't find '%s' in '%s'", login, filename); | 78 | if (error) { |
40 | return; | 79 | if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && error == MEMBER_NOT_FOUND) { |
41 | } | 80 | /* Set the correct values for error message */ |
42 | passwd = fopen_or_warn(filename, "w"); | 81 | filename = name; |
43 | if (passwd) | 82 | name = args[1]; |
44 | while ((line = llist_pop(&plist))) | 83 | } |
45 | fputs(line, passwd); | 84 | bb_error_msg("can't find %s in %s", name, filename); |
46 | } else { | 85 | } else { |
47 | if (!found) { | 86 | passwd = fopen_func(filename, "w"); |
48 | bb_error_msg("can't find '%s' in '%s'", login, filename); | 87 | if (passwd) { |
49 | goto clean_up; | 88 | fputs(new, passwd); |
50 | } | 89 | if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); |
51 | fclose(passwd); | ||
52 | passwd = fopen_or_warn(filename, "w"); | ||
53 | if (passwd) { | ||
54 | clean_up: | ||
55 | while ((line = llist_pop(&plist))) { | ||
56 | if (found) fputs(line, passwd); | ||
57 | free(line); | ||
58 | } | 90 | } |
59 | fclose(passwd); | ||
60 | } | 91 | } |
61 | } | 92 | } |
93 | free(new); | ||
62 | } | 94 | } |
63 | 95 | ||
64 | int deluser_main(int argc, char **argv); | 96 | int deluser_main(int argc, char **argv); |
65 | int deluser_main(int argc, char **argv) | 97 | int deluser_main(int argc, char **argv) |
66 | { | 98 | { |
67 | if (argc != 2) | 99 | if (argc == 2 |
68 | bb_show_usage(); | 100 | || (ENABLE_FEATURE_DEL_USER_FROM_GROUP |
69 | 101 | && (applet_name[3] == 'g' && argc == 3)) | |
70 | if (ENABLE_DELUSER | ||
71 | && (!ENABLE_DELGROUP || applet_name[3] == 'u') | ||
72 | ) { | 102 | ) { |
73 | del_line_matching(argv[1], bb_path_passwd_file); | 103 | if (geteuid()) |
104 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | ||
105 | |||
106 | if ((ENABLE_FEATURE_DEL_USER_FROM_GROUP && argc != 3) | ||
107 | || ENABLE_DELUSER | ||
108 | || (ENABLE_DELGROUP && ENABLE_DESKTOP) | ||
109 | ) { | ||
110 | if (ENABLE_DELUSER | ||
111 | && (!ENABLE_DELGROUP || applet_name[3] == 'u') | ||
112 | ) { | ||
113 | del_line_matching(argv, bb_path_passwd_file, xfopen); | ||
114 | if (ENABLE_FEATURE_SHADOWPASSWDS) | ||
115 | del_line_matching(argv, bb_path_shadow_file, fopen_or_warn); | ||
116 | } else if (ENABLE_DESKTOP && ENABLE_DELGROUP && getpwnam(argv[1])) | ||
117 | bb_error_msg_and_die("can't remove primary group of user %s", argv[1]); | ||
118 | } | ||
119 | del_line_matching(argv, bb_path_group_file, xfopen); | ||
74 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 120 | if (ENABLE_FEATURE_SHADOWPASSWDS) |
75 | del_line_matching(argv[1], bb_path_shadow_file); | 121 | del_line_matching(argv, bb_path_gshadow_file, fopen_or_warn); |
76 | } | 122 | return EXIT_SUCCESS; |
77 | del_line_matching(argv[1], bb_path_group_file); | 123 | } else |
78 | if (ENABLE_FEATURE_SHADOWPASSWDS) | 124 | bb_show_usage(); |
79 | del_line_matching(argv[1], bb_path_gshadow_file); | ||
80 | |||
81 | return EXIT_SUCCESS; | ||
82 | } | 125 | } |
83 | |||
diff --git a/scripts/defconfig b/scripts/defconfig index 009026e5a..c9086eb13 100644 --- a/scripts/defconfig +++ b/scripts/defconfig | |||
@@ -349,6 +349,7 @@ CONFIG_USE_BB_PWD_GRP=y | |||
349 | CONFIG_ADDGROUP=y | 349 | CONFIG_ADDGROUP=y |
350 | CONFIG_FEATURE_ADDUSER_TO_GROUP=y | 350 | CONFIG_FEATURE_ADDUSER_TO_GROUP=y |
351 | CONFIG_DELGROUP=y | 351 | CONFIG_DELGROUP=y |
352 | CONFIG_FEATURE_DEL_USER_FROM_GROUP=y | ||
352 | CONFIG_ADDUSER=y | 353 | CONFIG_ADDUSER=y |
353 | CONFIG_DELUSER=y | 354 | CONFIG_DELUSER=y |
354 | CONFIG_GETTY=y | 355 | CONFIG_GETTY=y |