diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-22 21:35:52 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-22 21:35:52 +0000 |
commit | c2931aa2df2ddc6a627f3c40eb1cf5c221067092 (patch) | |
tree | 8b4b92c8c5bea933f7ea68302328bd17c0610b4a /loginutils/addgroup.c | |
parent | c8d7109f6036fab6b5993c24fc6514ba0c6a7d3d (diff) | |
download | busybox-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.c | 63 |
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 */ | ||
14 | static void xgroup_study(struct group *g) | 18 | static 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 | ||
84 | static 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) | |||
74 | int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 97 | int addgroup_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
75 | int addgroup_main(int argc UNUSED_PARAM, char **argv) | 98 | int 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(); |