diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-06-21 20:03:07 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-06-21 20:03:07 +0000 |
commit | f0f754aeaf47b416abba8206dd2632cf24bb94a3 (patch) | |
tree | 35490bf58aa4b99b4b9c97e37c3bf5beb92b5168 | |
parent | 9d9cecfd633b58fb493e5ab9f9472ada7f772627 (diff) | |
download | busybox-w32-f0f754aeaf47b416abba8206dd2632cf24bb94a3.tar.gz busybox-w32-f0f754aeaf47b416abba8206dd2632cf24bb94a3.tar.bz2 busybox-w32-f0f754aeaf47b416abba8206dd2632cf24bb94a3.zip |
Based on a tinylogin patch from Philip Blundell, add several
additional options to adduser.
-Erik
-rw-r--r-- | include/usage.h | 10 | ||||
-rw-r--r-- | loginutils/adduser.c | 104 |
2 files changed, 81 insertions, 33 deletions
diff --git a/include/usage.h b/include/usage.h index 9b5f484c1..d60a4dc78 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -10,9 +10,13 @@ | |||
10 | #define adduser_full_usage \ | 10 | #define adduser_full_usage \ |
11 | "Adds a user to the system" \ | 11 | "Adds a user to the system" \ |
12 | "Options:\n" \ | 12 | "Options:\n" \ |
13 | "\t-h\t\thome directory\n" \ | 13 | "\t-h DIR\t\tAssign home directory DIR\n" \ |
14 | "\t-s\t\tshell\n" \ | 14 | "\t-g GECOS\t\tAssign gecos field GECOS\n" \ |
15 | "\t-g\t\tGECOS string\n" | 15 | "\t-s SHELL\t\tAssign login shell SHELL\n" \ |
16 | "\t-G\t\tAdd the user to existing group GROUP\n" \ | ||
17 | "\t-S\t\tcreate a system user (ignored)\n" \ | ||
18 | "\t-D\t\tDo not assign a password (logins still possible via ssh)\n" \ | ||
19 | "\t-H\t\tDo not create the home directory\n" | ||
16 | 20 | ||
17 | #define adjtimex_trivial_usage \ | 21 | #define adjtimex_trivial_usage \ |
18 | "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]" | 22 | "[-q] [-o offset] [-f frequency] [-p timeconstant] [-t tick]" |
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 6784d32cc..41dc9f019 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -21,6 +21,9 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef _GNU_SOURCE | ||
25 | #define _GNU_SOURCE | ||
26 | #endif | ||
24 | #include <errno.h> | 27 | #include <errno.h> |
25 | #include <fcntl.h> | 28 | #include <fcntl.h> |
26 | #include <stdarg.h> | 29 | #include <stdarg.h> |
@@ -29,6 +32,7 @@ | |||
29 | #include <string.h> | 32 | #include <string.h> |
30 | #include <time.h> | 33 | #include <time.h> |
31 | #include <unistd.h> | 34 | #include <unistd.h> |
35 | #include <getopt.h> | ||
32 | #include <sys/param.h> | 36 | #include <sys/param.h> |
33 | #include <sys/stat.h> | 37 | #include <sys/stat.h> |
34 | #include <sys/types.h> | 38 | #include <sys/types.h> |
@@ -89,21 +93,23 @@ static int passwd_study(const char *filename, struct passwd *p) | |||
89 | } | 93 | } |
90 | } | 94 | } |
91 | 95 | ||
92 | /* EDR check for an already existing gid */ | 96 | if (p->pw_gid == 0) { |
93 | while (getgrgid(p->pw_uid) != NULL) | 97 | /* EDR check for an already existing gid */ |
94 | p->pw_uid++; | 98 | while (getgrgid(p->pw_uid) != NULL) |
99 | p->pw_uid++; | ||
100 | |||
101 | /* EDR also check for an existing group definition */ | ||
102 | if (getgrnam(p->pw_name) != NULL) | ||
103 | return 3; | ||
95 | 104 | ||
96 | /* EDR also check for an existing group definition */ | 105 | /* EDR create new gid always = uid */ |
97 | if (getgrnam(p->pw_name) != NULL) | 106 | p->pw_gid = p->pw_uid; |
98 | return 3; | 107 | } |
99 | 108 | ||
100 | /* EDR bounds check */ | 109 | /* EDR bounds check */ |
101 | if ((p->pw_uid > max) || (p->pw_uid < min)) | 110 | if ((p->pw_uid > max) || (p->pw_uid < min)) |
102 | return 2; | 111 | return 2; |
103 | 112 | ||
104 | /* EDR create new gid always = uid */ | ||
105 | p->pw_gid = p->pw_uid; | ||
106 | |||
107 | /* return 1; */ | 113 | /* return 1; */ |
108 | return 0; | 114 | return 0; |
109 | } | 115 | } |
@@ -127,7 +133,7 @@ static void passwd_wrapper(const char *login) | |||
127 | } | 133 | } |
128 | 134 | ||
129 | /* putpwent(3) remix */ | 135 | /* putpwent(3) remix */ |
130 | static int adduser(const char *filename, struct passwd *p) | 136 | static int adduser(const char *filename, struct passwd *p, int makehome, int setpass) |
131 | { | 137 | { |
132 | FILE *passwd; | 138 | FILE *passwd; |
133 | int r; | 139 | int r; |
@@ -135,6 +141,11 @@ static int adduser(const char *filename, struct passwd *p) | |||
135 | FILE *shadow; | 141 | FILE *shadow; |
136 | struct spwd *sp; | 142 | struct spwd *sp; |
137 | #endif | 143 | #endif |
144 | int new_group = 1; | ||
145 | |||
146 | /* if using a pre-existing group, don't create one */ | ||
147 | if (p->pw_gid != 0) | ||
148 | new_group = 0; | ||
138 | 149 | ||
139 | /* make sure everything is kosher and setup uid && gid */ | 150 | /* make sure everything is kosher and setup uid && gid */ |
140 | passwd = bb_wfopen(filename, "a"); | 151 | passwd = bb_wfopen(filename, "a"); |
@@ -181,29 +192,38 @@ static int adduser(const char *filename, struct passwd *p) | |||
181 | } | 192 | } |
182 | #endif | 193 | #endif |
183 | 194 | ||
184 | /* add to group */ | 195 | if (new_group) { |
185 | /* addgroup should be responsible for dealing w/ gshadow */ | 196 | /* add to group */ |
186 | addgroup_wrapper(p->pw_name, p->pw_gid); | 197 | /* addgroup should be responsible for dealing w/ gshadow */ |
198 | addgroup_wrapper(p->pw_name, p->pw_gid); | ||
199 | } | ||
187 | 200 | ||
188 | /* Clear the umask for this process so it doesn't | 201 | /* Clear the umask for this process so it doesn't |
189 | * * screw up the permissions on the mkdir and chown. */ | 202 | * * screw up the permissions on the mkdir and chown. */ |
190 | umask(0); | 203 | umask(0); |
191 | 204 | ||
192 | /* mkdir */ | 205 | if (makehome) { |
193 | if (mkdir(p->pw_dir, 0755)) { | 206 | /* mkdir */ |
194 | bb_perror_msg("%s", p->pw_dir); | 207 | if (mkdir(p->pw_dir, 0755)) { |
195 | } | 208 | bb_perror_msg("%s", p->pw_dir); |
196 | /* Set the owner and group so it is owned by the new user. */ | 209 | } |
197 | if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { | 210 | /* Set the owner and group so it is owned by the new user. */ |
198 | bb_perror_msg("%s", p->pw_dir); | 211 | if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { |
212 | bb_perror_msg("%s", p->pw_dir); | ||
213 | } | ||
214 | /* Now fix up the permissions to 2755. Can't do it before now | ||
215 | * since chown will clear the setgid bit */ | ||
216 | if (chmod(p->pw_dir, 02755)) { | ||
217 | bb_perror_msg("%s", p->pw_dir); | ||
218 | } | ||
199 | } | 219 | } |
200 | /* Now fix up the permissions to 2755. Can't do it before now | 220 | |
201 | * since chown will clear the setgid bit */ | 221 | if (setpass) { |
202 | if (chmod(p->pw_dir, 02755)) { | 222 | /* interactively set passwd */ |
203 | bb_perror_msg("%s", p->pw_dir); | 223 | passwd_wrapper(p->pw_name); |
204 | } | 224 | } |
205 | /* interactively set passwd */ | 225 | |
206 | passwd_wrapper(p->pw_name); | 226 | return 0; |
207 | } | 227 | } |
208 | 228 | ||
209 | 229 | ||
@@ -219,6 +239,9 @@ void if_i_am_not_root(void) | |||
219 | } | 239 | } |
220 | } | 240 | } |
221 | 241 | ||
242 | #define SETPASS 1 | ||
243 | #define MAKEHOME 4 | ||
244 | |||
222 | /* | 245 | /* |
223 | * adduser will take a login_name as its first parameter. | 246 | * adduser will take a login_name as its first parameter. |
224 | * | 247 | * |
@@ -230,19 +253,29 @@ void if_i_am_not_root(void) | |||
230 | * ________________________________________________________________________ */ | 253 | * ________________________________________________________________________ */ |
231 | int adduser_main(int argc, char **argv) | 254 | int adduser_main(int argc, char **argv) |
232 | { | 255 | { |
256 | struct passwd pw; | ||
233 | const char *login; | 257 | const char *login; |
234 | const char *gecos = default_gecos; | 258 | const char *gecos = default_gecos; |
235 | const char *home = NULL; | 259 | const char *home = NULL; |
236 | const char *shell = default_shell; | 260 | const char *shell = default_shell; |
237 | 261 | const char *usegroup = NULL; | |
238 | struct passwd pw; | 262 | int flags; |
263 | int setpass = 1; | ||
264 | int makehome = 1; | ||
239 | 265 | ||
240 | /* init */ | 266 | /* init */ |
241 | if (argc < 2) { | 267 | if (argc < 2) { |
242 | bb_show_usage(); | 268 | bb_show_usage(); |
243 | } | 269 | } |
244 | /* get args */ | 270 | /* get args */ |
245 | bb_getopt_ulflags(argc, argv, "h:g:s:", &home, &gecos, &shell); | 271 | flags = bb_getopt_ulflags(argc, argv, "h:g:s:G:DSH", &home, &gecos, &shell, &usegroup); |
272 | |||
273 | if (flags & SETPASS) { | ||
274 | setpass = 0; | ||
275 | } | ||
276 | if (flags & MAKEHOME) { | ||
277 | makehome = 0; | ||
278 | } | ||
246 | 279 | ||
247 | /* got root? */ | 280 | /* got root? */ |
248 | if_i_am_not_root(); | 281 | if_i_am_not_root(); |
@@ -271,6 +304,17 @@ int adduser_main(int argc, char **argv) | |||
271 | pw.pw_dir = (char *)home; | 304 | pw.pw_dir = (char *)home; |
272 | pw.pw_shell = (char *)shell; | 305 | pw.pw_shell = (char *)shell; |
273 | 306 | ||
307 | if (usegroup) { | ||
308 | /* Add user to a group that already exists */ | ||
309 | struct group *g; | ||
310 | |||
311 | g = getgrnam(usegroup); | ||
312 | if (g == NULL) | ||
313 | bb_error_msg_and_die("group %s does not exist", usegroup); | ||
314 | |||
315 | pw.pw_gid = g->gr_gid; | ||
316 | } | ||
317 | |||
274 | /* grand finale */ | 318 | /* grand finale */ |
275 | return adduser(bb_path_passwd_file, &pw); | 319 | return adduser(bb_path_passwd_file, &pw, makehome, setpass); |
276 | } | 320 | } |