aboutsummaryrefslogtreecommitdiff
path: root/loginutils/addgroup.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-22 21:35:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-22 21:35:52 +0000
commitc2931aa2df2ddc6a627f3c40eb1cf5c221067092 (patch)
tree8b4b92c8c5bea933f7ea68302328bd17c0610b4a /loginutils/addgroup.c
parentc8d7109f6036fab6b5993c24fc6514ba0c6a7d3d (diff)
downloadbusybox-w32-c2931aa2df2ddc6a627f3c40eb1cf5c221067092.tar.gz
busybox-w32-c2931aa2df2ddc6a627f3c40eb1cf5c221067092.tar.bz2
busybox-w32-c2931aa2df2ddc6a627f3c40eb1cf5c221067092.zip
adduser/addgroup: support specifying uid/gid, add system
account creation mode. By Tito. function old new delta adduser_main 650 726 +76 addgroup_main 341 402 +61 addgroup_longopts - 16 +16 adduser_longopts 97 103 +6 packed_usage 26161 26163 +2 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/0 up/down: 161/0) Total: 161 bytes
Diffstat (limited to 'loginutils/addgroup.c')
-rw-r--r--loginutils/addgroup.c63
1 files changed, 43 insertions, 20 deletions
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c
index 5a0cf3fff..cb839290d 100644
--- a/loginutils/addgroup.c
+++ b/loginutils/addgroup.c
@@ -11,34 +11,50 @@
11 */ 11 */
12#include "libbb.h" 12#include "libbb.h"
13 13
14#define OPT_GID (1 << 0)
15#define OPT_SYSTEM_ACCOUNT (1 << 1)
16
17/* We assume GID_T_MAX == INT_MAX */
14static void xgroup_study(struct group *g) 18static void xgroup_study(struct group *g)
15{ 19{
20 unsigned max = INT_MAX;
21
16 /* Make sure gr_name is unused */ 22 /* Make sure gr_name is unused */
17 if (getgrnam(g->gr_name)) { 23 if (getgrnam(g->gr_name)) {
18 goto error; 24 bb_error_msg_and_die("%s '%s' in use", "group", g->gr_name);
25 /* these format strings are reused in adduser and addgroup */
19 } 26 }
20 27
28 /* if a specific gid is requested, the --system switch and */
29 /* min and max values are overriden, and the range of valid */
30 /* gid values is set to [0, INT_MAX] */
31 if (!(option_mask32 & OPT_GID)) {
32 if (option_mask32 & OPT_SYSTEM_ACCOUNT) {
33 g->gr_gid = 100; /* FIRST_SYSTEM_GID */
34 max = 999; /* LAST_SYSTEM_GID */
35 } else {
36 g->gr_gid = 1000; /* FIRST_GID */
37 max = 64999; /* LAST_GID */
38 }
39 }
21 /* Check if the desired gid is free 40 /* Check if the desired gid is free
22 * or find the first free one */ 41 * or find the first free one */
23 while (1) { 42 while (1) {
24 if (!getgrgid(g->gr_gid)) { 43 if (!getgrgid(g->gr_gid)) {
25 return; /* found free group: return */ 44 return; /* found free group: return */
26 } 45 }
27 if (option_mask32) { 46 if (option_mask32 & OPT_GID) {
28 /* -g N, cannot pick gid other than N: error */ 47 /* -g N, cannot pick gid other than N: error */
29 g->gr_name = itoa(g->gr_gid); 48 bb_error_msg_and_die("%s '%s' in use", "gid", itoa(g->gr_gid));
30 goto error; 49 /* this format strings is reused in adduser and addgroup */
31 } 50 }
32 g->gr_gid++; 51 if (g->gr_gid == max) {
33 if (g->gr_gid <= 0) {
34 /* overflowed: error */ 52 /* overflowed: error */
35 bb_error_msg_and_die("no gids left"); 53 bb_error_msg_and_die("no %cids left", 'g');
54 /* this format string is reused in adduser and addgroup */
36 } 55 }
56 g->gr_gid++;
37 } 57 }
38
39 error:
40 /* exit */
41 bb_error_msg_and_die("group %s already exists", g->gr_name);
42} 58}
43 59
44/* append a new user to the passwd file */ 60/* append a new user to the passwd file */
@@ -53,7 +69,7 @@ static void new_group(char *group, gid_t gid)
53 xgroup_study(&gr); 69 xgroup_study(&gr);
54 70
55 /* add entry to group */ 71 /* add entry to group */
56 p = xasprintf("x:%u:", gr.gr_gid); 72 p = xasprintf("x:%u:", (unsigned) gr.gr_gid);
57 if (update_passwd(bb_path_group_file, group, p, NULL) < 0) 73 if (update_passwd(bb_path_group_file, group, p, NULL) < 0)
58 exit(EXIT_FAILURE); 74 exit(EXIT_FAILURE);
59 if (ENABLE_FEATURE_CLEAN_UP) 75 if (ENABLE_FEATURE_CLEAN_UP)
@@ -64,6 +80,13 @@ static void new_group(char *group, gid_t gid)
64#endif 80#endif
65} 81}
66 82
83#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
84static const char addgroup_longopts[] ALIGN1 =
85 "gid\0" Required_argument "g"
86 "system\0" No_argument "S"
87 ;
88#endif
89
67/* 90/*
68 * addgroup will take a login_name as its first parameter. 91 * addgroup will take a login_name as its first parameter.
69 * 92 *
@@ -74,23 +97,23 @@ static void new_group(char *group, gid_t gid)
74int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 97int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
75int addgroup_main(int argc UNUSED_PARAM, char **argv) 98int addgroup_main(int argc UNUSED_PARAM, char **argv)
76{ 99{
77 char *group; 100 unsigned opts;
78 gid_t gid = 0; 101 unsigned gid = 0;
79 102
80 /* need to be root */ 103 /* need to be root */
81 if (geteuid()) { 104 if (geteuid()) {
82 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 105 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
83 } 106 }
84 107#if ENABLE_FEATURE_ADDGROUP_LONG_OPTIONS
108 applet_long_options = addgroup_longopts;
109#endif
85 /* Syntax: 110 /* Syntax:
86 * addgroup group 111 * addgroup group
87 * addgroup -g num group 112 * addgroup -g num group
88 * addgroup user group 113 * addgroup user group
89 * Check for min, max and missing args */ 114 * Check for min, max and missing args */
90 opt_complementary = "-1:?2"; 115 opt_complementary = "-1:?2:g+";
91 if (getopt32(argv, "g:", &group)) { 116 opts = getopt32(argv, "g:S", &gid);
92 gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1);
93 }
94 /* move past the commandline options */ 117 /* move past the commandline options */
95 argv += optind; 118 argv += optind;
96 //argc -= optind; 119 //argc -= optind;
@@ -99,7 +122,7 @@ int addgroup_main(int argc UNUSED_PARAM, char **argv)
99 if (argv[1]) { 122 if (argv[1]) {
100 struct group *gr; 123 struct group *gr;
101 124
102 if (option_mask32) { 125 if (opts & OPT_GID) {
103 /* -g was there, but "addgroup -g num user group" 126 /* -g was there, but "addgroup -g num user group"
104 * is a no-no */ 127 * is a no-no */
105 bb_show_usage(); 128 bb_show_usage();