Print this page
4078 groupadd execs getent unnecessarily
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: Gary Mills <gary_mills@fastmail.fm>
Reviewed by: Milan Jurik <milan.jurik@xylab.cz>
Reviewed by: Gordon Ross <Gordon.W.Ross@gmail.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/oamuser/user/useradd.c
+++ new/usr/src/cmd/oamuser/user/useradd.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 27 /* All Rights Reserved */
28 28
29 +/*
30 + * Copyright (c) 2013 RackTop Systems.
31 + */
29 32
30 33 #include <sys/types.h>
31 34 #include <sys/stat.h>
32 35 #include <sys/param.h>
33 36 #include <stdio.h>
34 37 #include <stdlib.h>
35 38 #include <ctype.h>
36 39 #include <limits.h>
37 40 #include <string.h>
38 41 #include <userdefs.h>
39 42 #include <errno.h>
40 43 #include <project.h>
41 44 #include <unistd.h>
42 45 #include <user_attr.h>
46 +#include <libcmdutils.h>
43 47 #include "users.h"
44 48 #include "messages.h"
45 49 #include "userdisp.h"
46 50 #include "funcs.h"
47 51
48 52 /*
49 53 * useradd [-u uid [-o] | -g group | -G group [[, group]...] | -d dir [-m]
50 54 * | -s shell | -c comment | -k skel_dir | -b base_dir] ]
51 55 * [ -A authorization [, authorization ...]]
52 56 * [ -P profile [, profile ...]]
53 57 * [ -K key=value ]
54 58 * [ -R role [, role ...]] [-p project [, project ...]] login
55 59 * useradd -D [ -g group ] [ -b base_dir | -f inactive | -e expire |
56 60 * -s shell | -k skel_dir ]
57 61 * [ -A authorization [, authorization ...]]
58 62 * [ -P profile [, profile ...]] [ -K key=value ]
59 63 * [ -R role [, role ...]] [-p project [, project ...]] login
60 64 *
61 65 * This command adds new user logins to the system. Arguments are:
62 66 *
63 67 * uid - an integer
64 68 * group - an existing group's integer ID or char string name
65 69 * dir - home directory
66 70 * shell - a program to be used as a shell
67 71 * comment - any text string
68 72 * skel_dir - a skeleton directory
69 73 * base_dir - a directory
70 74 * login - a string of printable chars except colon(:)
71 75 * authorization - One or more comma separated authorizations defined
72 76 * in auth_attr(4).
73 77 * profile - One or more comma separated execution profiles defined
74 78 * in prof_attr(4)
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
75 79 * role - One or more comma-separated role names defined in user_attr(4)
76 80 * project - One or more comma-separated project names or numbers
77 81 *
78 82 */
79 83
80 84 extern struct userdefs *getusrdef();
81 85 extern void dispusrdef();
82 86
83 87 static void cleanup();
84 88
85 -extern uid_t findnextuid(void);
86 89 extern int check_perm(), valid_expire();
87 90 extern int putusrdef(), valid_uid();
88 91 extern int call_passmgmt(), edit_group(), create_home();
89 92 extern int edit_project();
90 93 extern int **valid_lgroup();
91 94 extern projid_t **valid_lproject();
92 95 extern void update_def(struct userdefs *);
93 96 extern void import_def(struct userdefs *);
94 97
95 98 static uid_t uid; /* new uid */
96 99 static char *logname; /* login name to add */
97 100 static struct userdefs *usrdefs; /* defaults for useradd */
98 101
99 102 char *cmdname;
100 103
101 104 static char homedir[ PATH_MAX + 1 ]; /* home directory */
102 105 static char gidstring[32]; /* group id string representation */
103 106 static gid_t gid; /* gid of new login */
104 107 static char uidstring[32]; /* user id string representation */
105 108 static char *uidstr = NULL; /* uid from command line */
106 109 static char *base_dir = NULL; /* base_dir from command line */
107 110 static char *group = NULL; /* group from command line */
108 111 static char *grps = NULL; /* multi groups from command line */
109 112 static char *dir = NULL; /* home dir from command line */
110 113 static char *shell = NULL; /* shell from command line */
111 114 static char *comment = NULL; /* comment from command line */
112 115 static char *skel_dir = NULL; /* skel dir from command line */
113 116 static long inact; /* inactive days */
114 117 static char *inactstr = NULL; /* inactive from command line */
115 118 static char inactstring[10]; /* inactivity string representation */
116 119 static char *expirestr = NULL; /* expiration date from command line */
117 120 static char *projects = NULL; /* project id's from command line */
118 121
119 122 static char *usertype = NULL; /* type of user, either role or normal */
120 123
121 124 typedef enum {
122 125 BASEDIR = 0,
123 126 SKELDIR,
124 127 SHELL
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
125 128 } path_opt_t;
126 129
127 130
128 131 static void valid_input(path_opt_t, const char *);
129 132
130 133 int
131 134 main(argc, argv)
132 135 int argc;
133 136 char *argv[];
134 137 {
135 - int ch, ret, mflag = 0, oflag = 0, Dflag = 0, **gidlist;
136 - projid_t **projlist;
138 + int ch, ret, mflag = 0, oflag = 0, Dflag = 0, **gidlist = NULL;
139 + projid_t **projlist = NULL;
137 140 char *ptr; /* loc in a str, may be set by strtol */
138 141 struct group *g_ptr;
139 142 struct project p_ptr;
140 143 char mybuf[PROJECT_BUFSZ];
141 144 struct stat statbuf; /* status buffer for stat */
142 145 int warning;
143 146 int busy = 0;
144 147 char **nargv; /* arguments for execvp of passmgmt */
145 148 int argindex; /* argument index into nargv */
146 149
147 150 cmdname = argv[0];
148 151
149 152 if (geteuid() != 0) {
150 153 errmsg(M_PERM_DENIED);
151 154 exit(EX_NO_PERM);
152 155 }
153 156
154 157 opterr = 0; /* no print errors from getopt */
155 158 usertype = getusertype(argv[0]);
156 159
157 160 change_key(USERATTR_TYPE_KW, usertype);
158 161
159 162 while ((ch = getopt(argc, argv,
160 163 "b:c:Dd:e:f:G:g:k:mop:s:u:A:P:R:K:")) != EOF)
161 164 switch (ch) {
162 165 case 'b':
163 166 base_dir = optarg;
164 167 break;
165 168
166 169 case 'c':
167 170 comment = optarg;
168 171 break;
169 172
170 173 case 'D':
171 174 Dflag++;
172 175 break;
173 176
174 177 case 'd':
175 178 dir = optarg;
176 179 break;
177 180
178 181 case 'e':
179 182 expirestr = optarg;
180 183 break;
181 184
182 185 case 'f':
183 186 inactstr = optarg;
184 187 break;
185 188
186 189 case 'G':
187 190 grps = optarg;
188 191 break;
189 192
190 193 case 'g':
191 194 group = optarg;
192 195 break;
193 196
194 197 case 'k':
195 198 skel_dir = optarg;
196 199 break;
197 200
198 201 case 'm':
199 202 mflag++;
200 203 break;
201 204
202 205 case 'o':
203 206 oflag++;
204 207 break;
205 208
206 209 case 'p':
207 210 projects = optarg;
208 211 break;
209 212
210 213 case 's':
211 214 shell = optarg;
212 215 break;
213 216
214 217 case 'u':
215 218 uidstr = optarg;
216 219 break;
217 220
218 221 case 'A':
219 222 change_key(USERATTR_AUTHS_KW, optarg);
220 223 break;
221 224
222 225 case 'P':
223 226 change_key(USERATTR_PROFILES_KW, optarg);
224 227 break;
225 228
226 229 case 'R':
227 230 if (is_role(usertype)) {
228 231 errmsg(M_ARUSAGE);
229 232 exit(EX_SYNTAX);
230 233 }
231 234 change_key(USERATTR_ROLES_KW, optarg);
232 235 break;
233 236
234 237 case 'K':
235 238 change_key(NULL, optarg);
236 239 break;
237 240
238 241 default:
239 242 case '?':
240 243 if (is_role(usertype))
241 244 errmsg(M_ARUSAGE);
242 245 else
243 246 errmsg(M_AUSAGE);
244 247 exit(EX_SYNTAX);
245 248 }
246 249
247 250 /* get defaults for adding new users */
248 251 usrdefs = getusrdef(usertype);
249 252
250 253 if (Dflag) {
251 254 /* DISPLAY mode */
252 255
253 256 /* check syntax */
254 257 if (optind != argc) {
255 258 if (is_role(usertype))
256 259 errmsg(M_ARUSAGE);
257 260 else
258 261 errmsg(M_AUSAGE);
259 262 exit(EX_SYNTAX);
260 263 }
261 264
262 265 if (uidstr != NULL || oflag || grps != NULL ||
263 266 dir != NULL || mflag || comment != NULL) {
264 267 if (is_role(usertype))
265 268 errmsg(M_ARUSAGE);
266 269 else
267 270 errmsg(M_AUSAGE);
268 271 exit(EX_SYNTAX);
269 272 }
270 273
271 274 /* Group must be an existing group */
272 275 if (group != NULL) {
273 276 switch (valid_group(group, &g_ptr, &warning)) {
274 277 case INVALID:
275 278 errmsg(M_INVALID, group, "group id");
276 279 exit(EX_BADARG);
277 280 /*NOTREACHED*/
278 281 case TOOBIG:
279 282 errmsg(M_TOOBIG, "gid", group);
280 283 exit(EX_BADARG);
281 284 /*NOTREACHED*/
282 285 case RESERVED:
283 286 case UNIQUE:
284 287 errmsg(M_GRP_NOTUSED, group);
285 288 exit(EX_NAME_NOT_EXIST);
286 289 }
287 290 if (warning)
288 291 warningmsg(warning, group);
289 292
290 293 usrdefs->defgroup = g_ptr->gr_gid;
291 294 usrdefs->defgname = g_ptr->gr_name;
292 295
293 296 }
294 297
295 298 /* project must be an existing project */
296 299 if (projects != NULL) {
297 300 switch (valid_project(projects, &p_ptr, mybuf,
298 301 sizeof (mybuf), &warning)) {
299 302 case INVALID:
300 303 errmsg(M_INVALID, projects, "project id");
301 304 exit(EX_BADARG);
302 305 /*NOTREACHED*/
303 306 case TOOBIG:
304 307 errmsg(M_TOOBIG, "projid", projects);
305 308 exit(EX_BADARG);
306 309 /*NOTREACHED*/
307 310 case UNIQUE:
308 311 errmsg(M_PROJ_NOTUSED, projects);
309 312 exit(EX_NAME_NOT_EXIST);
310 313 }
311 314 if (warning)
312 315 warningmsg(warning, projects);
313 316
314 317 usrdefs->defproj = p_ptr.pj_projid;
315 318 usrdefs->defprojname = p_ptr.pj_name;
316 319 }
317 320
318 321 /* base_dir must be an existing directory */
319 322 if (base_dir != NULL) {
320 323 valid_input(BASEDIR, base_dir);
321 324 usrdefs->defparent = base_dir;
322 325 }
323 326
324 327 /* inactivity period is an integer */
325 328 if (inactstr != NULL) {
326 329 /* convert inactstr to integer */
327 330 inact = strtol(inactstr, &ptr, 10);
328 331 if (*ptr || inact < 0) {
329 332 errmsg(M_INVALID, inactstr,
330 333 "inactivity period");
331 334 exit(EX_BADARG);
332 335 }
333 336
334 337 usrdefs->definact = inact;
335 338 }
336 339
337 340 /* expiration string is a date, newer than today */
338 341 if (expirestr != NULL) {
339 342 if (*expirestr) {
340 343 if (valid_expire(expirestr, (time_t *)0)
341 344 == INVALID) {
342 345 errmsg(M_INVALID, expirestr,
343 346 "expiration date");
344 347 exit(EX_BADARG);
345 348 }
346 349 usrdefs->defexpire = expirestr;
347 350 } else
348 351 /* Unset the expiration date */
349 352 usrdefs->defexpire = "";
350 353 }
351 354
352 355 if (shell != NULL) {
353 356 valid_input(SHELL, shell);
354 357 usrdefs->defshell = shell;
355 358 }
356 359 if (skel_dir != NULL) {
357 360 valid_input(SKELDIR, skel_dir);
358 361 usrdefs->defskel = skel_dir;
359 362 }
360 363 update_def(usrdefs);
361 364
362 365 /* change defaults for useradd */
363 366 if (putusrdef(usrdefs, usertype) < 0) {
364 367 errmsg(M_UPDATE, "created");
365 368 exit(EX_UPDATE);
366 369 }
367 370
368 371 /* Now, display */
369 372 dispusrdef(stdout, (D_ALL & ~D_RID), usertype);
370 373 exit(EX_SUCCESS);
371 374
372 375 }
373 376
374 377 /* ADD mode */
375 378
376 379 /* check syntax */
377 380 if (optind != argc - 1 || (skel_dir != NULL && !mflag)) {
378 381 if (is_role(usertype))
379 382 errmsg(M_ARUSAGE);
380 383 else
381 384 errmsg(M_AUSAGE);
382 385 exit(EX_SYNTAX);
383 386 }
384 387
385 388 logname = argv[optind];
386 389 switch (valid_login(logname, (struct passwd **)NULL, &warning)) {
387 390 case INVALID:
388 391 errmsg(M_INVALID, logname, "login name");
389 392 exit(EX_BADARG);
390 393 /*NOTREACHED*/
391 394
392 395 case NOTUNIQUE:
393 396 errmsg(M_USED, logname);
394 397 exit(EX_NAME_EXISTS);
395 398 /*NOTREACHED*/
396 399 }
397 400
398 401 if (warning)
399 402 warningmsg(warning, logname);
400 403 if (uidstr != NULL) {
401 404 /* convert uidstr to integer */
402 405 errno = 0;
403 406 uid = (uid_t)strtol(uidstr, &ptr, (int)10);
404 407 if (*ptr || errno == ERANGE) {
405 408 errmsg(M_INVALID, uidstr, "user id");
406 409 exit(EX_BADARG);
407 410 }
408 411
409 412 switch (valid_uid(uid, NULL)) {
410 413 case NOTUNIQUE:
411 414 if (!oflag) {
412 415 /* override not specified */
413 416 errmsg(M_UID_USED, uid);
414 417 exit(EX_ID_EXISTS);
415 418 }
416 419 break;
417 420 case RESERVED:
↓ open down ↓ |
271 lines elided |
↑ open up ↑ |
418 421 errmsg(M_RESERVED, uid);
419 422 break;
420 423 case TOOBIG:
421 424 errmsg(M_TOOBIG, "uid", uid);
422 425 exit(EX_BADARG);
423 426 break;
424 427 }
425 428
426 429 } else {
427 430
428 - if ((uid = findnextuid()) < 0) {
431 + if (findnextuid(DEFRID+1, MAXUID, &uid) != 0) {
429 432 errmsg(M_INVALID, "default id", "user id");
430 433 exit(EX_ID_EXISTS);
431 434 }
432 435 }
433 436
434 437 if (group != NULL) {
435 438 switch (valid_group(group, &g_ptr, &warning)) {
436 439 case INVALID:
437 440 errmsg(M_INVALID, group, "group id");
438 441 exit(EX_BADARG);
439 442 /*NOTREACHED*/
440 443 case TOOBIG:
441 444 errmsg(M_TOOBIG, "gid", group);
442 445 exit(EX_BADARG);
443 446 /*NOTREACHED*/
444 447 case RESERVED:
445 448 case UNIQUE:
446 449 errmsg(M_GRP_NOTUSED, group);
447 450 exit(EX_NAME_NOT_EXIST);
448 451 /*NOTREACHED*/
449 452 }
450 453
451 454 if (warning)
452 455 warningmsg(warning, group);
453 456 gid = g_ptr->gr_gid;
454 457
455 458 } else gid = usrdefs->defgroup;
456 459
457 460 if (grps != NULL) {
458 461 if (!*grps)
459 462 /* ignore -G "" */
460 463 grps = (char *)0;
461 464 else if (!(gidlist = valid_lgroup(grps, gid)))
462 465 exit(EX_BADARG);
463 466 }
464 467
465 468 if (projects != NULL) {
466 469 if (! *projects)
467 470 projects = (char *)0;
468 471 else if (! (projlist = valid_lproject(projects)))
469 472 exit(EX_BADARG);
470 473 }
471 474
472 475 /* if base_dir is provided, check its validity; otherwise default */
473 476 if (base_dir != NULL)
474 477 valid_input(BASEDIR, base_dir);
475 478 else
476 479 base_dir = usrdefs->defparent;
477 480
478 481 if (dir == NULL) {
479 482 /* set homedir to home directory made from base_dir */
480 483 (void) sprintf(homedir, "%s/%s", base_dir, logname);
481 484
482 485 } else if (REL_PATH(dir)) {
483 486 errmsg(M_RELPATH, dir);
484 487 exit(EX_BADARG);
485 488
486 489 } else
487 490 (void) strcpy(homedir, dir);
488 491
489 492 if (mflag) {
490 493 /* Does home dir. already exist? */
491 494 if (stat(homedir, &statbuf) == 0) {
492 495 /* directory exists - don't try to create */
493 496 mflag = 0;
494 497
495 498 if (check_perm(statbuf, uid, gid, S_IXOTH) != 0)
496 499 errmsg(M_NO_PERM, logname, homedir);
497 500 }
498 501 }
499 502 /*
500 503 * if shell, skel_dir are provided, check their validity.
501 504 * Otherwise default.
502 505 */
503 506 if (shell != NULL)
504 507 valid_input(SHELL, shell);
505 508 else
506 509 shell = usrdefs->defshell;
507 510
508 511 if (skel_dir != NULL)
509 512 valid_input(SKELDIR, skel_dir);
510 513 else
511 514 skel_dir = usrdefs->defskel;
512 515
513 516 if (inactstr != NULL) {
514 517 /* convert inactstr to integer */
515 518 inact = strtol(inactstr, &ptr, 10);
516 519 if (*ptr || inact < 0) {
517 520 errmsg(M_INVALID, inactstr, "inactivity period");
518 521 exit(EX_BADARG);
519 522 }
520 523 } else inact = usrdefs->definact;
521 524
522 525 /* expiration string is a date, newer than today */
523 526 if (expirestr != NULL) {
524 527 if (*expirestr) {
525 528 if (valid_expire(expirestr, (time_t *)0) == INVALID) {
526 529 errmsg(M_INVALID, expirestr, "expiration date");
527 530 exit(EX_BADARG);
528 531 }
529 532 usrdefs->defexpire = expirestr;
530 533 } else
531 534 /* Unset the expiration date */
532 535 expirestr = (char *)0;
533 536
534 537 } else expirestr = usrdefs->defexpire;
535 538
536 539 import_def(usrdefs);
537 540
538 541 /* must now call passmgmt */
539 542
540 543 /* set up arguments to passmgmt in nargv array */
541 544 nargv = malloc((30 + nkeys * 2) * sizeof (char *));
542 545 argindex = 0;
543 546 nargv[argindex++] = PASSMGMT;
544 547 nargv[argindex++] = "-a"; /* add */
545 548
546 549 if (comment != NULL) {
547 550 /* comment */
548 551 nargv[argindex++] = "-c";
549 552 nargv[argindex++] = comment;
550 553 }
551 554
552 555 /* flags for home directory */
553 556 nargv[argindex++] = "-h";
554 557 nargv[argindex++] = homedir;
555 558
556 559 /* set gid flag */
557 560 nargv[argindex++] = "-g";
558 561 (void) sprintf(gidstring, "%u", gid);
559 562 nargv[argindex++] = gidstring;
560 563
561 564 /* shell */
562 565 nargv[argindex++] = "-s";
563 566 nargv[argindex++] = shell;
564 567
565 568 /* set inactive */
566 569 nargv[argindex++] = "-f";
567 570 (void) sprintf(inactstring, "%ld", inact);
568 571 nargv[argindex++] = inactstring;
569 572
570 573 /* set expiration date */
571 574 if (expirestr != NULL) {
572 575 nargv[argindex++] = "-e";
573 576 nargv[argindex++] = expirestr;
574 577 }
575 578
576 579 /* set uid flag */
577 580 nargv[argindex++] = "-u";
578 581 (void) sprintf(uidstring, "%u", uid);
579 582 nargv[argindex++] = uidstring;
580 583
581 584 if (oflag) nargv[argindex++] = "-o";
582 585
583 586 if (nkeys > 1)
584 587 addkey_args(nargv, &argindex);
585 588
586 589 /* finally - login name */
587 590 nargv[argindex++] = logname;
588 591
589 592 /* set the last to null */
590 593 nargv[argindex++] = NULL;
591 594
592 595 /* now call passmgmt */
593 596 ret = PEX_FAILED;
594 597 /*
595 598 * If call_passmgmt fails for any reason other than PEX_BADUID, exit
596 599 * is invoked with an appropriate error message. If PEX_BADUID is
597 600 * returned, then if the user specified the ID, exit is invoked
598 601 * with an appropriate error message. Otherwise we try to pick a
599 602 * different ID and try again. If we run out of IDs, i.e. no more
600 603 * users can be created, then -1 is returned and we terminate via exit.
601 604 * If PEX_BUSY is returned we increment a count, since we will stop
602 605 * trying if PEX_BUSY reaches 3. For PEX_SUCCESS we immediately
603 606 * terminate the loop.
604 607 */
605 608 while (busy < 3 && ret != PEX_SUCCESS) {
606 609 switch (ret = call_passmgmt(nargv)) {
607 610 case PEX_SUCCESS:
608 611 break;
609 612 case PEX_BUSY:
610 613 busy++;
611 614 break;
612 615 case PEX_HOSED_FILES:
613 616 errmsg(M_HOSED_FILES);
614 617 exit(EX_INCONSISTENT);
615 618 break;
616 619
617 620 case PEX_SYNTAX:
618 621 case PEX_BADARG:
619 622 /* should NEVER occur that passmgmt usage is wrong */
620 623 if (is_role(usertype))
621 624 errmsg(M_ARUSAGE);
622 625 else
623 626 errmsg(M_AUSAGE);
624 627 exit(EX_SYNTAX);
625 628 break;
626 629
↓ open down ↓ |
188 lines elided |
↑ open up ↑ |
627 630 case PEX_BADUID:
628 631 /*
629 632 * The uid has been taken. If it was specified by a
630 633 * user, then we must fail. Otherwise, keep trying
631 634 * to get a good uid until we run out of IDs.
632 635 */
633 636 if (uidstr != NULL) {
634 637 errmsg(M_UID_USED, uid);
635 638 exit(EX_ID_EXISTS);
636 639 } else {
637 - if ((uid = findnextuid()) < 0) {
640 + if (findnextuid(DEFRID+1, MAXUID, &uid) != 0) {
638 641 errmsg(M_INVALID, "default id",
639 642 "user id");
640 643 exit(EX_ID_EXISTS);
641 644 }
642 645 (void) sprintf(uidstring, "%u", uid);
643 646 }
644 647 break;
645 648
646 649 case PEX_BADNAME:
647 650 /* invalid loname */
648 651 errmsg(M_USED, logname);
649 652 exit(EX_NAME_EXISTS);
650 653 break;
651 654
652 655 default:
653 656 errmsg(M_UPDATE, "created");
654 657 exit(ret);
655 658 break;
656 659 }
657 660 }
658 661 if (busy == 3) {
659 662 errmsg(M_UPDATE, "created");
660 663 exit(ret);
661 664 }
662 665
663 666 /* add group entry */
664 667 if ((grps != NULL) && edit_group(logname, (char *)0, gidlist, 0)) {
665 668 errmsg(M_UPDATE, "created");
666 669 cleanup(logname);
667 670 exit(EX_UPDATE);
668 671 }
669 672
670 673 /* update project database */
671 674 if ((projects != NULL) &&
672 675 edit_project(logname, (char *)NULL, projlist, 0)) {
673 676 errmsg(M_UPDATE, "created");
674 677 cleanup(logname);
675 678 exit(EX_UPDATE);
676 679 }
677 680
678 681 /* create home directory */
679 682 if (mflag &&
680 683 (create_home(homedir, skel_dir, uid, gid) != EX_SUCCESS)) {
681 684 (void) edit_group(logname, (char *)0, (int **)0, 1);
682 685 cleanup(logname);
683 686 exit(EX_HOMEDIR);
684 687 }
685 688
686 689 return (ret);
687 690 }
688 691
689 692 static void
690 693 cleanup(logname)
691 694 char *logname;
692 695 {
693 696 char *nargv[4];
694 697
695 698 nargv[0] = PASSMGMT;
696 699 nargv[1] = "-d";
697 700 nargv[2] = logname;
698 701 nargv[3] = NULL;
699 702
700 703 switch (call_passmgmt(nargv)) {
701 704 case PEX_SUCCESS:
702 705 break;
703 706
704 707 case PEX_SYNTAX:
705 708 /* should NEVER occur that passmgmt usage is wrong */
706 709 if (is_role(usertype))
707 710 errmsg(M_ARUSAGE);
708 711 else
709 712 errmsg(M_AUSAGE);
710 713 break;
711 714
712 715 case PEX_BADUID:
713 716 /* uid is used - shouldn't happen but print message anyway */
714 717 errmsg(M_UID_USED, uid);
715 718 break;
716 719
717 720 case PEX_BADNAME:
718 721 /* invalid loname */
719 722 errmsg(M_USED, logname);
720 723 break;
721 724
722 725 default:
723 726 errmsg(M_UPDATE, "created");
724 727 break;
725 728 }
726 729 }
727 730
728 731 /* Check the validity for shell, base_dir and skel_dir */
729 732
730 733 void
731 734 valid_input(path_opt_t opt, const char *input)
732 735 {
733 736 struct stat statbuf;
734 737
735 738 if (REL_PATH(input)) {
736 739 errmsg(M_RELPATH, input);
737 740 exit(EX_BADARG);
738 741 }
739 742 if (stat(input, &statbuf) == -1) {
740 743 errmsg(M_INVALID, input, "path");
741 744 exit(EX_BADARG);
742 745 }
743 746 if (opt == SHELL) {
744 747 if (!S_ISREG(statbuf.st_mode) ||
745 748 (statbuf.st_mode & 0555) != 0555) {
746 749 errmsg(M_INVALID, input, "shell");
747 750 exit(EX_BADARG);
748 751 }
749 752 } else {
750 753 if (!S_ISDIR(statbuf.st_mode)) {
751 754 errmsg(M_INVALID, input, "directory");
752 755 exit(EX_BADARG);
753 756 }
754 757 }
755 758 }
↓ open down ↓ |
108 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX