1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <auth_attr.h> 30 #include <auth_list.h> 31 #include <dirent.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <libintl.h> 35 #include <locale.h> 36 #include <pwd.h> 37 #include <signal.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <strings.h> 42 #include <unistd.h> 43 #include <bsm/devices.h> 44 #include <sys/acl.h> 45 #include <tsol/label.h> 46 #include <syslog.h> 47 #include <limits.h> 48 #include <user_attr.h> 49 #include <secdb.h> 50 #include <sys/mkdev.h> 51 #include <sys/acl.h> 52 #include <sys/file.h> 53 #include <sys/procfs.h> 54 #include <sys/param.h> 55 #include <sys/resource.h> 56 #include <sys/stat.h> 57 #include <sys/time.h> 58 #include <sys/types.h> 59 #include <sys/wait.h> 60 #include <utime.h> 61 #include <libgen.h> 62 #include <zone.h> 63 #include <nss_dbdefs.h> 64 #include <bsm/devalloc.h> 65 #include "allocate.h" 66 67 extern void print_error(int, char *); 68 69 #if defined(DEBUG) || defined(lint) 70 #define dprintf(s, a) (void) fprintf(stderr, s, a) 71 #define dperror(s) perror(s) 72 #else /* !DEBUG */ 73 #define dprintf(s, a) 0 74 #define dperror(s) 0 75 #endif /* DEBUG */ 76 77 #define DEV_ERRORED(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_ERR_MODE) 78 #define DEV_INVALID(sbuf) (((sbuf).st_mode & ~S_IFMT) == ALLOC_INVALID) 79 #define DEV_ALLOCATED(sbuf) ((sbuf).st_uid != ALLOC_UID || \ 80 !(((sbuf).st_mode & ~S_IFMT) == DEALLOC_MODE || \ 81 DEV_ERRORED(sbuf) || DEV_INVALID(sbuf))) 82 83 #define ALLOC_CLEAN "-A" 84 #define DEALLOC_CLEAN "-D" 85 #define DAC_DIR "/etc/security/dev" 86 #define DEVICE_AUTH_SEPARATOR "," 87 #define LOCALDEVICE "/dev/console" 88 #define PROCFS "/proc/" 89 #define SFF_NO_ERROR 0x1 90 91 #define ALLOC_BY_NONE -1 92 #define CHECK_DRANGE 1 93 #define CHECK_URANGE 2 94 #define CHECK_ZLABEL 3 95 96 extern void audit_allocate_list(char *); 97 extern void audit_allocate_device(char *); 98 99 extern int system_labeled; 100 extern char *newenv[]; 101 102 struct state_file { 103 int sf_flags; 104 char sf_path[MAXPATHLEN]; 105 }; 106 107 struct file_info { 108 struct stat fi_stat; 109 char *fi_message; 110 }; 111 112 struct zone_path { 113 int count; 114 char **path; 115 }; 116 117 struct devnames { 118 char **dnames; 119 }; 120 121 static int _dev_file_name(struct state_file *, devmap_t *); 122 static int lock_dev(char *); 123 static int _check_label(devalloc_t *, char *, uid_t, int); 124 static int create_znode(char *, struct zone_path *, devmap_t *); 125 static int remove_znode(char *, devmap_t *); 126 static int update_device(char **, char *, int); 127 128 /* 129 * checks if the invoking user is local to the device 130 */ 131 /*ARGSUSED*/ 132 int 133 _is_local(uid_t uid) 134 { 135 struct stat statbuf; 136 137 if (stat(LOCALDEVICE, &statbuf) == 0 && 138 statbuf.st_uid == uid) 139 return (1); 140 141 return (0); 142 } 143 144 /* 145 * Checks if the user with the specified uid has the specified authorization 146 */ 147 int 148 _is_authorized(char *auths, uid_t uid) 149 { 150 char *dcp, *authlist, *lasts; 151 char pw_buf[NSS_BUFLEN_PASSWD]; 152 struct passwd pw_ent; 153 154 /* 155 * first, the easy cases 156 */ 157 if (strcmp(auths, "@") == 0) 158 return (1); 159 if (strcmp(auths, "*") == 0) 160 return (ALLOC_BY_NONE); 161 if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) 162 return (0); 163 if (strpbrk(auths, DEVICE_AUTH_SEPARATOR) == NULL) 164 return (chkauthattr(auths, pw_ent.pw_name)); 165 authlist = strdup(auths); 166 if (authlist == NULL) 167 return (0); 168 for (dcp = authlist; 169 (dcp = strtok_r(dcp, DEVICE_AUTH_SEPARATOR, &lasts)) != NULL; 170 dcp = NULL) { 171 if (chkauthattr(dcp, pw_ent.pw_name)) 172 break; 173 } 174 free(authlist); 175 176 return (dcp != NULL); 177 } 178 179 /* 180 * Checks if the specified user has authorization for the device 181 */ 182 int 183 _is_dev_authorized(devalloc_t *da, uid_t uid) 184 { 185 int ares; 186 char *auth_list, *dcp, *subauth = NULL; 187 188 auth_list = da->da_devauth; 189 if (auth_list == NULL) 190 return (0); 191 dcp = strpbrk(auth_list, KV_TOKEN_DELIMIT); 192 if (dcp == NULL) 193 return (_is_authorized(auth_list, uid)); 194 if (_is_local(uid)) { 195 /* the local authorization is before the separator */ 196 ares = dcp - auth_list; 197 subauth = malloc(ares + 1); 198 if (subauth == NULL) 199 return (0); 200 (void) strlcpy(subauth, auth_list, (ares + 1)); 201 auth_list = subauth; 202 } else 203 auth_list = dcp + 1; 204 ares = _is_authorized(auth_list, uid); 205 if (subauth != NULL) 206 free(subauth); 207 208 return (ares); 209 } 210 211 int 212 check_devs(devmap_t *dm) 213 { 214 int status = 0; 215 char **file; 216 217 if (dm->dmap_devarray == NULL) 218 return (NODMAPERR); 219 for (file = dm->dmap_devarray; *file != NULL; file++) { 220 if ((status = access(*file, F_OK)) == -1) { 221 dprintf("Unable to access file %s\n", *file); 222 break; 223 } 224 } 225 226 return (status); 227 } 228 229 int 230 print_da_defs(da_defs_t *da_defs) 231 { 232 char optbuf[BUFSIZ]; 233 char *p = NULL; 234 235 if (da_defs->devopts == NULL) { 236 dprintf("No default attributes for %s\n", da_defs->devtype); 237 return (DEFATTRSERR); 238 } 239 (void) printf("dev_type=%s\n", da_defs->devtype); 240 if (_kva2str(da_defs->devopts, optbuf, sizeof (optbuf), KV_ASSIGN, 241 KV_TOKEN_DELIMIT) == 0) { 242 if (p = rindex(optbuf, ':')) 243 *p = '\0'; 244 (void) printf("\t%s\n", optbuf); 245 } 246 247 return (0); 248 } 249 250 void 251 print_dev_attrs(int optflag, devalloc_t *da, devmap_t *dm, 252 struct file_info *fip) 253 { 254 char *p = NULL; 255 char optbuf[BUFSIZ]; 256 257 (void) printf("device=%s%s", dm->dmap_devname, KV_DELIMITER); 258 (void) printf("type=%s%s", dm->dmap_devtype, KV_DELIMITER); 259 (void) printf("auths=%s%s", 260 (da->da_devauth ? da->da_devauth : ""), KV_DELIMITER); 261 (void) printf("clean=%s%s", 262 (da->da_devexec ? da->da_devexec : ""), KV_DELIMITER); 263 if (da->da_devopts != NULL) { 264 if (_kva2str(da->da_devopts, optbuf, sizeof (optbuf), 265 KV_ASSIGN, KV_TOKEN_DELIMIT) == 0) { 266 if (p = rindex(optbuf, ':')) 267 *p = '\0'; 268 (void) printf("%s", optbuf); 269 } 270 } 271 (void) printf("%s", KV_DELIMITER); 272 if (optflag & WINDOWING) { 273 if (DEV_INVALID(fip->fi_stat)) 274 (void) printf("owner=/INVALID:%s%s", fip->fi_message, 275 KV_DELIMITER); 276 else if (DEV_ERRORED(fip->fi_stat)) 277 (void) printf("owner=/ERROR%s", KV_DELIMITER); 278 else if (!DEV_ALLOCATED(fip->fi_stat)) 279 (void) printf("owner=/FREE%s", KV_DELIMITER); 280 else 281 (void) printf("owner=%ld%s", fip->fi_stat.st_uid, 282 KV_DELIMITER); 283 } 284 (void) printf("files=%s", dm->dmap_devlist); 285 (void) printf("\n"); 286 } 287 288 void 289 print_dev(devmap_t *dm) 290 { 291 char **file; 292 293 (void) printf(gettext("device: %s "), dm->dmap_devname); 294 (void) printf(gettext("type: %s "), dm->dmap_devtype); 295 (void) printf(gettext("files:")); 296 file = dm->dmap_devarray; 297 if (file != NULL) { 298 for (; *file != NULL; file++) 299 (void) printf(" %s", *file); 300 } 301 (void) printf("\n"); 302 } 303 304 /* ARGSUSED */ 305 int 306 _list_device(int optflag, uid_t uid, devalloc_t *da, char *zonename) 307 { 308 int bytes = 0; 309 int error = 0; 310 int is_authorized = 0; 311 char *fname = NULL; 312 char file_name[MAXPATHLEN]; 313 devmap_t *dm; 314 struct file_info fi; 315 struct state_file sf; 316 317 setdmapent(); 318 if ((dm = getdmapnam(da->da_devname)) == NULL) { 319 enddmapent(); 320 dprintf("Unable to find %s in the maps database\n", 321 da->da_devname); 322 return (NODMAPERR); 323 } 324 enddmapent(); 325 if (system_labeled) { 326 if ((error = _dev_file_name(&sf, dm)) != 0) { 327 freedmapent(dm); 328 dprintf("Unable to find %s device files\n", 329 da->da_devname); 330 error = NODMAPERR; 331 goto out; 332 } 333 fname = sf.sf_path; 334 } else { 335 bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR, 336 da->da_devname); 337 if (bytes <= 0) { 338 error = DEVNAMEERR; 339 goto out; 340 } else if (bytes >= MAXPATHLEN) { 341 dprintf("device name %s is too long.\n", 342 da->da_devname); 343 error = DEVLONGERR; 344 goto out; 345 } 346 fname = file_name; 347 } 348 if (stat(fname, &fi.fi_stat) != 0) { 349 dprintf("Unable to stat %s\n", fname); 350 dperror("Error:"); 351 error = DACACCERR; 352 goto out; 353 } 354 if (optflag & USERID) 355 is_authorized = 1; 356 else 357 is_authorized = _is_dev_authorized(da, uid); 358 if (optflag & LISTFREE) { /* list_devices -n */ 359 /* 360 * list all free devices 361 */ 362 if (DEV_ALLOCATED(fi.fi_stat)) { 363 error = PREALLOCERR; 364 goto out; 365 } 366 if (system_labeled) { 367 /* 368 * for this free device, check if - 369 * 1. user has authorization to allocate 370 * 2. the zone label is within the label range of the 371 * device 372 */ 373 if (is_authorized == ALLOC_BY_NONE) { 374 error = DAUTHERR; 375 goto out; 376 } else if (is_authorized == 0) { 377 error = UAUTHERR; 378 goto out; 379 } 380 if (_check_label(da, zonename, uid, 381 CHECK_DRANGE) != 0) { 382 error = LABELRNGERR; 383 goto out; 384 } 385 } 386 } else if (optflag & LISTALLOC) { /* list_devices -u */ 387 /* 388 * list all allocated devices 389 */ 390 if (!DEV_ALLOCATED(fi.fi_stat)) { 391 error = DEVNALLOCERR; 392 goto out; 393 } 394 if (fi.fi_stat.st_uid != uid) { 395 error = DEVSTATEERR; 396 goto out; 397 } 398 if (system_labeled) { 399 /* 400 * check if the zone label equals the label at which 401 * the device is allocated. 402 */ 403 if (_check_label(da, zonename, uid, 404 CHECK_ZLABEL) != 0) { 405 error = LABELRNGERR; 406 goto out; 407 } 408 } 409 } else if (optflag & LISTALL) { /* list_devices -l */ 410 /* 411 * list all devices - free and allocated - available 412 */ 413 if (DEV_ALLOCATED(fi.fi_stat)) { 414 if (optflag & WINDOWING && 415 (is_authorized == ALLOC_BY_NONE)) { 416 /* 417 * don't complain if we're here for the GUI. 418 */ 419 error = 0; 420 } else if (fi.fi_stat.st_uid != uid) { 421 if (!(optflag & WINDOWING)) { 422 error = ALLOCUERR; 423 goto out; 424 } 425 } 426 if (system_labeled && !(optflag & WINDOWING)) { 427 /* 428 * if we're not displaying in the GUI, 429 * check if the zone label equals the label 430 * at which the device is allocated. 431 */ 432 if (_check_label(da, zonename, uid, 433 CHECK_ZLABEL) != 0) { 434 error = LABELRNGERR; 435 goto out; 436 } 437 } 438 } else if (system_labeled && !(optflag & WINDOWING)) { 439 /* 440 * if we're not displaying in the GUI, 441 * for this free device, check if - 442 * 1. user has authorization to allocate 443 * 2. the zone label is within the label range of the 444 * device 445 */ 446 if (is_authorized == ALLOC_BY_NONE) { 447 error = DAUTHERR; 448 goto out; 449 } else if (is_authorized == 0) { 450 error = UAUTHERR; 451 goto out; 452 } 453 if (_check_label(da, zonename, uid, 454 CHECK_DRANGE) != 0) { 455 error = LABELRNGERR; 456 goto out; 457 } 458 } 459 } 460 if (system_labeled && DEV_ERRORED(fi.fi_stat) && !(optflag & LISTALL)) { 461 error = DEVSTATEERR; 462 goto out; 463 } 464 if (check_devs(dm) == -1) { 465 error = DSPMISSERR; 466 goto out; 467 } 468 if (optflag & LISTATTRS) 469 print_dev_attrs(optflag, da, dm, &fi); 470 else 471 print_dev(dm); 472 473 error = 0; 474 475 out: 476 freedmapent(dm); 477 return (error); 478 } 479 480 /* ARGSUSED */ 481 int 482 list_devices(int optflag, uid_t uid, char *device, char *zonename) 483 { 484 int error = 0; 485 da_defs_t *da_defs; 486 devalloc_t *da; 487 488 if (system_labeled && optflag & WINDOWING && !(optflag & LISTATTRS)) { 489 /* 490 * Private interface for GUI. 491 */ 492 (void) lock_dev(NULL); 493 (void) puts(DA_DB_LOCK); 494 return (0); 495 } 496 if (optflag & USERID) { 497 /* 498 * we need device.revoke to list someone else's devices 499 */ 500 if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid())) 501 return (UAUTHERR); 502 } 503 if (system_labeled) { 504 if (!(optflag & USERID) && 505 !_is_authorized(DEFAULT_DEV_ALLOC_AUTH, uid)) 506 /* 507 * we need device.allocate to list our devices 508 */ 509 return (UAUTHERR); 510 if (optflag & LISTDEFS) { 511 /* 512 * list default attrs from devalloc_defaults 513 */ 514 setdadefent(); 515 if (device) { 516 /* 517 * list default attrs for this device type 518 */ 519 da_defs = getdadeftype(device); 520 if (da_defs == NULL) { 521 enddadefent(); 522 dprintf("No default attributes for " 523 "%s\n", device); 524 return (DEFATTRSERR); 525 } 526 error = print_da_defs(da_defs); 527 freedadefent(da_defs); 528 } else { 529 /* 530 * list everything in devalloc_defaults 531 */ 532 while ((da_defs = getdadefent()) != NULL) { 533 (void) print_da_defs(da_defs); 534 freedadefent(da_defs); 535 } 536 } 537 enddadefent(); 538 return (error); 539 } 540 } 541 setdaent(); 542 if (device) { 543 /* 544 * list this device 545 */ 546 if ((da = getdanam(device)) == NULL) { 547 enddaent(); 548 return (NODAERR); 549 } 550 error = _list_device(optflag, uid, da, zonename); 551 freedaent(da); 552 } else { 553 /* 554 * list all devices 555 */ 556 while ((da = getdaent()) != NULL) { 557 (void) _list_device(optflag, uid, da, zonename); 558 freedaent(da); 559 } 560 } 561 enddaent(); 562 563 return (error); 564 } 565 566 /* 567 * Set the DAC characteristics of the file. 568 * This uses a fancy chmod() by setting a minimal ACL which sets the mode 569 * and discards any existing ACL. 570 */ 571 int 572 _newdac(char *file, uid_t owner, gid_t group, o_mode_t mode) 573 { 574 int err = 0; 575 576 if (mode == ALLOC_MODE) { 577 if (chown(file, owner, group) == -1) { 578 dperror("newdac: unable to chown"); 579 err = CHOWNERR; 580 } 581 } else do { 582 if (chown(file, owner, group) == -1) { 583 dperror("newdac: unable to chown"); 584 err = CHOWNERR; 585 } 586 } while (fdetach(file) == 0); 587 588 if (err) 589 return (err); 590 591 if (strncmp(file, "/dev/", strlen("/dev/")) != 0) { 592 /* 593 * This could be a SunRay device that is in /tmp. 594 */ 595 if (chmod(file, mode) == -1) { 596 dperror("newdac: unable to chmod"); 597 err = SETACLERR; 598 } 599 } else { 600 err = acl_strip(file, owner, group, (mode_t)mode); 601 } 602 603 if (err != 0) { 604 dperror("newdac: unable to setacl"); 605 err = SETACLERR; 606 } 607 608 return (err); 609 } 610 611 static int 612 lock_dev(char *file) 613 { 614 int lockfd = -1; 615 616 if ((file == NULL) || system_labeled) 617 file = DA_DEV_LOCK; 618 dprintf("locking %s\n", file); 619 if ((lockfd = open(file, O_RDWR | O_CREAT, 0600)) == -1) { 620 dperror("lock_dev: cannot open lock file"); 621 return (DEVLKERR); 622 } 623 if (lockf(lockfd, F_TLOCK, 0) == -1) { 624 dperror("lock_dev: cannot set lock"); 625 return (DEVLKERR); 626 } 627 628 return (0); 629 } 630 631 int 632 mk_alloc(devmap_t *list, uid_t uid, struct zone_path *zpath) 633 { 634 int i; 635 int error = 0; 636 char **file; 637 gid_t gid = getgid(); 638 mode_t mode = ALLOC_MODE; 639 640 file = list->dmap_devarray; 641 if (file == NULL) 642 return (NODMAPERR); 643 for (; *file != NULL; file++) { 644 dprintf("Allocating %s\n", *file); 645 if ((error = _newdac(*file, uid, gid, mode)) != 0) { 646 (void) _newdac(*file, ALLOC_ERRID, ALLOC_GID, 647 ALLOC_ERR_MODE); 648 break; 649 } 650 } 651 if (system_labeled && zpath->count && (error == 0)) { 652 /* 653 * mark as allocated any new device nodes that we 654 * created in local zone 655 */ 656 for (i = 0; i < zpath->count; i++) { 657 dprintf("Allocating %s\n", zpath->path[i]); 658 if ((error = _newdac(zpath->path[i], uid, gid, 659 mode)) != 0) { 660 (void) _newdac(zpath->path[i], ALLOC_ERRID, 661 ALLOC_GID, ALLOC_ERR_MODE); 662 break; 663 } 664 } 665 } 666 667 return (error); 668 } 669 670 /* 671 * mk_revoke() is used instead of system("/usr/sbin/fuser -k file") 672 * because "/usr/sbin/fuser -k file" kills all processes 673 * working with the file, even "vold" (bug #4095152). 674 */ 675 int 676 mk_revoke(int optflag, char *file) 677 { 678 int r = 0, p[2], fp, lock; 679 int fuserpid; 680 char buf[MAXPATHLEN]; 681 FILE *ptr; 682 pid_t c_pid; 683 prpsinfo_t info; 684 685 (void) strcpy(buf, PROCFS); 686 /* 687 * vfork() and execl() just to make the same output 688 * as before fixing of bug #4095152. 689 * The problem is that the "fuser" command prints 690 * one part of output into stderr and another into stdout, 691 * but user sees them mixed. Of course, better to change "fuser" 692 * or to intercept and not to print its output. 693 */ 694 if (!(optflag & SILENT)) { 695 c_pid = vfork(); 696 if (c_pid == -1) 697 return (-1); 698 if (c_pid == 0) { 699 dprintf("first exec fuser %s\n", file); 700 (void) execl("/usr/sbin/fuser", "fuser", file, NULL); 701 dperror("first exec fuser"); 702 _exit(1); 703 } 704 705 (void) waitpid(c_pid, &lock, 0); 706 dprintf("exit status %x\n", lock); 707 if (WEXITSTATUS(lock) != 0) 708 return (-1); 709 } 710 dprintf("first continuing c_pid=%d\n", (int)c_pid); 711 if (pipe(p)) { 712 dperror("pipe"); 713 return (-1); 714 } 715 /* vfork() and execl() to catch output and to process it */ 716 c_pid = vfork(); 717 if (c_pid == -1) { 718 dperror("second vfork"); 719 return (-1); 720 } 721 dprintf("second continuing c_pid=%d\n", (int)c_pid); 722 if (c_pid == 0) { 723 (void) close(p[0]); 724 (void) close(1); 725 (void) fcntl(p[1], F_DUPFD, 1); 726 (void) close(p[1]); 727 (void) close(2); 728 dprintf("second exec fuser %s\n", file); 729 (void) execl("/usr/sbin/fuser", "fuser", file, NULL); 730 dperror("second exec fuser"); 731 _exit(1); 732 } 733 (void) close(p[1]); 734 if ((ptr = fdopen(p[0], "r")) != NULL) { 735 while (!feof(ptr)) { 736 if (fscanf(ptr, "%d", &fuserpid) > 0) { 737 (void) sprintf(buf + strlen(PROCFS), "%d", 738 fuserpid); 739 if ((fp = open(buf, O_RDONLY)) == -1) { 740 dperror(buf); 741 continue; 742 } 743 if (ioctl(fp, PIOCPSINFO, 744 (char *)&info) == -1) { 745 dprintf("%d psinfo failed", fuserpid); 746 dperror(""); 747 (void) close(fp); 748 continue; 749 } 750 (void) close(fp); 751 if (strcmp(info.pr_fname, "vold") == NULL) { 752 dprintf("%d matched vold name\n", 753 fuserpid); 754 continue; 755 } 756 dprintf("killing %s", info.pr_fname); 757 dprintf("(%d)\n", fuserpid); 758 if ((r = 759 kill((pid_t)fuserpid, SIGKILL)) == -1) { 760 dprintf("kill %d", fuserpid); 761 dperror(""); 762 break; 763 } 764 } 765 } 766 } else { 767 dperror("fdopen(p[0], r)"); 768 r = -1; 769 } 770 (void) fclose(ptr); 771 772 return (r); 773 } 774 775 int 776 mk_unalloc(int optflag, devmap_t *list) 777 { 778 int error = 0; 779 int status; 780 char **file; 781 782 audit_allocate_list(list->dmap_devlist); 783 file = list->dmap_devarray; 784 if (file == NULL) 785 return (NODMAPERR); 786 for (; *file != NULL; file++) { 787 dprintf("Deallocating %s\n", *file); 788 if (mk_revoke(optflag, *file) < 0) { 789 dprintf("mk_unalloc: unable to revoke %s\n", *file); 790 dperror(""); 791 error = CNTFRCERR; 792 } 793 status = _newdac(*file, ALLOC_UID, ALLOC_GID, DEALLOC_MODE); 794 if (error == 0) 795 error = status; 796 797 } 798 799 return (error); 800 } 801 802 int 803 mk_error(devmap_t *list) 804 { 805 int status = 0; 806 char **file; 807 808 audit_allocate_list(list->dmap_devlist); 809 file = list->dmap_devarray; 810 if (file == NULL) 811 return (NODMAPERR); 812 for (; *file != NULL; file++) { 813 dprintf("Putting %s in error state\n", *file); 814 status = _newdac(*file, ALLOC_ERRID, ALLOC_GID, ALLOC_ERR_MODE); 815 } 816 817 return (status); 818 } 819 820 int 821 exec_clean(int optflag, char *devname, char *path, uid_t uid, char *zonename, 822 char *clean_arg) 823 { 824 int c; 825 int status = 0, exit_status; 826 char *mode, *cmd, *wdwcmd, *zoneroot; 827 char *devzone = zonename; 828 char wdwpath[PATH_MAX]; 829 char zonepath[MAXPATHLEN]; 830 char title[100]; 831 char pw_buf[NSS_BUFLEN_PASSWD]; 832 struct passwd pw_ent; 833 834 zonepath[0] = '\0'; 835 if (system_labeled) { 836 if ((zoneroot = getzonerootbyname(zonename)) == NULL) { 837 if (strcmp(clean_arg, ALLOC_CLEAN) == 0) { 838 return (-1); 839 } else if (optflag & FORCE) { 840 (void) strcpy(zonepath, "/"); 841 devzone = GLOBAL_ZONENAME; 842 } else { 843 dprintf("unable to get label for %s zone\n", 844 zonename); 845 return (-1); 846 } 847 } else { 848 (void) strcpy(zonepath, zoneroot); 849 free(zoneroot); 850 } 851 } 852 if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) 853 return (-1); 854 if (optflag & FORCE_ALL) 855 mode = "-I"; 856 else if (optflag & FORCE) 857 mode = "-f"; 858 else 859 mode = "-s"; 860 if (path == NULL) 861 return (0); 862 if ((cmd = strrchr(path, '/')) == NULL) 863 cmd = path; 864 else 865 cmd++; /* skip leading '/' */ 866 c = vfork(); 867 switch (c) { 868 case -1: 869 return (-1); 870 case 0: 871 (void) setuid(0); 872 if (system_labeled && (optflag & WINDOWING)) { 873 /* First try .windowing version of script */ 874 (void) strncpy(wdwpath, path, PATH_MAX); 875 (void) strncat(wdwpath, ".windowing", PATH_MAX); 876 if ((wdwcmd = strrchr(wdwpath, '/')) == NULL) 877 wdwcmd = wdwpath; 878 (void) execl(wdwpath, wdwcmd, mode, devname, clean_arg, 879 pw_ent.pw_name, devzone, zonepath, NULL); 880 /* If that failed, run regular version via dtterm */ 881 (void) snprintf(title, sizeof (title), 882 "Device %s for %s", 883 strcmp(clean_arg, ALLOC_CLEAN) == 0 ? 884 "allocation" : "deallocation", devname); 885 (void) execl("/usr/dt/bin/dtterm", "dtterm", 886 "-title", title, "-geometry", "x10+100+400", 887 "-e", "/etc/security/lib/wdwwrapper", 888 path, mode, devname, clean_arg, pw_ent.pw_name, 889 devzone, zonepath, NULL); 890 /* 891 * And if that failed, continue on to try 892 * running regular version directly. 893 */ 894 } 895 dprintf("clean script: %s, ", path); 896 dprintf("cmd=%s, ", cmd); 897 dprintf("mode=%s, ", mode); 898 if (system_labeled) { 899 dprintf("devname=%s ", devname); 900 dprintf("zonename=%s ", devzone); 901 dprintf("zonepath=%s ", zonepath); 902 dprintf("username=%s\n", pw_ent.pw_name); 903 (void) execl(path, cmd, mode, devname, clean_arg, 904 pw_ent.pw_name, devzone, zonepath, NULL); 905 } else { 906 dprintf("devname=%s\n", devname); 907 (void) execle(path, cmd, mode, devname, NULL, newenv); 908 } 909 dprintf("Unable to execute clean up script %s\n", path); 910 dperror(""); 911 exit(CNTDEXECERR); 912 default: 913 (void) waitpid(c, &status, 0); 914 dprintf("Child %d", c); 915 if (WIFEXITED(status)) { 916 exit_status = WEXITSTATUS(status); 917 dprintf(" exited, status: %d\n", exit_status); 918 return (exit_status); 919 } else if (WIFSIGNALED(status)) { 920 dprintf(" killed, signal %d\n", WTERMSIG(status)); 921 } else { 922 dprintf(": exit status %d\n", status); 923 } 924 return (-1); 925 } 926 } 927 928 int 929 _deallocate_dev(int optflag, devalloc_t *da, devmap_t *dm_in, uid_t uid, 930 char *zonename) 931 { 932 int bytes = 0; 933 int error = 0; 934 int is_authorized = 0; 935 uid_t nuid; 936 char *fname = NULL; 937 char file_name[MAXPATHLEN]; 938 char *devzone = NULL; 939 devmap_t *dm = NULL, *dm_new = NULL; 940 struct stat stat_buf; 941 struct state_file sf; 942 943 if (dm_in == NULL) { 944 setdmapent(); 945 if ((dm_new = getdmapnam(da->da_devname)) == NULL) { 946 enddmapent(); 947 dprintf("Unable to find %s in device map database\n", 948 da->da_devname); 949 return (NODMAPERR); 950 } 951 enddmapent(); 952 dm = dm_new; 953 } else { 954 dm = dm_in; 955 } 956 if (system_labeled) { 957 if (_dev_file_name(&sf, dm) != 0) { 958 if (dm_new) 959 freedmapent(dm_new); 960 dprintf("Unable to find %s device files\n", 961 da->da_devname); 962 error = NODMAPERR; 963 goto out; 964 } 965 fname = sf.sf_path; 966 } else { 967 bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR, 968 da->da_devname); 969 if (bytes <= 0) { 970 error = DEVNAMEERR; 971 goto out; 972 } else if (bytes >= MAXPATHLEN) { 973 dprintf("device name %s is too long.\n", 974 da->da_devname); 975 error = DEVLONGERR; 976 goto out; 977 } 978 fname = file_name; 979 } 980 981 audit_allocate_device(fname); 982 983 if (stat(fname, &stat_buf) != 0) { 984 dprintf("Unable to stat %s\n", fname); 985 error = DACACCERR; 986 goto out; 987 } 988 is_authorized = _is_dev_authorized(da, uid); 989 if (!(optflag & (FORCE | FORCE_ALL)) && !is_authorized) { 990 dprintf("User %d is unauthorized to deallocate\n", (int)uid); 991 error = UAUTHERR; 992 goto out; 993 } 994 if (system_labeled) { 995 /* 996 * unless we're here to deallocate by force, check if the 997 * label at which the device is currently allocated is 998 * within the user label range. 999 */ 1000 if (!(optflag & FORCE) && 1001 _check_label(da, zonename, uid, CHECK_URANGE) != 0) { 1002 error = LABELRNGERR; 1003 goto out; 1004 } 1005 } 1006 if (!(optflag & FORCE) && stat_buf.st_uid != uid && 1007 DEV_ALLOCATED(stat_buf)) { 1008 error = ALLOCUERR; 1009 goto out; 1010 } 1011 if (!DEV_ALLOCATED(stat_buf)) { 1012 if (DEV_ERRORED(stat_buf)) { 1013 if (!(optflag & FORCE)) { 1014 error = DEVSTATEERR; 1015 goto out; 1016 } 1017 } else { 1018 error = DEVNALLOCERR; 1019 goto out; 1020 } 1021 } 1022 /* All checks passed, time to lock and deallocate */ 1023 if ((error = lock_dev(fname)) != 0) 1024 goto out; 1025 if (system_labeled) { 1026 devzone = kva_match(da->da_devopts, DAOPT_ZONE); 1027 if (devzone && (strcmp(devzone, GLOBAL_ZONENAME) != 0)) { 1028 if ((remove_znode(devzone, dm) != 0) && 1029 !(optflag & FORCE)) { 1030 error = ZONEERR; 1031 goto out; 1032 } 1033 } 1034 } 1035 if ((error = mk_unalloc(optflag, dm)) != 0) { 1036 if (!(optflag & FORCE)) 1037 goto out; 1038 } 1039 if (system_labeled == 0) { 1040 if ((error = _newdac(fname, ALLOC_UID, ALLOC_GID, 1041 DEALLOC_MODE)) != 0) { 1042 (void) _newdac(file_name, ALLOC_UID, ALLOC_GID, 1043 ALLOC_ERR_MODE); 1044 goto out; 1045 } 1046 } 1047 /* 1048 * if we are deallocating device owned by someone else, 1049 * pass the owner's uid to the cleaning script. 1050 */ 1051 nuid = (stat_buf.st_uid == uid) ? uid : stat_buf.st_uid; 1052 error = exec_clean(optflag, da->da_devname, da->da_devexec, nuid, 1053 devzone, DEALLOC_CLEAN); 1054 if (error != 0) { 1055 if (!(optflag & (FORCE | FORCE_ALL))) { 1056 error = CLEANERR; 1057 (void) mk_error(dm); 1058 } else { 1059 error = 0; 1060 } 1061 } 1062 1063 out: 1064 if (dm_new) 1065 freedmapent(dm_new); 1066 return (error); 1067 } 1068 1069 int 1070 _allocate_dev(int optflag, uid_t uid, devalloc_t *da, char *zonename) 1071 { 1072 int i; 1073 int bytes = 0; 1074 int error = 0; 1075 int is_authorized = 0; 1076 int dealloc_optflag = 0; 1077 char *fname = NULL; 1078 char file_name[MAXPATHLEN]; 1079 devmap_t *dm; 1080 struct stat stat_buf; 1081 struct state_file sf; 1082 struct zone_path zpath; 1083 1084 zpath.count = 0; 1085 zpath.path = NULL; 1086 setdmapent(); 1087 if ((dm = getdmapnam(da->da_devname)) == NULL) { 1088 enddmapent(); 1089 dprintf("Unable to find %s in device map database\n", 1090 da->da_devname); 1091 return (NODMAPERR); 1092 } 1093 enddmapent(); 1094 if (system_labeled) { 1095 if (_dev_file_name(&sf, dm) != 0) { 1096 freedmapent(dm); 1097 dprintf("Unable to find %s device files\n", 1098 da->da_devname); 1099 error = NODMAPERR; 1100 goto out; 1101 } 1102 fname = sf.sf_path; 1103 } else { 1104 bytes = snprintf(file_name, MAXPATHLEN, "%s/%s", DAC_DIR, 1105 da->da_devname); 1106 if (bytes <= 0) { 1107 error = DEVNAMEERR; 1108 goto out; 1109 } else if (bytes >= MAXPATHLEN) { 1110 dprintf("device name %s is too long.\n", 1111 da->da_devname); 1112 error = DEVLONGERR; 1113 goto out; 1114 } 1115 fname = file_name; 1116 } 1117 1118 (void) audit_allocate_device(fname); 1119 1120 if (stat(fname, &stat_buf) != 0) { 1121 dprintf("Unable to stat %s\n", fname); 1122 dperror("Error:"); 1123 error = DACACCERR; 1124 goto out; 1125 } 1126 if (DEV_ERRORED(stat_buf)) { 1127 error = DEVSTATEERR; 1128 goto out; 1129 } 1130 is_authorized = _is_dev_authorized(da, uid); 1131 if (is_authorized == ALLOC_BY_NONE) { 1132 dprintf("Device %s is not allocatable\n", da->da_devname); 1133 error = UAUTHERR; 1134 goto out; 1135 } else if (!is_authorized && !(optflag & USERNAME)) { 1136 dprintf("User %d is unauthorized to allocate\n", (int)uid); 1137 error = UAUTHERR; 1138 goto out; 1139 } 1140 if (system_labeled) { 1141 /* 1142 * check if label of the zone to which the device is being 1143 * allocated is within the device label range. 1144 */ 1145 if (_check_label(da, zonename, uid, CHECK_DRANGE) != 0) { 1146 error = LABELRNGERR; 1147 goto out; 1148 } 1149 } 1150 if (check_devs(dm) == -1) { 1151 error = DSPMISSERR; 1152 goto out; 1153 } 1154 if (DEV_ALLOCATED(stat_buf)) { 1155 if (optflag & FORCE) { 1156 if (optflag & SILENT) 1157 dealloc_optflag = FORCE|SILENT; 1158 else 1159 dealloc_optflag = FORCE; 1160 if (_deallocate_dev(dealloc_optflag, da, dm, uid, 1161 zonename)) { 1162 dprintf("Couldn't force deallocate device %s\n", 1163 da->da_devname); 1164 error = CNTFRCERR; 1165 goto out; 1166 } 1167 } else if (stat_buf.st_uid == uid) { 1168 error = PREALLOCERR; 1169 goto out; 1170 } else { 1171 error = ALLOCUERR; 1172 goto out; 1173 } 1174 } 1175 /* All checks passed, time to lock and allocate */ 1176 if ((error = lock_dev(fname)) != 0) 1177 goto out; 1178 if (system_labeled) { 1179 /* 1180 * Run the cleaning program; it also mounts allocated 1181 * device if required. 1182 */ 1183 error = exec_clean(optflag, da->da_devname, da->da_devexec, uid, 1184 zonename, ALLOC_CLEAN); 1185 if ((error != 0) && (error != CLEAN_MOUNT)) { 1186 error = CLEANERR; 1187 (void) mk_error(dm); 1188 goto out; 1189 } 1190 /* 1191 * If not mounted, create zonelinks, if this is not the 1192 * global zone. 1193 */ 1194 if ((strcmp(zonename, GLOBAL_ZONENAME) != 0) && 1195 (error != CLEAN_MOUNT)) { 1196 if (create_znode(zonename, &zpath, dm) != 0) { 1197 error = ZONEERR; 1198 goto out; 1199 } 1200 } 1201 } 1202 1203 (void) audit_allocate_list(dm->dmap_devlist); 1204 1205 if ((error = mk_alloc(dm, uid, &zpath)) != 0) { 1206 (void) mk_unalloc(optflag, dm); 1207 goto out; 1208 } 1209 1210 if (system_labeled == 0) { 1211 if ((error = _newdac(file_name, uid, getgid(), 1212 ALLOC_MODE)) != 0) { 1213 (void) _newdac(file_name, ALLOC_UID, ALLOC_GID, 1214 ALLOC_ERR_MODE); 1215 goto out; 1216 } 1217 } 1218 error = 0; 1219 out: 1220 if (zpath.count) { 1221 for (i = 0; i < zpath.count; i++) 1222 free(zpath.path[i]); 1223 free(zpath.path); 1224 } 1225 freedmapent(dm); 1226 return (error); 1227 } 1228 1229 void 1230 _store_devnames(int *count, struct devnames *dnms, char *zonename, 1231 devalloc_t *da, int flag) 1232 { 1233 int i; 1234 1235 dnms->dnames = (char **)realloc(dnms->dnames, 1236 (*count + 1) * sizeof (char *)); 1237 if (da) { 1238 dnms->dnames[*count] = strdup(da->da_devname); 1239 (*count)++; 1240 } else { 1241 dnms->dnames[*count] = NULL; 1242 if (flag == DA_ADD_ZONE) 1243 (void) update_device(dnms->dnames, zonename, 1244 DA_ADD_ZONE); 1245 else if (flag == DA_REMOVE_ZONE) 1246 (void) update_device(dnms->dnames, NULL, 1247 DA_REMOVE_ZONE); 1248 for (i = 0; i < *count; i++) 1249 free(dnms->dnames[i]); 1250 free(dnms->dnames); 1251 } 1252 } 1253 1254 int 1255 allocate(int optflag, uid_t uid, char *device, char *zonename) 1256 { 1257 int count = 0; 1258 int error = 0; 1259 devalloc_t *da; 1260 struct devnames dnms; 1261 1262 if (optflag & (FORCE | USERID | USERNAME)) { 1263 if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid())) 1264 return (UAUTHERR); 1265 } 1266 dnms.dnames = NULL; 1267 setdaent(); 1268 if (optflag & TYPE) { 1269 /* 1270 * allocate devices of this type 1271 */ 1272 while ((da = getdatype(device)) != NULL) { 1273 if (system_labeled && 1274 da_check_logindevperm(da->da_devname)) { 1275 freedaent(da); 1276 continue; 1277 } 1278 dprintf("trying to allocate %s\n", da->da_devname); 1279 error = _allocate_dev(optflag, uid, da, zonename); 1280 if (system_labeled && (error == 0)) { 1281 /* 1282 * we need to record in device_allocate the 1283 * label (zone name) at which this device is 1284 * being allocated. store this device entry. 1285 */ 1286 _store_devnames(&count, &dnms, zonename, da, 0); 1287 } 1288 freedaent(da); 1289 error = 0; 1290 } 1291 } else { 1292 /* 1293 * allocate this device 1294 */ 1295 if ((da = getdanam(device)) == NULL) { 1296 enddaent(); 1297 return (NODAERR); 1298 } 1299 if (system_labeled && da_check_logindevperm(device)) { 1300 freedaent(da); 1301 return (LOGINDEVPERMERR); 1302 } 1303 dprintf("trying to allocate %s\n", da->da_devname); 1304 error = _allocate_dev(optflag, uid, da, zonename); 1305 /* 1306 * we need to record in device_allocate the label (zone name) 1307 * at which this device is being allocated. store this device 1308 * entry. 1309 */ 1310 if (system_labeled && (error == 0)) 1311 _store_devnames(&count, &dnms, zonename, da, 0); 1312 freedaent(da); 1313 } 1314 enddaent(); 1315 /* 1316 * add to device_allocate labels (zone names) for the devices we 1317 * allocated. 1318 */ 1319 if (dnms.dnames) 1320 _store_devnames(&count, &dnms, zonename, NULL, DA_ADD_ZONE); 1321 1322 return (error); 1323 } 1324 1325 /* ARGSUSED */ 1326 int 1327 deallocate(int optflag, uid_t uid, char *device, char *zonename) 1328 { 1329 int count = 0; 1330 int error = 0; 1331 devalloc_t *da; 1332 struct devnames dnms; 1333 1334 if (optflag & (FORCE | FORCE_ALL)) { 1335 if (!_is_authorized(DEVICE_REVOKE_AUTH, getuid())) 1336 return (UAUTHERR); 1337 } 1338 if (optflag & FORCE_ALL) 1339 optflag |= FORCE; 1340 dnms.dnames = NULL; 1341 setdaent(); 1342 if (optflag & FORCE_ALL) { 1343 /* 1344 * deallocate all devices 1345 */ 1346 while ((da = getdaent()) != NULL) { 1347 if (system_labeled && 1348 da_check_logindevperm(da->da_devname)) { 1349 freedaent(da); 1350 continue; 1351 } 1352 dprintf("trying to deallocate %s\n", da->da_devname); 1353 error = _deallocate_dev(optflag, da, NULL, uid, 1354 zonename); 1355 if (system_labeled && (error == 0)) { 1356 /* 1357 * we need to remove this device's allocation 1358 * label (zone name) from device_allocate. 1359 * store this device name. 1360 */ 1361 _store_devnames(&count, &dnms, zonename, da, 0); 1362 } 1363 freedaent(da); 1364 error = 0; 1365 } 1366 } else if (system_labeled && optflag & TYPE) { 1367 /* 1368 * deallocate all devices of this type 1369 */ 1370 while ((da = getdatype(device)) != NULL) { 1371 if (da_check_logindevperm(da->da_devname)) { 1372 freedaent(da); 1373 continue; 1374 } 1375 dprintf("trying to deallocate %s\n", da->da_devname); 1376 error = _deallocate_dev(optflag, da, NULL, uid, 1377 zonename); 1378 if (error == 0) { 1379 /* 1380 * we need to remove this device's allocation 1381 * label (zone name) from device_allocate. 1382 * store this device name. 1383 */ 1384 _store_devnames(&count, &dnms, zonename, da, 0); 1385 } 1386 freedaent(da); 1387 error = 0; 1388 } 1389 } else if (!(optflag & TYPE)) { 1390 /* 1391 * deallocate this device 1392 */ 1393 if ((da = getdanam(device)) == NULL) { 1394 enddaent(); 1395 return (NODAERR); 1396 } 1397 if (system_labeled && da_check_logindevperm(da->da_devname)) { 1398 freedaent(da); 1399 return (LOGINDEVPERMERR); 1400 } 1401 dprintf("trying to deallocate %s\n", da->da_devname); 1402 error = _deallocate_dev(optflag, da, NULL, uid, zonename); 1403 if (system_labeled && (error == 0)) { 1404 /* 1405 * we need to remove this device's allocation label 1406 * (zone name) from device_allocate. store this 1407 * device name. 1408 */ 1409 _store_devnames(&count, &dnms, zonename, da, 0); 1410 } 1411 freedaent(da); 1412 } 1413 enddaent(); 1414 /* 1415 * remove from device_allocate labels (zone names) for the devices we 1416 * deallocated. 1417 */ 1418 if (dnms.dnames) 1419 _store_devnames(&count, &dnms, zonename, NULL, DA_REMOVE_ZONE); 1420 1421 return (error); 1422 } 1423 1424 static int 1425 _dev_file_name(struct state_file *sfp, devmap_t *dm) 1426 { 1427 sfp->sf_flags = 0; 1428 /* if devlist is generated, never leave device in error state */ 1429 if (dm->dmap_devlist[0] == '`') 1430 sfp->sf_flags |= SFF_NO_ERROR; 1431 if (dm->dmap_devarray == NULL || 1432 dm->dmap_devarray[0] == NULL) 1433 return (NODMAPERR); 1434 (void) strncpy(sfp->sf_path, dm->dmap_devarray[0], 1435 sizeof (sfp->sf_path)); 1436 sfp->sf_path[sizeof (sfp->sf_path) - 1] = '\0'; 1437 if (sfp->sf_path[0] == '\0') { 1438 dprintf("dev_file_name: no device list for %s\n", 1439 dm->dmap_devname); 1440 return (NODMAPERR); 1441 } 1442 1443 return (0); 1444 } 1445 1446 /* 1447 * _check_label - 1448 * checks the device label range against zone label, which is also 1449 * user's current label. 1450 * returns 0 if in range, -1 for all other conditions. 1451 * 1452 */ 1453 1454 static int 1455 _check_label(devalloc_t *da, char *zonename, uid_t uid, int flag) 1456 { 1457 int err; 1458 int in_range = 0; 1459 char *alloczone, *lstr; 1460 char pw_buf[NSS_BUFLEN_PASSWD]; 1461 blrange_t *range; 1462 m_label_t *zlabel; 1463 struct passwd pw_ent; 1464 1465 if ((da == NULL) || (zonename == NULL)) 1466 return (-1); 1467 1468 if ((zlabel = getzonelabelbyname(zonename)) == NULL) { 1469 dprintf("unable to get label for %s zone\n", zonename); 1470 return (-1); 1471 } 1472 if (flag == CHECK_DRANGE) { 1473 blrange_t drange; 1474 1475 drange.lower_bound = blabel_alloc(); 1476 lstr = kva_match(da->da_devopts, DAOPT_MINLABEL); 1477 if (lstr == NULL) { 1478 bsllow(drange.lower_bound); 1479 } else if (stobsl(lstr, drange.lower_bound, NO_CORRECTION, 1480 &err) == 0) { 1481 dprintf("bad min_label for device %s\n", 1482 da->da_devname); 1483 free(zlabel); 1484 blabel_free(drange.lower_bound); 1485 return (-1); 1486 } 1487 drange.upper_bound = blabel_alloc(); 1488 lstr = kva_match(da->da_devopts, DAOPT_MAXLABEL); 1489 if (lstr == NULL) { 1490 bslhigh(drange.upper_bound); 1491 } else if (stobsl(lstr, drange.upper_bound, NO_CORRECTION, 1492 &err) == 0) { 1493 dprintf("bad max_label for device %s\n", 1494 da->da_devname); 1495 free(zlabel); 1496 blabel_free(drange.lower_bound); 1497 blabel_free(drange.upper_bound); 1498 return (-1); 1499 } 1500 if (blinrange(zlabel, &drange) == 0) { 1501 char *zlbl = NULL, *min = NULL, *max = NULL; 1502 1503 (void) bsltos(zlabel, &zlbl, 0, 0); 1504 (void) bsltos(drange.lower_bound, &min, 0, 0); 1505 (void) bsltos(drange.upper_bound, &max, 0, 0); 1506 dprintf("%s zone label ", zonename); 1507 dprintf("%s outside device label range: ", zlbl); 1508 dprintf("min - %s, ", min); 1509 dprintf("max - %s\n", max); 1510 free(zlabel); 1511 blabel_free(drange.lower_bound); 1512 blabel_free(drange.upper_bound); 1513 return (-1); 1514 } 1515 } else if (flag == CHECK_URANGE) { 1516 if (getpwuid_r(uid, &pw_ent, pw_buf, sizeof (pw_buf)) == NULL) { 1517 dprintf("Unable to get passwd entry for userid %d\n", 1518 (int)uid); 1519 free(zlabel); 1520 return (-1); 1521 } 1522 if ((range = getuserrange(pw_ent.pw_name)) == NULL) { 1523 dprintf("Unable to get label range for userid %d\n", 1524 (int)uid); 1525 free(zlabel); 1526 return (-1); 1527 } 1528 in_range = blinrange(zlabel, range); 1529 free(zlabel); 1530 blabel_free(range->lower_bound); 1531 blabel_free(range->upper_bound); 1532 free(range); 1533 if (in_range == 0) { 1534 dprintf("%s device label ", da->da_devname); 1535 dprintf("out of user %d label range\n", (int)uid); 1536 return (-1); 1537 } 1538 } else if (flag == CHECK_ZLABEL) { 1539 alloczone = kva_match(da->da_devopts, DAOPT_ZONE); 1540 if (alloczone == NULL) { 1541 free(zlabel); 1542 return (-1); 1543 } 1544 if (strcmp(zonename, alloczone) != 0) { 1545 dprintf("%s zone is different than ", zonename); 1546 dprintf("%s zone to which the device ", alloczone); 1547 dprintf("%s is allocated\n", da->da_devname); 1548 free(zlabel); 1549 return (-1); 1550 } 1551 } 1552 free(zlabel); 1553 1554 return (0); 1555 } 1556 1557 int 1558 create_znode(char *zonename, struct zone_path *zpath, devmap_t *list) 1559 { 1560 int i; 1561 int size; 1562 int len = 0; 1563 int fcount = 0; 1564 char *p, *tmpfile, *zoneroot; 1565 char **file; 1566 char zonepath[MAXPATHLEN]; 1567 struct stat statb; 1568 1569 file = list->dmap_devarray; 1570 if (file == NULL) 1571 return (NODMAPERR); 1572 if ((zoneroot = getzonerootbyname(zonename)) == NULL) { 1573 dprintf("unable to get label for %s zone\n", zonename); 1574 return (1); 1575 } 1576 (void) strcpy(zonepath, zoneroot); 1577 free(zoneroot); 1578 if ((p = strstr(zonepath, "/root")) == NULL) 1579 return (1); 1580 *p = '\0'; 1581 len = strlen(zonepath); 1582 size = sizeof (zonepath); 1583 for (; *file != NULL; file++) { 1584 if (stat(*file, &statb) == -1) { 1585 dprintf("Couldn't stat the file %s\n", *file); 1586 return (1); 1587 } 1588 /* 1589 * First time initialization 1590 */ 1591 tmpfile = strdup(*file); 1592 1593 /* 1594 * Most devices have pathnames starting in /dev 1595 * but SunRay devices do not. In SRRS 3.1 they use /tmp. 1596 * 1597 * If the device pathname is not in /dev then create 1598 * a symbolic link to it and put the device in /dev 1599 */ 1600 if (strncmp(tmpfile, "/dev/", strlen("/dev/")) != 0) { 1601 char *linkdir; 1602 char srclinkdir[MAXPATHLEN]; 1603 char dstlinkdir[MAXPATHLEN]; 1604 1605 linkdir = strchr(tmpfile + 1, '/'); 1606 p = strchr(linkdir + 1, '/'); 1607 *p = '\0'; 1608 (void) strcpy(dstlinkdir, "/dev"); 1609 (void) strncat(dstlinkdir, linkdir, MAXPATHLEN); 1610 (void) snprintf(srclinkdir, MAXPATHLEN, "%s/root%s", 1611 zonepath, tmpfile); 1612 (void) symlink(dstlinkdir, srclinkdir); 1613 *p = '/'; 1614 (void) strncat(dstlinkdir, p, MAXPATHLEN); 1615 free(tmpfile); 1616 tmpfile = strdup(dstlinkdir); 1617 } 1618 if ((p = rindex(tmpfile, '/')) == NULL) { 1619 dprintf("bad path in create_znode for %s\n", 1620 tmpfile); 1621 return (1); 1622 } 1623 *p = '\0'; 1624 (void) strcat(zonepath, tmpfile); 1625 *p = '/'; 1626 if ((mkdirp(zonepath, 0755) != 0) && (errno != EEXIST)) { 1627 dprintf("Unable to create directory %s\n", zonepath); 1628 return (1); 1629 } 1630 zonepath[len] = '\0'; 1631 if (strlcat(zonepath, tmpfile, size) >= size) { 1632 dprintf("Buffer overflow in create_znode for %s\n", 1633 *file); 1634 free(tmpfile); 1635 return (1); 1636 } 1637 free(tmpfile); 1638 fcount++; 1639 if ((zpath->path = (char **)realloc(zpath->path, 1640 (fcount * sizeof (char *)))) == NULL) 1641 return (1); 1642 zpath->path[zpath->count] = strdup(zonepath); 1643 zpath->count = fcount; 1644 if (mknod(zonepath, statb.st_mode, statb.st_rdev) == -1) { 1645 switch (errno) { 1646 case EEXIST: 1647 break; 1648 default: 1649 dprintf("mknod error: %s\n", 1650 strerror(errno)); 1651 for (i = 0; i <= fcount; i++) 1652 free(zpath->path[i]); 1653 free(zpath->path); 1654 return (1); 1655 } 1656 } 1657 zonepath[len] = '\0'; 1658 } 1659 1660 return (0); 1661 } 1662 1663 int 1664 remove_znode(char *zonename, devmap_t *dm) 1665 { 1666 int len = 0; 1667 char *zoneroot; 1668 char **file; 1669 char zonepath[MAXPATHLEN]; 1670 1671 file = dm->dmap_devarray; 1672 if (file == NULL) 1673 return (NODMAPERR); 1674 if ((zoneroot = getzonerootbyname(zonename)) == NULL) { 1675 (void) snprintf(zonepath, MAXPATHLEN, "/zone/%s", zonename); 1676 } else { 1677 char *p; 1678 1679 if ((p = strstr(zoneroot, "/root")) == NULL) 1680 return (1); 1681 *p = '\0'; 1682 (void) strcpy(zonepath, zoneroot); 1683 free(zoneroot); 1684 } 1685 /* 1686 * To support SunRay we will just deal with the 1687 * file in /dev, not the symlinks. 1688 */ 1689 (void) strncat(zonepath, "/dev", MAXPATHLEN); 1690 len = strlen(zonepath); 1691 for (; *file != NULL; file++) { 1692 char *devrelpath; 1693 1694 /* 1695 * remove device node from zone. 1696 * 1697 * SunRay devices don't start with /dev 1698 * so skip over first directory to make 1699 * sure it is /dev. SunRay devices in zones 1700 * will have a symlink into /dev but 1701 * we don't ever delete it. 1702 */ 1703 devrelpath = strchr(*file + 1, '/'); 1704 1705 if (strlcat(zonepath, devrelpath, MAXPATHLEN) >= MAXPATHLEN) { 1706 dprintf("Buffer overflow in remove_znode for %s\n", 1707 *file); 1708 return (1); 1709 } 1710 errno = 0; 1711 if ((unlink(zonepath) == -1) && (errno != ENOENT)) { 1712 perror(zonepath); 1713 return (1); 1714 } 1715 zonepath[len] = '\0'; 1716 } 1717 1718 return (0); 1719 } 1720 1721 int 1722 update_device(char **devnames, char *zonename, int flag) 1723 { 1724 int len, rc; 1725 char *optstr = NULL; 1726 da_args dargs; 1727 devinfo_t devinfo; 1728 1729 dargs.optflag = flag; 1730 dargs.optflag |= DA_UPDATE|DA_ALLOC_ONLY; 1731 dargs.rootdir = NULL; 1732 dargs.devnames = devnames; 1733 devinfo.devname = devinfo.devtype = devinfo.devauths = devinfo.devexec = 1734 devinfo.devlist = NULL; 1735 if (dargs.optflag & DA_ADD_ZONE) { 1736 len = strlen(DAOPT_ZONE) + strlen(zonename) + 3; 1737 if ((optstr = (char *)malloc(len)) == NULL) 1738 return (-1); 1739 (void) snprintf(optstr, len, "%s%s%s", DAOPT_ZONE, KV_ASSIGN, 1740 zonename); 1741 devinfo.devopts = optstr; 1742 } 1743 dargs.devinfo = &devinfo; 1744 1745 rc = da_update_device(&dargs); 1746 1747 if (optstr) 1748 free(optstr); 1749 1750 return (rc); 1751 } 1752