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/addgroup.c

    r821 r1765  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * addgroup - add users to /etc/passwd and /etc/shadow
     3 * addgroup - add groups to /etc/group and /etc/gshadow
    44 *
    55 * Copyright (C) 1999 by Lineo, inc. and John Beppu
    66 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
     7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
    78 *
    89 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     
    1011 */
    1112
    12 #include <stdio.h>
    13 #include <string.h>
    14 #include <sys/types.h>
    15 #include <unistd.h>
     13#include "libbb.h"
    1614
    17 #include "busybox.h"
     15static void xgroup_study(struct group *g)
     16{
     17    /* Make sure gr_name is unused */
     18    if (getgrnam(g->gr_name)) {
     19        goto error;
     20    }
    1821
    19 /* make sure gr_name isn't taken, make sure gid is kosher
    20  * return 1 on failure */
    21 static int group_study(struct group *g)
    22 {
    23     FILE *etc_group;
    24     gid_t desired;
    25 
    26     struct group *grp;
    27     const int max = 65000;
    28 
    29     etc_group = bb_xfopen(bb_path_group_file, "r");
    30 
    31     /* make sure gr_name isn't taken, make sure gid is kosher */
    32     desired = g->gr_gid;
    33     while ((grp = fgetgrent(etc_group))) {
    34         if ((strcmp(grp->gr_name, g->gr_name)) == 0) {
    35             bb_error_msg_and_die("%s: group already in use", g->gr_name);
     22    /* Check if the desired gid is free
     23     * or find the first free one */
     24    while (1) {
     25        if (!getgrgid(g->gr_gid)) {
     26            return; /* found free group: return */
    3627        }
    37         if ((desired) && grp->gr_gid == desired) {
    38             bb_error_msg_and_die("%d: gid already in use",
    39                               desired);
     28        if (option_mask32) {
     29            /* -g N, cannot pick gid other than N: error */
     30            g->gr_name = itoa(g->gr_gid);
     31            goto error;
    4032        }
    41         if ((grp->gr_gid > g->gr_gid) && (grp->gr_gid < max)) {
    42             g->gr_gid = grp->gr_gid;
     33        g->gr_gid++;
     34        if (g->gr_gid <= 0) {
     35            /* overflowed: error */
     36            bb_error_msg_and_die("no gids left");
    4337        }
    4438    }
    45     fclose(etc_group);
    4639
    47     /* gid */
    48     if (desired) {
    49         g->gr_gid = desired;
    50     } else {
    51         g->gr_gid++;
    52     }
    53     /* return 1; */
    54     return 0;
     40 error:
     41    /* exit */
     42    bb_error_msg_and_die("group %s already exists", g->gr_name);
    5543}
    5644
    5745/* append a new user to the passwd file */
    58 static int addgroup(char *group, gid_t gid, const char *user)
     46static void new_group(char *group, gid_t gid)
    5947{
    6048    FILE *file;
     
    6452    gr.gr_gid = gid;
    6553    gr.gr_name = group;
    66     if (group_study(&gr))
    67         return 1;
     54    xgroup_study(&gr);
    6855
    6956    /* add entry to group */
    70     file = bb_xfopen(bb_path_group_file, "a");
     57    file = xfopen(bb_path_group_file, "a");
    7158    /* group:passwd:gid:userlist */
    72     fprintf(file, "%s:%s:%d:%s\n", group, "x", gr.gr_gid, user);
    73     fclose(file);
     59    fprintf(file, "%s:x:%d:\n", group, gr.gr_gid);
     60    if (ENABLE_FEATURE_CLEAN_UP)
     61        fclose(file);
     62#if ENABLE_FEATURE_SHADOWPASSWDS
     63    file = fopen_or_warn(bb_path_gshadow_file, "a");
     64    if (file) {
     65        fprintf(file, "%s:!::\n", group);
     66        if (ENABLE_FEATURE_CLEAN_UP)
     67            fclose(file);
     68    }
     69#endif
     70}
    7471
    75 #if ENABLE_FEATURE_SHADOWPASSWDS
    76     file = bb_xfopen(bb_path_gshadow_file, "a");
    77     fprintf(file, "%s:!::\n", group);
    78     fclose(file);
     72#if ENABLE_FEATURE_ADDUSER_TO_GROUP
     73static void add_user_to_group(char **args,
     74        const char *path,
     75        FILE *(*fopen_func)(const char *fileName, const char *mode))
     76{
     77    char *line;
     78    int len = strlen(args[1]);
     79    llist_t *plist = NULL;
     80    FILE *group_file;
     81
     82    group_file = fopen_func(path, "r");
     83
     84    if (!group_file) return;
     85
     86    while ((line = xmalloc_getline(group_file))) {
     87        /* Find the group */
     88        if (!strncmp(line, args[1], len)
     89         && line[len] == ':'
     90        ) {
     91            /* Add the new user */
     92            line = xasprintf("%s%s%s", line,
     93                        last_char_is(line, ':') ? "" : ",",
     94                        args[0]);
     95        }
     96        llist_add_to_end(&plist, line);
     97    }
     98
     99    if (ENABLE_FEATURE_CLEAN_UP) {
     100        fclose(group_file);
     101        group_file = fopen_func(path, "w");
     102        while ((line = llist_pop(&plist))) {
     103            if (group_file)
     104                fprintf(group_file, "%s\n", line);
     105            free(line);
     106        }
     107        if (group_file)
     108            fclose(group_file);
     109    } else {
     110        group_file = fopen_func(path, "w");
     111        if (group_file)
     112            while ((line = llist_pop(&plist)))
     113                fprintf(group_file, "%s\n", line);
     114    }
     115}
    79116#endif
    80 
    81     /* return 1; */
    82     return 0;
    83 }
    84117
    85118/*
    86119 * addgroup will take a login_name as its first parameter.
    87120 *
    88  * gid
    89  *
    90  * can be customized via command-line parameters.
    91  * ________________________________________________________________________ */
     121 * gid can be customized via command-line parameters.
     122 * If called with two non-option arguments, addgroup
     123 * will add an existing user to an existing group.
     124 */
     125int addgroup_main(int argc, char **argv);
    92126int addgroup_main(int argc, char **argv)
    93127{
    94128    char *group;
    95129    gid_t gid = 0;
    96    
    97     /* check for min, max and missing args and exit on error */
    98     bb_opt_complementally = "-1:?2:?";
    99130
    100     if (bb_getopt_ulflags(argc, argv, "g:", &group)) {
    101         gid = bb_xgetlarg(group, 10, 0, LONG_MAX);
     131    /* need to be root */
     132    if (geteuid()) {
     133        bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
     134    }
     135
     136    /* Syntax:
     137     *  addgroup group
     138     *  addgroup -g num group
     139     *  addgroup user group
     140     * Check for min, max and missing args */
     141    opt_complementary = "-1:?2";
     142    if (getopt32(argv, "g:", &group)) {
     143        gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1);
    102144    }
    103145    /* move past the commandline options */
    104146    argv += optind;
     147    argc -= optind;
    105148
    106     /* need to be root */
    107     if(geteuid()) {
    108         bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
    109     }
     149#if ENABLE_FEATURE_ADDUSER_TO_GROUP
     150    if (argc == 2) {
     151        struct group *gr;
    110152
    111     /* werk */
    112     return addgroup(argv[0], gid, (argv[1]) ? argv[1] : "");
     153        if (option_mask32) {
     154            /* -g was there, but "addgroup -g num user group"
     155             * is a no-no */
     156            bb_show_usage();
     157        }
     158
     159        /* check if group and user exist */
     160        xuname2uid(argv[0]); /* unknown user: exit */
     161        xgroup2gid(argv[1]); /* unknown group: exit */
     162        /* check if user is already in this group */
     163        gr = getgrnam(argv[1]);
     164        for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) {
     165            if (!strcmp(argv[0], *(gr->gr_mem))) {
     166                /* user is already in group: do nothing */
     167                return EXIT_SUCCESS;
     168            }
     169        }
     170        add_user_to_group(argv, bb_path_group_file, xfopen);
     171#if ENABLE_FEATURE_SHADOWPASSWDS
     172        add_user_to_group(argv, bb_path_gshadow_file, fopen_or_warn);
     173#endif /* ENABLE_FEATURE_SHADOWPASSWDS */
     174    } else
     175#endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */
     176        new_group(argv[0], gid);
     177
     178    /* Reached only on success */
     179    return EXIT_SUCCESS;
    113180}
Note: See TracChangeset for help on using the changeset viewer.