[821] | 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 $ */
|
---|