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

Last change on this file since 3621 was 3621, checked in by Bruno Cornec, 7 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.