1 | /* vi: set sw=4 ts=4: */
|
---|
2 | /*
|
---|
3 | * deluser (remove lusers from the system ;) for TinyLogin
|
---|
4 | *
|
---|
5 | * Copyright (C) 1999 by Lineo, inc. and John Beppu
|
---|
6 | * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
|
---|
7 | * Unified with delgroup by Tito Ragusa <farmatito@tiscali.it>
|
---|
8 | *
|
---|
9 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
---|
10 | *
|
---|
11 | */
|
---|
12 |
|
---|
13 | #include <sys/stat.h>
|
---|
14 | #include <unistd.h>
|
---|
15 | #include <stdio.h>
|
---|
16 | #include <stdlib.h>
|
---|
17 | #include <string.h>
|
---|
18 | #include "busybox.h"
|
---|
19 |
|
---|
20 | /* where to start and stop deletion */
|
---|
21 | typedef struct {
|
---|
22 | size_t start;
|
---|
23 | size_t stop;
|
---|
24 | } Bounds;
|
---|
25 |
|
---|
26 | /* An interesting side-effect of boundary()'s
|
---|
27 | * implementation is that the first user (typically root)
|
---|
28 | * cannot be removed. Let's call it a feature. */
|
---|
29 | static inline Bounds boundary(const char *buffer, const char *login)
|
---|
30 | {
|
---|
31 | char needle[256];
|
---|
32 | char *start;
|
---|
33 | char *stop;
|
---|
34 | Bounds b;
|
---|
35 |
|
---|
36 | snprintf(needle, 256, "\n%s:", login);
|
---|
37 | needle[255] = 0;
|
---|
38 | start = strstr(buffer, needle);
|
---|
39 | if (!start) {
|
---|
40 | b.start = 0;
|
---|
41 | b.stop = 0;
|
---|
42 | return b;
|
---|
43 | }
|
---|
44 | start++;
|
---|
45 |
|
---|
46 | stop = strchr(start, '\n');
|
---|
47 | b.start = start - buffer;
|
---|
48 | b.stop = stop - buffer;
|
---|
49 | return b;
|
---|
50 | }
|
---|
51 |
|
---|
52 | /* grep -v ^login (except it only deletes the first match) */
|
---|
53 | /* ...in fact, I think I'm going to simplify this later */
|
---|
54 | static void del_line_matching(const char *login, const char *filename)
|
---|
55 | {
|
---|
56 | char *buffer;
|
---|
57 | FILE *passwd;
|
---|
58 | Bounds b;
|
---|
59 | struct stat statbuf;
|
---|
60 |
|
---|
61 |
|
---|
62 | if ((passwd = bb_wfopen(filename, "r"))) {
|
---|
63 | xstat(filename, &statbuf);
|
---|
64 | buffer = (char *) xmalloc(statbuf.st_size * sizeof(char));
|
---|
65 | fread(buffer, statbuf.st_size, sizeof(char), passwd);
|
---|
66 | fclose(passwd);
|
---|
67 | /* find the user to remove */
|
---|
68 | b = boundary(buffer, login);
|
---|
69 | if (b.stop != 0) {
|
---|
70 | /* write the file w/o the user */
|
---|
71 | if ((passwd = bb_wfopen(filename, "w"))) {
|
---|
72 | fwrite(buffer, (b.start - 1), sizeof(char), passwd);
|
---|
73 | fwrite(&buffer[b.stop], (statbuf.st_size - b.stop), sizeof(char), passwd);
|
---|
74 | fclose(passwd);
|
---|
75 | }
|
---|
76 | } else {
|
---|
77 | bb_error_msg("Can't find '%s' in '%s'", login, filename);
|
---|
78 | }
|
---|
79 | free(buffer);
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | int deluser_main(int argc, char **argv)
|
---|
84 | {
|
---|
85 | if (argc != 2) {
|
---|
86 | bb_show_usage();
|
---|
87 | } else {
|
---|
88 | if (ENABLE_DELUSER && bb_applet_name[3] == 'u') {
|
---|
89 | del_line_matching(argv[1], bb_path_passwd_file);
|
---|
90 | if (ENABLE_FEATURE_SHADOWPASSWDS)
|
---|
91 | del_line_matching(argv[1], bb_path_shadow_file);
|
---|
92 | }
|
---|
93 | del_line_matching(argv[1], bb_path_group_file);
|
---|
94 | if (ENABLE_FEATURE_SHADOWPASSWDS)
|
---|
95 | del_line_matching(argv[1], bb_path_gshadow_file);
|
---|
96 | }
|
---|
97 | return (EXIT_SUCCESS);
|
---|
98 | }
|
---|
99 |
|
---|
100 | /* $Id: deluser.c,v 1.4 2003/07/14 20:20:45 andersen Exp $ */
|
---|