source: MondoRescue/branches/3.3/mindi-busybox/loginutils/addgroup.c@ 3624

Last change on this file since 3624 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

File size: 6.2 KB
RevLine 
[821]1/* vi: set sw=4 ts=4: */
2/*
[1765]3 * addgroup - add groups to /etc/group and /etc/gshadow
[821]4 *
5 * Copyright (C) 1999 by Lineo, inc. and John Beppu
6 * Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
[1765]7 * Copyright (C) 2007 by Tito Ragusa <farmatito@tiscali.it>
[821]8 *
[2725]9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
[821]10 *
11 */
[3621]12//config:config ADDGROUP
13//config: bool "addgroup"
14//config: default y
15//config: help
16//config: Utility for creating a new group account.
17//config:
18//config:config FEATURE_ADDGROUP_LONG_OPTIONS
19//config: bool "Enable long options"
20//config: default y
21//config: depends on ADDGROUP && LONG_OPTS
22//config: help
23//config: Support long options for the addgroup applet.
24//config:
25//config:config FEATURE_ADDUSER_TO_GROUP
26//config: bool "Support for adding users to groups"
27//config: default y
28//config: depends on ADDGROUP
29//config: help
30//config: If called with two non-option arguments,
31//config: addgroup will add an existing user to an
32//config: existing group.
[3232]33
[3621]34//applet:IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP))
35
36//kbuild:lib-$(CONFIG_ADDGROUP) += addgroup.o
37
[3232]38//usage:#define addgroup_trivial_usage
[3621]39//usage: "[-g GID] [-S] " IF_FEATURE_ADDUSER_TO_GROUP("[USER] ") "GROUP"
[3232]40//usage:#define addgroup_full_usage "\n\n"
[3621]41//usage: "Add a group" IF_FEATURE_ADDUSER_TO_GROUP(" or add a user to a group") "\n"
[3232]42//usage: "\n -g GID Group id"
43//usage: "\n -S Create a system group"
44
[1765]45#include "libbb.h"
[821]46
[2725]47#if CONFIG_LAST_SYSTEM_ID < CONFIG_FIRST_SYSTEM_ID
48#error Bad LAST_SYSTEM_ID or FIRST_SYSTEM_ID in .config
49#endif
[3621]50#if CONFIG_LAST_ID < CONFIG_LAST_SYSTEM_ID
51#error Bad LAST_ID or LAST_SYSTEM_ID in .config
52#endif
[2725]53
54#define OPT_GID (1 << 0)
55#define OPT_SYSTEM_ACCOUNT (1 << 1)
56
[1765]57static void xgroup_study(struct group *g)
[821]58{
[3621]59 unsigned max = CONFIG_LAST_ID;
[2725]60
[1765]61 /* Make sure gr_name is unused */
62 if (getgrnam(g->gr_name)) {
[2725]63 bb_error_msg_and_die("%s '%s' in use", "group", g->gr_name);
64 /* these format strings are reused in adduser and addgroup */
[1765]65 }
[821]66
[2725]67 /* if a specific gid is requested, the --system switch and */
68 /* min and max values are overridden, and the range of valid */
69 /* gid values is set to [0, INT_MAX] */
70 if (!(option_mask32 & OPT_GID)) {
71 if (option_mask32 & OPT_SYSTEM_ACCOUNT) {
72 g->gr_gid = CONFIG_FIRST_SYSTEM_ID;
73 max = CONFIG_LAST_SYSTEM_ID;
74 } else {
75 g->gr_gid = CONFIG_LAST_SYSTEM_ID + 1;
76 }
77 }
[1765]78 /* Check if the desired gid is free
79 * or find the first free one */
80 while (1) {
81 if (!getgrgid(g->gr_gid)) {
82 return; /* found free group: return */
[821]83 }
[2725]84 if (option_mask32 & OPT_GID) {
[1765]85 /* -g N, cannot pick gid other than N: error */
[2725]86 bb_error_msg_and_die("%s '%s' in use", "gid", itoa(g->gr_gid));
87 /* this format strings is reused in adduser and addgroup */
[821]88 }
[2725]89 if (g->gr_gid == max) {
[1765]90 /* overflowed: error */
[2725]91 bb_error_msg_and_die("no %cids left", 'g');
92 /* this format string is reused in adduser and addgroup */
[821]93 }
[2725]94 g->gr_gid++;
[821]95 }
96}
97
98/* append a new user to the passwd file */
[1765]99static void new_group(char *group, gid_t gid)
[821]100{
101 struct group gr;
[2725]102 char *p;
[821]103
104 /* make sure gid and group haven't already been allocated */
105 gr.gr_gid = gid;
106 gr.gr_name = group;
[1765]107 xgroup_study(&gr);
[821]108
109 /* add entry to group */
[2725]110 p = xasprintf("x:%u:", (unsigned) gr.gr_gid);
111 if (update_passwd(bb_path_group_file, group, p, NULL) < 0)
112 exit(EXIT_FAILURE);
[1765]113 if (ENABLE_FEATURE_CLEAN_UP)
[2725]114 free(p);
[821]115#if ENABLE_FEATURE_SHADOWPASSWDS
[2725]116 /* /etc/gshadow fields:
117 * 1. Group name.
118 * 2. Encrypted password.
119 * If set, non-members of the group can join the group
120 * by typing the password for that group using the newgrp command.
121 * If the value is of this field ! then no user is allowed
122 * to access the group using the newgrp command. A value of !!
123 * is treated the same as a value of ! only it indicates
124 * that a password has never been set before. If the value is null,
125 * only group members can log into the group.
126 * 3. Group administrators (comma delimited list).
127 * Group members listed here can add or remove group members
128 * using the gpasswd command.
129 * 4. Group members (comma delimited list).
130 */
131 /* Ignore errors: if file is missing we assume admin doesn't want it */
132 update_passwd(bb_path_gshadow_file, group, "!::", NULL);
[821]133#endif
[1765]134}
[821]135
[2725]136#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
137static const char addgroup_longopts[] ALIGN1 =
138 "gid\0" Required_argument "g"
139 "system\0" No_argument "S"
140 ;
[1765]141#endif
[821]142
143/*
144 * addgroup will take a login_name as its first parameter.
145 *
[1765]146 * gid can be customized via command-line parameters.
147 * If called with two non-option arguments, addgroup
148 * will add an existing user to an existing group.
149 */
[2725]150int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
151int addgroup_main(int argc UNUSED_PARAM, char **argv)
[821]152{
[2725]153 unsigned opts;
[3621]154 const char *gid = "0";
[821]155
[1765]156 /* need to be root */
157 if (geteuid()) {
158 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
[821]159 }
[2725]160#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
161 applet_long_options = addgroup_longopts;
162#endif
[1765]163 /* Syntax:
164 * addgroup group
165 * addgroup -g num group
166 * addgroup user group
167 * Check for min, max and missing args */
[3621]168 opt_complementary = "-1:?2";
[2725]169 opts = getopt32(argv, "g:S", &gid);
[821]170 /* move past the commandline options */
171 argv += optind;
[2725]172 //argc -= optind;
[821]173
[1765]174#if ENABLE_FEATURE_ADDUSER_TO_GROUP
[2725]175 if (argv[1]) {
[1765]176 struct group *gr;
[821]177
[2725]178 if (opts & OPT_GID) {
[1765]179 /* -g was there, but "addgroup -g num user group"
180 * is a no-no */
181 bb_show_usage();
182 }
183
184 /* check if group and user exist */
185 xuname2uid(argv[0]); /* unknown user: exit */
[2725]186 gr = xgetgrnam(argv[1]); /* unknown group: exit */
[1765]187 /* check if user is already in this group */
188 for (; *(gr->gr_mem) != NULL; (gr->gr_mem)++) {
189 if (!strcmp(argv[0], *(gr->gr_mem))) {
190 /* user is already in group: do nothing */
191 return EXIT_SUCCESS;
192 }
193 }
[2725]194 if (update_passwd(bb_path_group_file, argv[1], NULL, argv[0]) < 0) {
195 return EXIT_FAILURE;
196 }
197# if ENABLE_FEATURE_SHADOWPASSWDS
198 update_passwd(bb_path_gshadow_file, argv[1], NULL, argv[0]);
199# endif
[1765]200 } else
201#endif /* ENABLE_FEATURE_ADDUSER_TO_GROUP */
[2725]202 {
203 die_if_bad_username(argv[0]);
[3621]204 new_group(argv[0], xatou_range(gid, 0, CONFIG_LAST_ID));
[2725]205 }
[1765]206 /* Reached only on success */
207 return EXIT_SUCCESS;
[821]208}
Note: See TracBrowser for help on using the repository browser.