diff options
Diffstat (limited to 'deluser.c')
-rw-r--r-- | deluser.c | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/deluser.c b/deluser.c new file mode 100644 index 000000000..bb6e10996 --- /dev/null +++ b/deluser.c | |||
@@ -0,0 +1,175 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * deluser (remove lusers from the system ;) for TinyLogin | ||
4 | * | ||
5 | * | ||
6 | * Copyright (C) 1999 by Lineo, inc. | ||
7 | * Written by John Beppu <beppu@lineo.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | |||
25 | #include <sys/stat.h> | ||
26 | #include <unistd.h> | ||
27 | #include <stdio.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <string.h> | ||
30 | #include "busybox.h" | ||
31 | |||
32 | #define PASSWD_FILE "/etc/passwd" | ||
33 | #define GROUP_FILE "/etc/group" | ||
34 | |||
35 | /* where to start and stop deletion */ | ||
36 | typedef struct { | ||
37 | size_t start; | ||
38 | size_t stop; | ||
39 | } Bounds; | ||
40 | |||
41 | /* An interesting side-effect of boundary()'s | ||
42 | * implementation is that the first user (typically root) | ||
43 | * cannot be removed. Let's call it a feature. */ | ||
44 | static Bounds boundary(const char *buffer, const char *login) | ||
45 | { | ||
46 | char needle[256]; | ||
47 | char *start; | ||
48 | char *stop; | ||
49 | Bounds b; | ||
50 | |||
51 | snprintf(needle, 256, "\n%s", login); | ||
52 | needle[255] = 0; | ||
53 | start = strstr(buffer, needle); | ||
54 | if (!start) { | ||
55 | b.start = 0; | ||
56 | b.stop = 0; | ||
57 | return b; | ||
58 | } | ||
59 | start++; | ||
60 | |||
61 | stop = index(start, '\n'); /* index is a BSD-ism */ | ||
62 | b.start = start - buffer; | ||
63 | b.stop = stop - buffer; | ||
64 | return b; | ||
65 | } | ||
66 | |||
67 | /* grep -v ^login (except it only deletes the first match) */ | ||
68 | /* ...in fact, I think I'm going to simplify this later */ | ||
69 | static int del_line_matching(char *login, char *filename) | ||
70 | { | ||
71 | char *buffer; | ||
72 | FILE *passwd; | ||
73 | size_t len; | ||
74 | Bounds b; | ||
75 | struct stat statbuf; | ||
76 | |||
77 | /* load into buffer */ | ||
78 | passwd = fopen(filename, "r"); | ||
79 | if (!passwd) { | ||
80 | return 1; | ||
81 | } | ||
82 | stat(filename, &statbuf); | ||
83 | len = statbuf.st_size; | ||
84 | buffer = (char *) malloc(len * sizeof(char)); | ||
85 | |||
86 | if (!buffer) { | ||
87 | fclose(passwd); | ||
88 | return 1; | ||
89 | } | ||
90 | fread(buffer, len, sizeof(char), passwd); | ||
91 | |||
92 | fclose(passwd); | ||
93 | |||
94 | /* find the user to remove */ | ||
95 | b = boundary(buffer, login); | ||
96 | if (b.stop == 0) { | ||
97 | free(buffer); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | /* write the file w/o the user */ | ||
102 | passwd = fopen(filename, "w"); | ||
103 | if (!passwd) { | ||
104 | return 1; | ||
105 | } | ||
106 | fwrite(buffer, (b.start - 1), sizeof(char), passwd); | ||
107 | fwrite(&buffer[b.stop], (len - b.stop), sizeof(char), passwd); | ||
108 | |||
109 | fclose(passwd); | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /* ________________________________________________________________________ */ | ||
115 | int delgroup_main(int argc, char **argv) | ||
116 | { | ||
117 | /* int successful; */ | ||
118 | int failure; | ||
119 | |||
120 | if (argc != 2) { | ||
121 | show_usage(); | ||
122 | } else { | ||
123 | |||
124 | failure = del_line_matching(argv[1], GROUP_FILE); | ||
125 | #ifdef TLG_FEATURE_SHADOWPASSWDS | ||
126 | if (access(GSHADOW_FILE, W_OK) == 0) { | ||
127 | /* EDR the |= works if the error is not 0, so he had it wrong */ | ||
128 | failure |= del_line_matching(argv[1], GSHADOW_FILE); | ||
129 | } | ||
130 | #endif /* TLG_FEATURE_SHADOWPASSWDS */ | ||
131 | /* if (!successful) { */ | ||
132 | if (failure) { | ||
133 | error_msg_and_die("%s: Group could not be removed\n", argv[1]); | ||
134 | } | ||
135 | |||
136 | } | ||
137 | return (EXIT_SUCCESS); | ||
138 | } | ||
139 | |||
140 | /* ________________________________________________________________________ */ | ||
141 | int deluser_main(int argc, char **argv) | ||
142 | { | ||
143 | /* int successful; */ | ||
144 | int failure; | ||
145 | |||
146 | if (argc != 2) { | ||
147 | show_usage(); | ||
148 | } else { | ||
149 | |||
150 | failure = del_line_matching(argv[1], PASSWD_FILE); | ||
151 | /* if (!successful) { */ | ||
152 | if (failure) { | ||
153 | error_msg_and_die("%s: User could not be removed from %s\n", | ||
154 | argv[1], PASSWD_FILE); | ||
155 | } | ||
156 | #ifdef TLG_FEATURE_SHADOWPASSWDS | ||
157 | failure = del_line_matching(argv[1], SHADOW_FILE); | ||
158 | /* if (!successful) { */ | ||
159 | if (failure) { | ||
160 | error_msg_and_die("%s: User could not be removed from %s\n", | ||
161 | argv[1], SHADOW_FILE); | ||
162 | } | ||
163 | #endif /* TLG_FEATURE_SHADOWPASSWDS */ | ||
164 | failure = del_line_matching(argv[1], GROUP_FILE); | ||
165 | /* if (!successful) { */ | ||
166 | if (failure) { | ||
167 | error_msg_and_die("%s: User could not be removed from %s\n", | ||
168 | argv[1], GROUP_FILE); | ||
169 | } | ||
170 | |||
171 | } | ||
172 | return (EXIT_SUCCESS); | ||
173 | } | ||
174 | |||
175 | /* $Id: deluser.c,v 1.1 2001/08/21 16:18:59 andersen Exp $ */ | ||