blob: bb6e10996d84fe93db2c1729512fc597570d627c [file] [log] [blame]
Eric Andersenf349e972001-08-21 16:18:59 +00001/* 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 */
36typedef 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. */
44static 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 */
69static 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/* ________________________________________________________________________ */
115int 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/* ________________________________________________________________________ */
141int 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 $ */