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