Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (16 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/loginutils/deluser.c

    r821 r1765  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * deluser (remove lusers from the system ;) for TinyLogin
     3 * deluser/delgroup implementation for busybox
    44 *
    55 * Copyright (C) 1999 by Lineo, inc. and John Beppu
    66 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
    7  * Unified with delgroup by Tito Ragusa <farmatito@tiscali.it>
     7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
    88 *
    9  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     9 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
    1010 *
    1111 */
    1212
    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"
     13#include "libbb.h"
    1914
    20 /* where to start and stop deletion */
    21 typedef struct {
    22     size_t start;
    23     size_t stop;
    24 } Bounds;
     15/* Status */
     16#define STATUS_OK            0
     17#define NAME_NOT_FOUND       1
     18#define MEMBER_NOT_FOUND     2
    2519
    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)
     20static void del_line_matching(char **args,
     21        const char *filename,
     22        FILE *(*fopen_func)(const char *fileName, const char *mode))
    3023{
    31     char needle[256];
    32     char *start;
    33     char *stop;
    34     Bounds b;
     24    FILE *passwd;
     25    smallint error = NAME_NOT_FOUND;
     26    char *name = (ENABLE_FEATURE_DEL_USER_FROM_GROUP && args[2]) ? args[2] : args[1];
     27    char *line, *del;
     28    char *new = xzalloc(1);
    3529
    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;
     30    passwd = fopen_func(filename, "r");
     31    if (passwd) {
     32        while ((line = xmalloc_fgets(passwd))) {
     33            int len = strlen(name);
     34
     35            if (strncmp(line, name, len) == 0
     36             && 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);
     74        }
     75
     76        if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd);
     77
     78        if (error) {
     79            if (ENABLE_FEATURE_DEL_USER_FROM_GROUP && error == MEMBER_NOT_FOUND) {
     80                /* Set the correct values for error message */
     81                filename = name;
     82                name = args[1];
     83            }
     84            bb_error_msg("can't find %s in %s", name, filename);
     85        } else {
     86            passwd = fopen_func(filename, "w");
     87            if (passwd) {
     88                fputs(new, passwd);
     89                if (ENABLE_FEATURE_CLEAN_UP) fclose(passwd);
     90            }
     91        }
    4392    }
    44     start++;
    45 
    46     stop = strchr(start, '\n');
    47     b.start = start - buffer;
    48     b.stop = stop - buffer;
    49     return b;
     93    free(new);
    5094}
    5195
    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 
     96int deluser_main(int argc, char **argv);
    8397int deluser_main(int argc, char **argv)
    8498{
    85     if (argc != 2) {
     99    if (argc == 2
     100     || (ENABLE_FEATURE_DEL_USER_FROM_GROUP
     101        && (applet_name[3] == 'g' && argc == 3))
     102    ) {
     103        if (geteuid())
     104            bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
     105
     106        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
    86124        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);
    98125}
    99 
    100 /* $Id: deluser.c,v 1.4 2003/07/14 20:20:45 andersen Exp $ */
Note: See TracChangeset for help on using the changeset viewer.