source: MondoRescue/branches/3.2/mindi-busybox/loginutils/addgroup.c@ 3232

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