1 |
/* vi: set sw=4 ts=4: */ |
/* vi: set sw=4 ts=4: */ |
2 |
/* |
/* |
3 |
* deluser (remove lusers from the system ;) for TinyLogin |
* deluser/delgroup implementation for busybox |
4 |
* |
* |
5 |
* Copyright (C) 1999 by Lineo, inc. and John Beppu |
* Copyright (C) 1999 by Lineo, inc. and John Beppu |
6 |
* Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> |
* Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org> |
7 |
* Unified with delgroup by Tito Ragusa <farmatito@tiscali.it> |
* Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it> |
8 |
* |
* |
9 |
* Licensed under GPL version 2, see file LICENSE in this tarball for details. |
* Licensed under GPL version 2, see file LICENSE in this tarball for details. |
10 |
* |
* |
11 |
*/ |
*/ |
12 |
|
|
13 |
#include "busybox.h" |
#include "libbb.h" |
14 |
|
|
15 |
static void del_line_matching(const char *login, const char *filename) |
/* 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* FAST_FUNC (*fopen_func)(const char *fileName, const char *mode)) |
23 |
{ |
{ |
|
char *line; |
|
24 |
FILE *passwd; |
FILE *passwd; |
25 |
int len = strlen(login); |
smallint error = NAME_NOT_FOUND; |
26 |
int found = 0; |
char *name = (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) ? args[2] : args[1]; |
27 |
llist_t *plist = NULL; |
char *line, *del; |
28 |
|
char *new = xzalloc(1); |
29 |
passwd = fopen_or_warn(filename, "r"); |
|
30 |
if (!passwd) return; |
passwd = fopen_func(filename, "r"); |
31 |
|
if (passwd) { |
32 |
while ((line = xmalloc_fgets(passwd))) { |
while ((line = xmalloc_fgets(passwd))) { |
33 |
if (!strncmp(line, login, len) |
int len = strlen(name); |
34 |
&& line[len] == ':' |
|
35 |
) { |
if (strncmp(line, name, len) == 0 |
36 |
found++; |
&& 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); |
free(line); |
|
} else { |
|
|
llist_add_to_end(&plist, line); |
|
74 |
} |
} |
|
} |
|
75 |
|
|
76 |
if (!ENABLE_FEATURE_CLEAN_UP) { |
if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); |
77 |
if (!found) { |
|
78 |
bb_error_msg("can't find '%s' in '%s'", login, filename); |
if (error) { |
79 |
return; |
if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && error == MEMBER_NOT_FOUND) { |
80 |
} |
/* Set the correct values for error message */ |
81 |
passwd = fopen_or_warn(filename, "w"); |
filename = name; |
82 |
if (passwd) |
name = args[1]; |
83 |
while ((line = llist_pop(&plist))) |
} |
84 |
fputs(line, passwd); |
bb_error_msg("can't find %s in %s", name, filename); |
85 |
} else { |
} else { |
86 |
if (!found) { |
passwd = fopen_func(filename, "w"); |
87 |
bb_error_msg("can't find '%s' in '%s'", login, filename); |
if (passwd) { |
88 |
goto clean_up; |
fputs(new, passwd); |
89 |
} |
if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd); |
|
fclose(passwd); |
|
|
passwd = fopen_or_warn(filename, "w"); |
|
|
if (passwd) { |
|
|
clean_up: |
|
|
while ((line = llist_pop(&plist))) { |
|
|
if (found) fputs(line, passwd); |
|
|
free(line); |
|
90 |
} |
} |
|
fclose(passwd); |
|
91 |
} |
} |
92 |
} |
} |
93 |
|
free(new); |
94 |
} |
} |
95 |
|
|
96 |
|
int deluser_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
97 |
int deluser_main(int argc, char **argv) |
int deluser_main(int argc, char **argv) |
98 |
{ |
{ |
99 |
if (argc != 2) |
if (argc == 2 |
100 |
bb_show_usage(); |
|| (ENABLE_FEATURE_DEL_USER_FROM_GROUP |
101 |
|
&& (applet_name[3] == 'g' && argc == 3)) |
|
if (ENABLE_DELUSER |
|
|
&& (!ENABLE_DELGROUP || applet_name[3] == 'u') |
|
102 |
) { |
) { |
103 |
del_line_matching(argv[1], bb_path_passwd_file); |
if (geteuid()) |
104 |
if (ENABLE_FEATURE_SHADOWPASSWDS) |
bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
|
del_line_matching(argv[1], bb_path_shadow_file); |
|
|
} |
|
|
del_line_matching(argv[1], bb_path_group_file); |
|
|
if (ENABLE_FEATURE_SHADOWPASSWDS) |
|
|
del_line_matching(argv[1], bb_path_gshadow_file); |
|
105 |
|
|
106 |
return EXIT_SUCCESS; |
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); |
120 |
|
if (ENABLE_FEATURE_SHADOWPASSWDS) |
121 |
|
del_line_matching(argv, bb_path_gshadow_file, fopen_or_warn); |
122 |
|
return EXIT_SUCCESS; |
123 |
|
} else |
124 |
|
bb_show_usage(); |
125 |
} |
} |
|
|
|
|
/* $Id: deluser.c,v 1.1 2007-09-01 22:43:52 niro Exp $ */ |
|