diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-30 12:32:37 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-07-30 12:32:37 +0000 |
commit | f1f1b69dc12d489ef8b8cd1fb4114d404407e481 (patch) | |
tree | 9db38af23628c5c8e8b97f8aed67b5e0333fa7b5 /loginutils/addgroup.c | |
parent | 980864de081536ac8b5bdb053abea622da72ad75 (diff) | |
download | busybox-w32-f1f1b69dc12d489ef8b8cd1fb4114d404407e481.tar.gz busybox-w32-f1f1b69dc12d489ef8b8cd1fb4114d404407e481.tar.bz2 busybox-w32-f1f1b69dc12d489ef8b8cd1fb4114d404407e481.zip |
addgroup: "disallow addgroup -g num user group"; make -g 0 work
(Tito <farmatito@tiscali.it>)
Diffstat (limited to 'loginutils/addgroup.c')
-rw-r--r-- | loginutils/addgroup.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c index b29b66527..cf7cca907 100644 --- a/loginutils/addgroup.c +++ b/loginutils/addgroup.c | |||
@@ -14,34 +14,32 @@ | |||
14 | 14 | ||
15 | static void xgroup_study(struct group *g) | 15 | static void xgroup_study(struct group *g) |
16 | { | 16 | { |
17 | enum { max = 65000 }; | ||
18 | /* Use a particular gid. */ | ||
19 | int desired = (g->gr_gid > 0); | ||
20 | |||
21 | /* Make sure gr_name is unused */ | 17 | /* Make sure gr_name is unused */ |
22 | if (getgrnam(g->gr_name)) { | 18 | if (getgrnam(g->gr_name)) { |
23 | goto error; | 19 | goto error; |
24 | } | 20 | } |
25 | 21 | ||
26 | /* Check if the desired gid is free or | 22 | /* Check if the desired gid is free |
27 | find the first free one */ | 23 | * or find the first free one */ |
28 | do { | 24 | while (1) { |
29 | if (g->gr_gid == max) { /* out of bounds: exit */ | ||
30 | bb_error_msg_and_die("no gids left"); | ||
31 | } | ||
32 | if (!getgrgid(g->gr_gid)) { | 25 | if (!getgrgid(g->gr_gid)) { |
33 | return; /* ok */ | 26 | return; /* found free group: return */ |
34 | } | 27 | } |
35 | if (desired) { /* the desired gid is already in use: exit */ | 28 | if (option_mask32) { |
29 | /* -g N, cannot pick gid other than N: error */ | ||
36 | g->gr_name = itoa(g->gr_gid); | 30 | g->gr_name = itoa(g->gr_gid); |
37 | goto error; | 31 | goto error; |
38 | } | 32 | } |
39 | g->gr_gid++; | 33 | g->gr_gid++; |
40 | } while (1); | 34 | if (g->gr_gid <= 0) { |
35 | /* overflowed: error */ | ||
36 | bb_error_msg_and_die("no gids left"); | ||
37 | } | ||
38 | } | ||
41 | 39 | ||
42 | error: | 40 | error: |
43 | /* exit */ | 41 | /* exit */ |
44 | bb_error_msg_and_die("%s: already in use", g->gr_name); | 42 | bb_error_msg_and_die("group %s already exists", g->gr_name); |
45 | } | 43 | } |
46 | 44 | ||
47 | /* append a new user to the passwd file */ | 45 | /* append a new user to the passwd file */ |
@@ -53,7 +51,7 @@ static void new_group(char *group, gid_t gid) | |||
53 | /* make sure gid and group haven't already been allocated */ | 51 | /* make sure gid and group haven't already been allocated */ |
54 | gr.gr_gid = gid; | 52 | gr.gr_gid = gid; |
55 | gr.gr_name = group; | 53 | gr.gr_name = group; |
56 | xgroup_study( &gr); | 54 | xgroup_study(&gr); |
57 | 55 | ||
58 | /* add entry to group */ | 56 | /* add entry to group */ |
59 | file = xfopen(bb_path_group_file, "a"); | 57 | file = xfopen(bb_path_group_file, "a"); |
@@ -88,7 +86,7 @@ static void add_user_to_group(char **args, | |||
88 | while ((line = xmalloc_getline(group_file))) { | 86 | while ((line = xmalloc_getline(group_file))) { |
89 | /* Find the group */ | 87 | /* Find the group */ |
90 | if (!strncmp(line, args[1], len) | 88 | if (!strncmp(line, args[1], len) |
91 | && line[len] == ':' | 89 | && line[len] == ':' |
92 | ) { | 90 | ) { |
93 | /* Add the new user */ | 91 | /* Add the new user */ |
94 | line = xasprintf("%s%s%s", line, | 92 | line = xasprintf("%s%s%s", line, |
@@ -121,7 +119,7 @@ static void add_user_to_group(char **args, | |||
121 | * addgroup will take a login_name as its first parameter. | 119 | * addgroup will take a login_name as its first parameter. |
122 | * | 120 | * |
123 | * gid can be customized via command-line parameters. | 121 | * gid can be customized via command-line parameters. |
124 | * If called with two non-option arguments, addgroup | 122 | * If called with two non-option arguments, addgroup |
125 | * will add an existing user to an existing group. | 123 | * will add an existing user to an existing group. |
126 | */ | 124 | */ |
127 | int addgroup_main(int argc, char **argv); | 125 | int addgroup_main(int argc, char **argv); |
@@ -130,24 +128,34 @@ int addgroup_main(int argc, char **argv) | |||
130 | char *group; | 128 | char *group; |
131 | gid_t gid = 0; | 129 | gid_t gid = 0; |
132 | 130 | ||
133 | /* check for min, max and missing args and exit on error */ | 131 | /* need to be root */ |
134 | opt_complementary = "-1:?2:?"; | 132 | if (geteuid()) { |
133 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | ||
134 | } | ||
135 | |||
136 | /* Syntax: | ||
137 | * addgroup group | ||
138 | * addgroup -g num group | ||
139 | * addgroup user group | ||
140 | * Check for min, max and missing args */ | ||
141 | opt_complementary = "-1:?2"; | ||
135 | if (getopt32(argc, argv, "g:", &group)) { | 142 | if (getopt32(argc, argv, "g:", &group)) { |
136 | gid = xatoul_range(group, 0, (gid_t)ULONG_MAX); | 143 | gid = xatoul_range(group, 0, ((unsigned long)(gid_t)ULONG_MAX) >> 1); |
137 | } | 144 | } |
138 | /* move past the commandline options */ | 145 | /* move past the commandline options */ |
139 | argv += optind; | 146 | argv += optind; |
140 | argc -= optind; | 147 | argc -= optind; |
141 | 148 | ||
142 | /* need to be root */ | ||
143 | if (geteuid()) { | ||
144 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | ||
145 | } | ||
146 | |||
147 | #if ENABLE_FEATURE_ADDUSER_TO_GROUP | 149 | #if ENABLE_FEATURE_ADDUSER_TO_GROUP |
148 | if (argc == 2) { | 150 | if (argc == 2) { |
149 | struct group *gr; | 151 | struct group *gr; |
150 | 152 | ||
153 | if (option_mask32) { | ||
154 | /* -g was there, but "addgroup -g num user group" | ||
155 | * is a no-no */ | ||
156 | bb_show_usage(); | ||
157 | } | ||
158 | |||
151 | /* check if group and user exist */ | 159 | /* check if group and user exist */ |
152 | xuname2uid(argv[0]); /* unknown user: exit */ | 160 | xuname2uid(argv[0]); /* unknown user: exit */ |
153 | xgroup2gid(argv[1]); /* unknown group: exit */ | 161 | xgroup2gid(argv[1]); /* unknown group: exit */ |