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 /* 30 * zoneadm is a command interpreter for zone administration. It is all in 31 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based. 32 * main() calls parse_and_run() which calls cmd_match(), then invokes the 33 * appropriate command's handler function. The rest of the program is the 34 * handler functions and their helper functions. 35 * 36 * Some of the helper functions are used largely to simplify I18N: reducing 37 * the need for translation notes. This is particularly true of many of 38 * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather 39 * than zerror(gettext("foo failed")) with a translation note indicating 40 * that "foo" need not be translated. 41 */ 42 43 #include <stdio.h> 44 #include <errno.h> 45 #include <unistd.h> 46 #include <signal.h> 47 #include <stdarg.h> 48 #include <ctype.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <wait.h> 52 #include <zone.h> 53 #include <priv.h> 54 #include <locale.h> 55 #include <libintl.h> 56 #include <libzonecfg.h> 57 #include <bsm/adt.h> 58 #include <sys/param.h> 59 #include <sys/types.h> 60 #include <sys/stat.h> 61 #include <sys/statvfs.h> 62 #include <assert.h> 63 #include <sys/sockio.h> 64 #include <sys/mntent.h> 65 #include <limits.h> 66 #include <dirent.h> 67 68 #include <fcntl.h> 69 #include <door.h> 70 #include <macros.h> 71 #include <libgen.h> 72 #include <fnmatch.h> 73 #include <sys/modctl.h> 74 75 #include <pool.h> 76 #include <sys/pool.h> 77 78 #include "zoneadm.h" 79 80 #define MAXARGS 8 81 82 /* Reflects kernel zone entries */ 83 typedef struct zone_entry { 84 zoneid_t zid; 85 char zname[ZONENAME_MAX]; 86 char *zstate_str; 87 zone_state_t zstate_num; 88 char zroot[MAXPATHLEN]; 89 } zone_entry_t; 90 91 static zone_entry_t *zents; 92 static size_t nzents; 93 94 #define LOOPBACK_IF "lo0" 95 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af)) 96 97 struct net_if { 98 char *name; 99 int af; 100 }; 101 102 /* 0755 is the default directory mode. */ 103 #define DEFAULT_DIR_MODE \ 104 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 105 106 struct cmd { 107 uint_t cmd_num; /* command number */ 108 char *cmd_name; /* command name */ 109 char *short_usage; /* short form help */ 110 int (*handler)(int argc, char *argv[]); /* function to call */ 111 112 }; 113 114 #define SHELP_HELP "help" 115 #define SHELP_BOOT "boot [-- boot_arguments]" 116 #define SHELP_HALT "halt" 117 #define SHELP_READY "ready" 118 #define SHELP_REBOOT "reboot [-- boot_arguments]" 119 #define SHELP_LIST "list [-cipv]" 120 #define SHELP_VERIFY "verify" 121 #define SHELP_INSTALL "install [-x nodataset]" 122 #define SHELP_UNINSTALL "uninstall [-F]" 123 #define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename" 124 #define SHELP_MOVE "move zonepath" 125 #define SHELP_DETACH "detach [-n]" 126 #define SHELP_ATTACH "attach [-F] [-n <path>]" 127 128 static int help_func(int argc, char *argv[]); 129 static int ready_func(int argc, char *argv[]); 130 static int boot_func(int argc, char *argv[]); 131 static int halt_func(int argc, char *argv[]); 132 static int reboot_func(int argc, char *argv[]); 133 static int list_func(int argc, char *argv[]); 134 static int verify_func(int argc, char *argv[]); 135 static int install_func(int argc, char *argv[]); 136 static int uninstall_func(int argc, char *argv[]); 137 static int mount_func(int argc, char *argv[]); 138 static int unmount_func(int argc, char *argv[]); 139 static int clone_func(int argc, char *argv[]); 140 static int move_func(int argc, char *argv[]); 141 static int detach_func(int argc, char *argv[]); 142 static int attach_func(int argc, char *argv[]); 143 static int sanity_check(char *zone, int cmd_num, boolean_t running, 144 boolean_t unsafe_when_running); 145 static int cmd_match(char *cmd); 146 static int verify_details(int); 147 148 static struct cmd cmdtab[] = { 149 { CMD_HELP, "help", SHELP_HELP, help_func }, 150 { CMD_BOOT, "boot", SHELP_BOOT, boot_func }, 151 { CMD_HALT, "halt", SHELP_HALT, halt_func }, 152 { CMD_READY, "ready", SHELP_READY, ready_func }, 153 { CMD_REBOOT, "reboot", SHELP_REBOOT, reboot_func }, 154 { CMD_LIST, "list", SHELP_LIST, list_func }, 155 { CMD_VERIFY, "verify", SHELP_VERIFY, verify_func }, 156 { CMD_INSTALL, "install", SHELP_INSTALL, install_func }, 157 { CMD_UNINSTALL, "uninstall", SHELP_UNINSTALL, 158 uninstall_func }, 159 /* mount and unmount are private commands for admin/install */ 160 { CMD_MOUNT, "mount", NULL, mount_func }, 161 { CMD_UNMOUNT, "unmount", NULL, unmount_func }, 162 { CMD_CLONE, "clone", SHELP_CLONE, clone_func }, 163 { CMD_MOVE, "move", SHELP_MOVE, move_func }, 164 { CMD_DETACH, "detach", SHELP_DETACH, detach_func }, 165 { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func } 166 }; 167 168 /* global variables */ 169 170 /* set early in main(), never modified thereafter, used all over the place */ 171 static char *execname; 172 static char *locale; 173 char *target_zone; 174 175 /* used in do_subproc() and signal handler */ 176 static volatile boolean_t child_killed; 177 178 char * 179 cmd_to_str(int cmd_num) 180 { 181 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 182 return (cmdtab[cmd_num].cmd_name); 183 } 184 185 /* This is a separate function because of gettext() wrapping. */ 186 static char * 187 long_help(int cmd_num) 188 { 189 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 190 switch (cmd_num) { 191 case CMD_HELP: 192 return (gettext("Print usage message.")); 193 case CMD_BOOT: 194 return (gettext("Activates (boots) specified zone. See " 195 "zoneadm(1m) for valid boot\n\targuments.")); 196 case CMD_HALT: 197 return (gettext("Halts specified zone, bypassing shutdown " 198 "scripts and removing runtime\n\tresources of the zone.")); 199 case CMD_READY: 200 return (gettext("Prepares a zone for running applications but " 201 "does not start any user\n\tprocesses in the zone.")); 202 case CMD_REBOOT: 203 return (gettext("Restarts the zone (equivalent to a halt / " 204 "boot sequence).\n\tFails if the zone is not active. " 205 "See zoneadm(1m) for valid boot\n\targuments.")); 206 case CMD_LIST: 207 return (gettext("Lists the current zones, or a " 208 "specific zone if indicated. By default,\n\tall " 209 "running zones are listed, though this can be " 210 "expanded to all\n\tinstalled zones with the -i " 211 "option or all configured zones with the\n\t-c " 212 "option. When used with the general -z <zone> " 213 "option, lists only the\n\tspecified zone, but " 214 "lists it regardless of its state, and the -i " 215 "and -c\n\toptions are disallowed. The -v option " 216 "can be used to display verbose\n\tinformation: " 217 "zone name, id, current state, root directory and " 218 "options.\n\tThe -p option can be used to request " 219 "machine-parsable output. The -v\n\tand -p " 220 "options are mutually exclusive. If neither -v " 221 "nor -p is used,\n\tjust the zone name is listed.")); 222 case CMD_VERIFY: 223 return (gettext("Check to make sure the configuration " 224 "can safely be instantiated\n\ton the machine: " 225 "physical network interfaces exist, etc.")); 226 case CMD_INSTALL: 227 return (gettext("Install the configuration on to the system. " 228 "The -x nodataset option\n\tcan be used to prevent the " 229 "creation of a new ZFS file system for the\n\tzone " 230 "(assuming the zonepath is within a ZFS file system).")); 231 case CMD_UNINSTALL: 232 return (gettext("Uninstall the configuration from the system. " 233 "The -F flag can be used\n\tto force the action.")); 234 case CMD_CLONE: 235 return (gettext("Clone the installation of another zone. " 236 "The -m option can be used to\n\tspecify 'copy' which " 237 "forces a copy of the source zone. The -s option\n\t" 238 "can be used to specify the name of a ZFS snapshot " 239 "that was taken from\n\ta previous clone command. The " 240 "snapshot will be used as the source\n\tinstead of " 241 "creating a new ZFS snapshot.")); 242 case CMD_MOVE: 243 return (gettext("Move the zone to a new zonepath.")); 244 case CMD_DETACH: 245 return (gettext("Detach the zone from the system. The zone " 246 "state is changed to\n\t'configured' (but the files under " 247 "the zonepath are untouched).\n\tThe zone can subsequently " 248 "be attached, or can be moved to another\n\tsystem and " 249 "attached there. The -n option can be used to specify\n\t" 250 "'no-execute' mode. When -n is used, the information " 251 "needed to attach\n\tthe zone is sent to standard output " 252 "but the zone is not actually\n\tdetached.")); 253 case CMD_ATTACH: 254 return (gettext("Attach the zone to the system. The zone " 255 "state must be 'configured'\n\tprior to attach; upon " 256 "successful completion, the zone state will be\n\t" 257 "'installed'. The system software on the current " 258 "system must be\n\tcompatible with the software on the " 259 "zone's original system.\n\tSpecify -F to force the attach " 260 "and skip software compatibility tests.\n\tThe -n option " 261 "can be used to specify 'no-execute' mode. When -n is\n\t" 262 "used, the information needed to attach the zone is read " 263 "from the\n\tspecified path and the configuration is only " 264 "validated. The path can\n\tbe '-' to specify standard " 265 "input.")); 266 default: 267 return (""); 268 } 269 /* NOTREACHED */ 270 return (NULL); 271 } 272 273 /* 274 * Called with explicit B_TRUE when help is explicitly requested, B_FALSE for 275 * unexpected errors. 276 */ 277 278 static int 279 usage(boolean_t explicit) 280 { 281 int i; 282 FILE *fd = explicit ? stdout : stderr; 283 284 (void) fprintf(fd, "%s:\t%s help\n", gettext("usage"), execname); 285 (void) fprintf(fd, "\t%s [-z <zone>] list\n", execname); 286 (void) fprintf(fd, "\t%s -z <zone> <%s>\n", execname, 287 gettext("subcommand")); 288 (void) fprintf(fd, "\n%s:\n\n", gettext("Subcommands")); 289 for (i = CMD_MIN; i <= CMD_MAX; i++) { 290 if (cmdtab[i].short_usage == NULL) 291 continue; 292 (void) fprintf(fd, "%s\n", cmdtab[i].short_usage); 293 if (explicit) 294 (void) fprintf(fd, "\t%s\n\n", long_help(i)); 295 } 296 if (!explicit) 297 (void) fputs("\n", fd); 298 return (Z_USAGE); 299 } 300 301 static void 302 sub_usage(char *short_usage, int cmd_num) 303 { 304 (void) fprintf(stderr, "%s:\t%s\n", gettext("usage"), short_usage); 305 (void) fprintf(stderr, "\t%s\n", long_help(cmd_num)); 306 } 307 308 /* 309 * zperror() is like perror(3c) except that this also prints the executable 310 * name at the start of the message, and takes a boolean indicating whether 311 * to call libc'c strerror() or that from libzonecfg. 312 */ 313 314 void 315 zperror(const char *str, boolean_t zonecfg_error) 316 { 317 (void) fprintf(stderr, "%s: %s: %s\n", execname, str, 318 zonecfg_error ? zonecfg_strerror(errno) : strerror(errno)); 319 } 320 321 /* 322 * zperror2() is very similar to zperror() above, except it also prints a 323 * supplied zone name after the executable. 324 * 325 * All current consumers of this function want libzonecfg's strerror() rather 326 * than libc's; if this ever changes, this function can be made more generic 327 * like zperror() above. 328 */ 329 330 void 331 zperror2(const char *zone, const char *str) 332 { 333 (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str, 334 zonecfg_strerror(errno)); 335 } 336 337 /* PRINTFLIKE1 */ 338 void 339 zerror(const char *fmt, ...) 340 { 341 va_list alist; 342 343 va_start(alist, fmt); 344 (void) fprintf(stderr, "%s: ", execname); 345 if (target_zone != NULL) 346 (void) fprintf(stderr, "zone '%s': ", target_zone); 347 (void) vfprintf(stderr, fmt, alist); 348 (void) fprintf(stderr, "\n"); 349 va_end(alist); 350 } 351 352 static void * 353 safe_calloc(size_t nelem, size_t elsize) 354 { 355 void *r = calloc(nelem, elsize); 356 357 if (r == NULL) { 358 zerror(gettext("failed to allocate %lu bytes: %s"), 359 (ulong_t)nelem * elsize, strerror(errno)); 360 exit(Z_ERR); 361 } 362 return (r); 363 } 364 365 static void 366 zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) 367 { 368 static boolean_t firsttime = B_TRUE; 369 370 assert(!(verbose && parsable)); 371 if (firsttime && verbose) { 372 firsttime = B_FALSE; 373 (void) printf("%*s %-16s %-14s %-30s\n", ZONEID_WIDTH, "ID", 374 "NAME", "STATUS", "PATH"); 375 } 376 if (!verbose) { 377 if (!parsable) { 378 (void) printf("%s\n", zent->zname); 379 return; 380 } 381 if (zent->zid == ZONE_ID_UNDEFINED) 382 (void) printf("-"); 383 else 384 (void) printf("%lu", zent->zid); 385 (void) printf(":%s:%s:%s\n", zent->zname, zent->zstate_str, 386 zent->zroot); 387 return; 388 } 389 if (zent->zstate_str != NULL) { 390 if (zent->zid == ZONE_ID_UNDEFINED) 391 (void) printf("%*s", ZONEID_WIDTH, "-"); 392 else 393 (void) printf("%*lu", ZONEID_WIDTH, zent->zid); 394 (void) printf(" %-16s %-14s %-30s\n", zent->zname, 395 zent->zstate_str, zent->zroot); 396 } 397 } 398 399 static int 400 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) 401 { 402 char root[MAXPATHLEN], *cp; 403 int err; 404 405 (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname)); 406 (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot)); 407 zent->zstate_str = "???"; 408 409 zent->zid = zid; 410 411 /* 412 * For labeled zones which query the zone path of lower-level 413 * zones, the path needs to be adjusted to drop the final 414 * "/root" component. This adjusted path is then useful 415 * for reading down any exported directories from the 416 * lower-level zone. 417 */ 418 if (is_system_labeled() && zent->zid != ZONE_ID_UNDEFINED) { 419 if (zone_getattr(zent->zid, ZONE_ATTR_ROOT, zent->zroot, 420 sizeof (zent->zroot)) == -1) { 421 zperror2(zent->zname, 422 gettext("could not get zone path.")); 423 return (Z_ERR); 424 } 425 cp = zent->zroot + strlen(zent->zroot) - 5; 426 if (cp > zent->zroot && strcmp(cp, "/root") == 0) 427 *cp = 0; 428 } else { 429 if ((err = zone_get_zonepath(zent->zname, root, 430 sizeof (root))) != Z_OK) { 431 errno = err; 432 zperror2(zent->zname, 433 gettext("could not get zone path.")); 434 return (Z_ERR); 435 } 436 (void) strlcpy(zent->zroot, root, sizeof (zent->zroot)); 437 } 438 439 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) { 440 errno = err; 441 zperror2(zent->zname, gettext("could not get state")); 442 return (Z_ERR); 443 } 444 zent->zstate_str = zone_state_str(zent->zstate_num); 445 446 return (Z_OK); 447 } 448 449 /* 450 * fetch_zents() calls zone_list(2) to find out how many zones are running 451 * (which is stored in the global nzents), then calls zone_list(2) again 452 * to fetch the list of running zones (stored in the global zents). This 453 * function may be called multiple times, so if zents is already set, we 454 * return immediately to save work. 455 */ 456 457 static int 458 fetch_zents(void) 459 { 460 zoneid_t *zids = NULL; 461 uint_t nzents_saved; 462 int i, retv; 463 FILE *fp; 464 boolean_t inaltroot; 465 zone_entry_t *zentp; 466 467 if (nzents > 0) 468 return (Z_OK); 469 470 if (zone_list(NULL, &nzents) != 0) { 471 zperror(gettext("failed to get zoneid list"), B_FALSE); 472 return (Z_ERR); 473 } 474 475 again: 476 if (nzents == 0) 477 return (Z_OK); 478 479 zids = safe_calloc(nzents, sizeof (zoneid_t)); 480 nzents_saved = nzents; 481 482 if (zone_list(zids, &nzents) != 0) { 483 zperror(gettext("failed to get zone list"), B_FALSE); 484 free(zids); 485 return (Z_ERR); 486 } 487 if (nzents != nzents_saved) { 488 /* list changed, try again */ 489 free(zids); 490 goto again; 491 } 492 493 zents = safe_calloc(nzents, sizeof (zone_entry_t)); 494 495 inaltroot = zonecfg_in_alt_root(); 496 if (inaltroot) 497 fp = zonecfg_open_scratch("", B_FALSE); 498 else 499 fp = NULL; 500 zentp = zents; 501 retv = Z_OK; 502 for (i = 0; i < nzents; i++) { 503 char name[ZONENAME_MAX]; 504 char altname[ZONENAME_MAX]; 505 506 if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) { 507 zperror(gettext("failed to get zone name"), B_FALSE); 508 retv = Z_ERR; 509 continue; 510 } 511 if (zonecfg_is_scratch(name)) { 512 /* Ignore scratch zones by default */ 513 if (!inaltroot) 514 continue; 515 if (fp == NULL || 516 zonecfg_reverse_scratch(fp, name, altname, 517 sizeof (altname), NULL, 0) == -1) { 518 zerror(gettext("could not resolve scratch " 519 "zone %s"), name); 520 retv = Z_ERR; 521 continue; 522 } 523 (void) strcpy(name, altname); 524 } else { 525 /* Ignore non-scratch when in an alternate root */ 526 if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0) 527 continue; 528 } 529 if (lookup_zone_info(name, zids[i], zentp) != Z_OK) { 530 zerror(gettext("failed to get zone data")); 531 retv = Z_ERR; 532 continue; 533 } 534 zentp++; 535 } 536 nzents = zentp - zents; 537 if (fp != NULL) 538 zonecfg_close_scratch(fp); 539 540 free(zids); 541 return (retv); 542 } 543 544 static int 545 zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable) 546 { 547 int i; 548 zone_entry_t zent; 549 FILE *cookie; 550 char *name; 551 552 /* 553 * First get the list of running zones from the kernel and print them. 554 * If that is all we need, then return. 555 */ 556 if ((i = fetch_zents()) != Z_OK) { 557 /* 558 * No need for error messages; fetch_zents() has already taken 559 * care of this. 560 */ 561 return (i); 562 } 563 for (i = 0; i < nzents; i++) 564 zone_print(&zents[i], verbose, parsable); 565 if (min_state >= ZONE_STATE_RUNNING) 566 return (Z_OK); 567 /* 568 * Next, get the full list of zones from the configuration, skipping 569 * any we have already printed. 570 */ 571 cookie = setzoneent(); 572 while ((name = getzoneent(cookie)) != NULL) { 573 for (i = 0; i < nzents; i++) { 574 if (strcmp(zents[i].zname, name) == 0) 575 break; 576 } 577 if (i < nzents) { 578 free(name); 579 continue; 580 } 581 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) { 582 free(name); 583 continue; 584 } 585 free(name); 586 if (zent.zstate_num >= min_state) 587 zone_print(&zent, verbose, parsable); 588 } 589 endzoneent(cookie); 590 return (Z_OK); 591 } 592 593 static zone_entry_t * 594 lookup_running_zone(char *str) 595 { 596 zoneid_t zoneid; 597 char *cp; 598 int i; 599 600 if (fetch_zents() != Z_OK) 601 return (NULL); 602 603 for (i = 0; i < nzents; i++) { 604 if (strcmp(str, zents[i].zname) == 0) 605 return (&zents[i]); 606 } 607 errno = 0; 608 zoneid = strtol(str, &cp, 0); 609 if (zoneid < MIN_ZONEID || zoneid > MAX_ZONEID || 610 errno != 0 || *cp != '\0') 611 return (NULL); 612 for (i = 0; i < nzents; i++) { 613 if (zoneid == zents[i].zid) 614 return (&zents[i]); 615 } 616 return (NULL); 617 } 618 619 /* 620 * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if 621 * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect). 622 */ 623 static boolean_t 624 bad_mode_bit(mode_t mode, mode_t bit, boolean_t on, char *file) 625 { 626 char *str; 627 628 assert(bit == S_IRUSR || bit == S_IWUSR || bit == S_IXUSR || 629 bit == S_IRGRP || bit == S_IWGRP || bit == S_IXGRP || 630 bit == S_IROTH || bit == S_IWOTH || bit == S_IXOTH); 631 /* 632 * TRANSLATION_NOTE 633 * The strings below will be used as part of a larger message, 634 * either: 635 * (file name) must be (owner|group|world) (read|writ|execut)able 636 * or 637 * (file name) must not be (owner|group|world) (read|writ|execut)able 638 */ 639 switch (bit) { 640 case S_IRUSR: 641 str = gettext("owner readable"); 642 break; 643 case S_IWUSR: 644 str = gettext("owner writable"); 645 break; 646 case S_IXUSR: 647 str = gettext("owner executable"); 648 break; 649 case S_IRGRP: 650 str = gettext("group readable"); 651 break; 652 case S_IWGRP: 653 str = gettext("group writable"); 654 break; 655 case S_IXGRP: 656 str = gettext("group executable"); 657 break; 658 case S_IROTH: 659 str = gettext("world readable"); 660 break; 661 case S_IWOTH: 662 str = gettext("world writable"); 663 break; 664 case S_IXOTH: 665 str = gettext("world executable"); 666 break; 667 } 668 if ((mode & bit) == (on ? 0 : bit)) { 669 /* 670 * TRANSLATION_NOTE 671 * The first parameter below is a file name; the second 672 * is one of the "(owner|group|world) (read|writ|execut)able" 673 * strings from above. 674 */ 675 /* 676 * The code below could be simplified but not in a way 677 * that would easily translate to non-English locales. 678 */ 679 if (on) { 680 (void) fprintf(stderr, gettext("%s must be %s.\n"), 681 file, str); 682 } else { 683 (void) fprintf(stderr, gettext("%s must not be %s.\n"), 684 file, str); 685 } 686 return (B_TRUE); 687 } 688 return (B_FALSE); 689 } 690 691 /* 692 * We want to make sure that no zone has its zone path as a child node 693 * (in the directory sense) of any other. We do that by comparing this 694 * zone's path to the path of all other (non-global) zones. The comparison 695 * in each case is simple: add '/' to the end of the path, then do a 696 * strncmp() of the two paths, using the length of the shorter one. 697 */ 698 699 static int 700 crosscheck_zonepaths(char *path) 701 { 702 char rpath[MAXPATHLEN]; /* resolved path */ 703 char path_copy[MAXPATHLEN]; /* copy of original path */ 704 char rpath_copy[MAXPATHLEN]; /* copy of original rpath */ 705 struct zoneent *ze; 706 int res, err; 707 FILE *cookie; 708 709 cookie = setzoneent(); 710 while ((ze = getzoneent_private(cookie)) != NULL) { 711 /* Skip zones which are not installed. */ 712 if (ze->zone_state < ZONE_STATE_INSTALLED) { 713 free(ze); 714 continue; 715 } 716 /* Skip the global zone and the current target zone. */ 717 if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0 || 718 strcmp(ze->zone_name, target_zone) == 0) { 719 free(ze); 720 continue; 721 } 722 if (strlen(ze->zone_path) == 0) { 723 /* old index file without path, fall back */ 724 if ((err = zone_get_zonepath(ze->zone_name, 725 ze->zone_path, sizeof (ze->zone_path))) != Z_OK) { 726 errno = err; 727 zperror2(ze->zone_name, 728 gettext("could not get zone path")); 729 free(ze); 730 continue; 731 } 732 } 733 (void) snprintf(path_copy, sizeof (path_copy), "%s%s", 734 zonecfg_get_root(), ze->zone_path); 735 res = resolvepath(path_copy, rpath, sizeof (rpath)); 736 if (res == -1) { 737 if (errno != ENOENT) { 738 zperror(path_copy, B_FALSE); 739 free(ze); 740 return (Z_ERR); 741 } 742 (void) printf(gettext("WARNING: zone %s is installed, " 743 "but its %s %s does not exist.\n"), ze->zone_name, 744 "zonepath", path_copy); 745 free(ze); 746 continue; 747 } 748 rpath[res] = '\0'; 749 (void) snprintf(path_copy, sizeof (path_copy), "%s/", path); 750 (void) snprintf(rpath_copy, sizeof (rpath_copy), "%s/", rpath); 751 if (strncmp(path_copy, rpath_copy, 752 min(strlen(path_copy), strlen(rpath_copy))) == 0) { 753 /* 754 * TRANSLATION_NOTE 755 * zonepath is a literal that should not be translated. 756 */ 757 (void) fprintf(stderr, gettext("%s zonepath (%s) and " 758 "%s zonepath (%s) overlap.\n"), 759 target_zone, path, ze->zone_name, rpath); 760 free(ze); 761 return (Z_ERR); 762 } 763 free(ze); 764 } 765 endzoneent(cookie); 766 return (Z_OK); 767 } 768 769 static int 770 validate_zonepath(char *path, int cmd_num) 771 { 772 int res; /* result of last library/system call */ 773 boolean_t err = B_FALSE; /* have we run into an error? */ 774 struct stat stbuf; 775 struct statvfs64 vfsbuf; 776 char rpath[MAXPATHLEN]; /* resolved path */ 777 char ppath[MAXPATHLEN]; /* parent path */ 778 char rppath[MAXPATHLEN]; /* resolved parent path */ 779 char rootpath[MAXPATHLEN]; /* root path */ 780 zone_state_t state; 781 782 if (path[0] != '/') { 783 (void) fprintf(stderr, 784 gettext("%s is not an absolute path.\n"), path); 785 return (Z_ERR); 786 } 787 if ((res = resolvepath(path, rpath, sizeof (rpath))) == -1) { 788 if ((errno != ENOENT) || 789 (cmd_num != CMD_VERIFY && cmd_num != CMD_INSTALL && 790 cmd_num != CMD_CLONE && cmd_num != CMD_MOVE)) { 791 zperror(path, B_FALSE); 792 return (Z_ERR); 793 } 794 if (cmd_num == CMD_VERIFY) { 795 /* 796 * TRANSLATION_NOTE 797 * zoneadm is a literal that should not be translated. 798 */ 799 (void) fprintf(stderr, gettext("WARNING: %s does not " 800 "exist, so it could not be verified.\nWhen " 801 "'zoneadm %s' is run, '%s' will try to create\n%s, " 802 "and '%s' will be tried again,\nbut the '%s' may " 803 "fail if:\nthe parent directory of %s is group- or " 804 "other-writable\nor\n%s overlaps with any other " 805 "installed zones.\n"), path, 806 cmd_to_str(CMD_INSTALL), cmd_to_str(CMD_INSTALL), 807 path, cmd_to_str(CMD_VERIFY), 808 cmd_to_str(CMD_VERIFY), path, path); 809 return (Z_OK); 810 } 811 /* 812 * The zonepath is supposed to be mode 700 but its 813 * parent(s) 755. So use 755 on the mkdirp() then 814 * chmod() the zonepath itself to 700. 815 */ 816 if (mkdirp(path, DEFAULT_DIR_MODE) < 0) { 817 zperror(path, B_FALSE); 818 return (Z_ERR); 819 } 820 /* 821 * If the chmod() fails, report the error, but might 822 * as well continue the verify procedure. 823 */ 824 if (chmod(path, S_IRWXU) != 0) 825 zperror(path, B_FALSE); 826 /* 827 * Since the mkdir() succeeded, we should not have to 828 * worry about a subsequent ENOENT, thus this should 829 * only recurse once. 830 */ 831 return (validate_zonepath(path, cmd_num)); 832 } 833 rpath[res] = '\0'; 834 if (strcmp(path, rpath) != 0) { 835 errno = Z_RESOLVED_PATH; 836 zperror(path, B_TRUE); 837 return (Z_ERR); 838 } 839 if ((res = stat(rpath, &stbuf)) != 0) { 840 zperror(rpath, B_FALSE); 841 return (Z_ERR); 842 } 843 if (!S_ISDIR(stbuf.st_mode)) { 844 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 845 rpath); 846 return (Z_ERR); 847 } 848 if ((strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) || 849 (strcmp(stbuf.st_fstype, MNTTYPE_XMEMFS) == 0)) { 850 (void) printf(gettext("WARNING: %s is on a temporary " 851 "file system.\n"), rpath); 852 } 853 if (crosscheck_zonepaths(rpath) != Z_OK) 854 return (Z_ERR); 855 /* 856 * Try to collect and report as many minor errors as possible 857 * before returning, so the user can learn everything that needs 858 * to be fixed up front. 859 */ 860 if (stbuf.st_uid != 0) { 861 (void) fprintf(stderr, gettext("%s is not owned by root.\n"), 862 rpath); 863 err = B_TRUE; 864 } 865 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rpath); 866 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rpath); 867 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rpath); 868 err |= bad_mode_bit(stbuf.st_mode, S_IRGRP, B_FALSE, rpath); 869 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rpath); 870 err |= bad_mode_bit(stbuf.st_mode, S_IXGRP, B_FALSE, rpath); 871 err |= bad_mode_bit(stbuf.st_mode, S_IROTH, B_FALSE, rpath); 872 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rpath); 873 err |= bad_mode_bit(stbuf.st_mode, S_IXOTH, B_FALSE, rpath); 874 875 (void) snprintf(ppath, sizeof (ppath), "%s/..", path); 876 if ((res = resolvepath(ppath, rppath, sizeof (rppath))) == -1) { 877 zperror(ppath, B_FALSE); 878 return (Z_ERR); 879 } 880 rppath[res] = '\0'; 881 if ((res = stat(rppath, &stbuf)) != 0) { 882 zperror(rppath, B_FALSE); 883 return (Z_ERR); 884 } 885 /* theoretically impossible */ 886 if (!S_ISDIR(stbuf.st_mode)) { 887 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 888 rppath); 889 return (Z_ERR); 890 } 891 if (stbuf.st_uid != 0) { 892 (void) fprintf(stderr, gettext("%s is not owned by root.\n"), 893 rppath); 894 err = B_TRUE; 895 } 896 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rppath); 897 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rppath); 898 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rppath); 899 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rppath); 900 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rppath); 901 if (strcmp(rpath, rppath) == 0) { 902 (void) fprintf(stderr, gettext("%s is its own parent.\n"), 903 rppath); 904 err = B_TRUE; 905 } 906 907 if (statvfs64(rpath, &vfsbuf) != 0) { 908 zperror(rpath, B_FALSE); 909 return (Z_ERR); 910 } 911 if (strcmp(vfsbuf.f_basetype, MNTTYPE_NFS) == 0) { 912 /* 913 * TRANSLATION_NOTE 914 * Zonepath and NFS are literals that should not be translated. 915 */ 916 (void) fprintf(stderr, gettext("Zonepath %s is on an NFS " 917 "mounted file system.\n" 918 "\tA local file system must be used.\n"), rpath); 919 return (Z_ERR); 920 } 921 if (vfsbuf.f_flag & ST_NOSUID) { 922 /* 923 * TRANSLATION_NOTE 924 * Zonepath and nosuid are literals that should not be 925 * translated. 926 */ 927 (void) fprintf(stderr, gettext("Zonepath %s is on a nosuid " 928 "file system.\n"), rpath); 929 return (Z_ERR); 930 } 931 932 if ((res = zone_get_state(target_zone, &state)) != Z_OK) { 933 errno = res; 934 zperror2(target_zone, gettext("could not get state")); 935 return (Z_ERR); 936 } 937 /* 938 * The existence of the root path is only bad in the configured state, 939 * as it is *supposed* to be there at the installed and later states. 940 * However, the root path is expected to be there if the zone is 941 * detached. 942 * State/command mismatches are caught earlier in verify_details(). 943 */ 944 if (state == ZONE_STATE_CONFIGURED && cmd_num != CMD_ATTACH) { 945 if (snprintf(rootpath, sizeof (rootpath), "%s/root", rpath) >= 946 sizeof (rootpath)) { 947 /* 948 * TRANSLATION_NOTE 949 * Zonepath is a literal that should not be translated. 950 */ 951 (void) fprintf(stderr, 952 gettext("Zonepath %s is too long.\n"), rpath); 953 return (Z_ERR); 954 } 955 if ((res = stat(rootpath, &stbuf)) == 0) { 956 if (zonecfg_detached(rpath)) 957 (void) fprintf(stderr, 958 gettext("Cannot %s detached " 959 "zone.\nUse attach or remove %s " 960 "directory.\n"), cmd_to_str(cmd_num), 961 rpath); 962 else 963 (void) fprintf(stderr, 964 gettext("Rootpath %s exists; " 965 "remove or move aside prior to %s.\n"), 966 rootpath, cmd_to_str(cmd_num)); 967 return (Z_ERR); 968 } 969 } 970 971 return (err ? Z_ERR : Z_OK); 972 } 973 974 static void 975 release_lock_file(int lockfd) 976 { 977 (void) close(lockfd); 978 } 979 980 static int 981 grab_lock_file(const char *zone_name, int *lockfd) 982 { 983 char pathbuf[PATH_MAX]; 984 struct flock flock; 985 986 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s", zonecfg_get_root(), 987 ZONES_TMPDIR) >= sizeof (pathbuf)) { 988 zerror(gettext("alternate root path is too long")); 989 return (Z_ERR); 990 } 991 if (mkdir(pathbuf, S_IRWXU) < 0 && errno != EEXIST) { 992 zerror(gettext("could not mkdir %s: %s"), pathbuf, 993 strerror(errno)); 994 return (Z_ERR); 995 } 996 (void) chmod(pathbuf, S_IRWXU); 997 998 /* 999 * One of these lock files is created for each zone (when needed). 1000 * The lock files are not cleaned up (except on system reboot), 1001 * but since there is only one per zone, there is no resource 1002 * starvation issue. 1003 */ 1004 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s/%s.zoneadm.lock", 1005 zonecfg_get_root(), ZONES_TMPDIR, zone_name) >= sizeof (pathbuf)) { 1006 zerror(gettext("alternate root path is too long")); 1007 return (Z_ERR); 1008 } 1009 if ((*lockfd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { 1010 zerror(gettext("could not open %s: %s"), pathbuf, 1011 strerror(errno)); 1012 return (Z_ERR); 1013 } 1014 /* 1015 * Lock the file to synchronize with other zoneadmds 1016 */ 1017 flock.l_type = F_WRLCK; 1018 flock.l_whence = SEEK_SET; 1019 flock.l_start = (off_t)0; 1020 flock.l_len = (off_t)0; 1021 if (fcntl(*lockfd, F_SETLKW, &flock) < 0) { 1022 zerror(gettext("unable to lock %s: %s"), pathbuf, 1023 strerror(errno)); 1024 release_lock_file(*lockfd); 1025 return (Z_ERR); 1026 } 1027 return (Z_OK); 1028 } 1029 1030 static boolean_t 1031 get_doorname(const char *zone_name, char *buffer) 1032 { 1033 return (snprintf(buffer, PATH_MAX, "%s" ZONE_DOOR_PATH, 1034 zonecfg_get_root(), zone_name) < PATH_MAX); 1035 } 1036 1037 /* 1038 * system daemons are not audited. For the global zone, this occurs 1039 * "naturally" since init is started with the default audit 1040 * characteristics. Since zoneadmd is a system daemon and it starts 1041 * init for a zone, it is necessary to clear out the audit 1042 * characteristics inherited from whomever started zoneadmd. This is 1043 * indicated by the audit id, which is set from the ruid parameter of 1044 * adt_set_user(), below. 1045 */ 1046 1047 static void 1048 prepare_audit_context() 1049 { 1050 adt_session_data_t *ah; 1051 char *failure = gettext("audit failure: %s"); 1052 1053 if (adt_start_session(&ah, NULL, 0)) { 1054 zerror(failure, strerror(errno)); 1055 return; 1056 } 1057 if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT, 1058 ADT_NO_AUDIT, ADT_NO_AUDIT, NULL, ADT_NEW)) { 1059 zerror(failure, strerror(errno)); 1060 (void) adt_end_session(ah); 1061 return; 1062 } 1063 if (adt_set_proc(ah)) 1064 zerror(failure, strerror(errno)); 1065 1066 (void) adt_end_session(ah); 1067 } 1068 1069 static int 1070 start_zoneadmd(const char *zone_name) 1071 { 1072 char doorpath[PATH_MAX]; 1073 pid_t child_pid; 1074 int error = Z_ERR; 1075 int doorfd, lockfd; 1076 struct door_info info; 1077 1078 if (!get_doorname(zone_name, doorpath)) 1079 return (Z_ERR); 1080 1081 if (grab_lock_file(zone_name, &lockfd) != Z_OK) 1082 return (Z_ERR); 1083 1084 /* 1085 * Now that we have the lock, re-confirm that the daemon is 1086 * *not* up and working fine. If it is still down, we have a green 1087 * light to start it. 1088 */ 1089 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1090 if (errno != ENOENT) { 1091 zperror(doorpath, B_FALSE); 1092 goto out; 1093 } 1094 } else { 1095 if (door_info(doorfd, &info) == 0 && 1096 ((info.di_attributes & DOOR_REVOKED) == 0)) { 1097 error = Z_OK; 1098 (void) close(doorfd); 1099 goto out; 1100 } 1101 (void) close(doorfd); 1102 } 1103 1104 if ((child_pid = fork()) == -1) { 1105 zperror(gettext("could not fork"), B_FALSE); 1106 goto out; 1107 } else if (child_pid == 0) { 1108 const char *argv[6], **ap; 1109 1110 /* child process */ 1111 prepare_audit_context(); 1112 1113 ap = argv; 1114 *ap++ = "zoneadmd"; 1115 *ap++ = "-z"; 1116 *ap++ = zone_name; 1117 if (zonecfg_in_alt_root()) { 1118 *ap++ = "-R"; 1119 *ap++ = zonecfg_get_root(); 1120 } 1121 *ap = NULL; 1122 1123 (void) execv("/usr/lib/zones/zoneadmd", (char * const *)argv); 1124 /* 1125 * TRANSLATION_NOTE 1126 * zoneadmd is a literal that should not be translated. 1127 */ 1128 zperror(gettext("could not exec zoneadmd"), B_FALSE); 1129 _exit(Z_ERR); 1130 } else { 1131 /* parent process */ 1132 pid_t retval; 1133 int pstatus = 0; 1134 1135 do { 1136 retval = waitpid(child_pid, &pstatus, 0); 1137 } while (retval != child_pid); 1138 if (WIFSIGNALED(pstatus) || (WIFEXITED(pstatus) && 1139 WEXITSTATUS(pstatus) != 0)) { 1140 zerror(gettext("could not start %s"), "zoneadmd"); 1141 goto out; 1142 } 1143 } 1144 error = Z_OK; 1145 out: 1146 release_lock_file(lockfd); 1147 return (error); 1148 } 1149 1150 static int 1151 ping_zoneadmd(const char *zone_name) 1152 { 1153 char doorpath[PATH_MAX]; 1154 int doorfd; 1155 struct door_info info; 1156 1157 if (!get_doorname(zone_name, doorpath)) 1158 return (Z_ERR); 1159 1160 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1161 return (Z_ERR); 1162 } 1163 if (door_info(doorfd, &info) == 0 && 1164 ((info.di_attributes & DOOR_REVOKED) == 0)) { 1165 (void) close(doorfd); 1166 return (Z_OK); 1167 } 1168 (void) close(doorfd); 1169 return (Z_ERR); 1170 } 1171 1172 static int 1173 call_zoneadmd(const char *zone_name, zone_cmd_arg_t *arg) 1174 { 1175 char doorpath[PATH_MAX]; 1176 int doorfd, result; 1177 door_arg_t darg; 1178 1179 zoneid_t zoneid; 1180 uint64_t uniqid = 0; 1181 1182 zone_cmd_rval_t *rvalp; 1183 size_t rlen; 1184 char *cp, *errbuf; 1185 1186 rlen = getpagesize(); 1187 if ((rvalp = malloc(rlen)) == NULL) { 1188 zerror(gettext("failed to allocate %lu bytes: %s"), rlen, 1189 strerror(errno)); 1190 return (-1); 1191 } 1192 1193 if ((zoneid = getzoneidbyname(zone_name)) != ZONE_ID_UNDEFINED) { 1194 (void) zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid, 1195 sizeof (uniqid)); 1196 } 1197 arg->uniqid = uniqid; 1198 (void) strlcpy(arg->locale, locale, sizeof (arg->locale)); 1199 if (!get_doorname(zone_name, doorpath)) { 1200 zerror(gettext("alternate root path is too long")); 1201 free(rvalp); 1202 return (-1); 1203 } 1204 1205 /* 1206 * Loop trying to start zoneadmd; if something goes seriously 1207 * wrong we break out and fail. 1208 */ 1209 for (;;) { 1210 if (start_zoneadmd(zone_name) != Z_OK) 1211 break; 1212 1213 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1214 zperror(gettext("failed to open zone door"), B_FALSE); 1215 break; 1216 } 1217 1218 darg.data_ptr = (char *)arg; 1219 darg.data_size = sizeof (*arg); 1220 darg.desc_ptr = NULL; 1221 darg.desc_num = 0; 1222 darg.rbuf = (char *)rvalp; 1223 darg.rsize = rlen; 1224 if (door_call(doorfd, &darg) != 0) { 1225 (void) close(doorfd); 1226 /* 1227 * We'll get EBADF if the door has been revoked. 1228 */ 1229 if (errno != EBADF) { 1230 zperror(gettext("door_call failed"), B_FALSE); 1231 break; 1232 } 1233 continue; /* take another lap */ 1234 } 1235 (void) close(doorfd); 1236 1237 if (darg.data_size == 0) { 1238 /* Door server is going away; kick it again. */ 1239 continue; 1240 } 1241 1242 errbuf = rvalp->errbuf; 1243 while (*errbuf != '\0') { 1244 /* 1245 * Remove any newlines since zerror() 1246 * will append one automatically. 1247 */ 1248 cp = strchr(errbuf, '\n'); 1249 if (cp != NULL) 1250 *cp = '\0'; 1251 zerror("%s", errbuf); 1252 if (cp == NULL) 1253 break; 1254 errbuf = cp + 1; 1255 } 1256 result = rvalp->rval == 0 ? 0 : -1; 1257 free(rvalp); 1258 return (result); 1259 } 1260 1261 free(rvalp); 1262 return (-1); 1263 } 1264 1265 static int 1266 ready_func(int argc, char *argv[]) 1267 { 1268 zone_cmd_arg_t zarg; 1269 int arg; 1270 1271 if (zonecfg_in_alt_root()) { 1272 zerror(gettext("cannot ready zone in alternate root")); 1273 return (Z_ERR); 1274 } 1275 1276 optind = 0; 1277 if ((arg = getopt(argc, argv, "?")) != EOF) { 1278 switch (arg) { 1279 case '?': 1280 sub_usage(SHELP_READY, CMD_READY); 1281 return (optopt == '?' ? Z_OK : Z_USAGE); 1282 default: 1283 sub_usage(SHELP_READY, CMD_READY); 1284 return (Z_USAGE); 1285 } 1286 } 1287 if (argc > optind) { 1288 sub_usage(SHELP_READY, CMD_READY); 1289 return (Z_USAGE); 1290 } 1291 if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE) != Z_OK) 1292 return (Z_ERR); 1293 if (verify_details(CMD_READY) != Z_OK) 1294 return (Z_ERR); 1295 1296 zarg.cmd = Z_READY; 1297 if (call_zoneadmd(target_zone, &zarg) != 0) { 1298 zerror(gettext("call to %s failed"), "zoneadmd"); 1299 return (Z_ERR); 1300 } 1301 return (Z_OK); 1302 } 1303 1304 static int 1305 boot_func(int argc, char *argv[]) 1306 { 1307 zone_cmd_arg_t zarg; 1308 int arg; 1309 1310 if (zonecfg_in_alt_root()) { 1311 zerror(gettext("cannot boot zone in alternate root")); 1312 return (Z_ERR); 1313 } 1314 1315 zarg.bootbuf[0] = '\0'; 1316 1317 /* 1318 * The following getopt processes arguments to zone boot; that 1319 * is to say, the [here] portion of the argument string: 1320 * 1321 * zoneadm -z myzone boot [here] -- -v -m verbose 1322 * 1323 * Where [here] can either be nothing, -? (in which case we bail 1324 * and print usage), or -s. Support for -s is vestigal and 1325 * obsolete, but is retained because it was a documented interface 1326 * and there are known consumers including admin/install; the 1327 * proper way to specify boot arguments like -s is: 1328 * 1329 * zoneadm -z myzone boot -- -s -v -m verbose. 1330 */ 1331 optind = 0; 1332 if ((arg = getopt(argc, argv, "?s")) != EOF) { 1333 switch (arg) { 1334 case '?': 1335 sub_usage(SHELP_BOOT, CMD_BOOT); 1336 return (optopt == '?' ? Z_OK : Z_USAGE); 1337 case 's': 1338 (void) strlcpy(zarg.bootbuf, "-s", 1339 sizeof (zarg.bootbuf)); 1340 break; 1341 default: 1342 sub_usage(SHELP_BOOT, CMD_BOOT); 1343 return (Z_USAGE); 1344 } 1345 } 1346 1347 for (; optind < argc; optind++) { 1348 if (strlcat(zarg.bootbuf, argv[optind], 1349 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) { 1350 zerror(gettext("Boot argument list too long")); 1351 return (Z_ERR); 1352 } 1353 if (optind < argc - 1) 1354 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >= 1355 sizeof (zarg.bootbuf)) { 1356 zerror(gettext("Boot argument list too long")); 1357 return (Z_ERR); 1358 } 1359 } 1360 1361 if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE) != Z_OK) 1362 return (Z_ERR); 1363 if (verify_details(CMD_BOOT) != Z_OK) 1364 return (Z_ERR); 1365 zarg.cmd = Z_BOOT; 1366 if (call_zoneadmd(target_zone, &zarg) != 0) { 1367 zerror(gettext("call to %s failed"), "zoneadmd"); 1368 return (Z_ERR); 1369 } 1370 return (Z_OK); 1371 } 1372 1373 static void 1374 fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr) 1375 { 1376 ssize_t result; 1377 1378 zeptr->zid = zid; 1379 /* 1380 * Since we're looking up our own (non-global) zone name, 1381 * we can be assured that it will succeed. 1382 */ 1383 result = getzonenamebyid(zid, zeptr->zname, sizeof (zeptr->zname)); 1384 assert(result >= 0); 1385 if (!is_system_labeled()) { 1386 (void) strlcpy(zeptr->zroot, "/", sizeof (zeptr->zroot)); 1387 } else { 1388 (void) zone_getattr(zid, ZONE_ATTR_ROOT, zeptr->zroot, 1389 sizeof (zeptr->zroot)); 1390 } 1391 zeptr->zstate_str = "running"; 1392 } 1393 1394 static int 1395 list_func(int argc, char *argv[]) 1396 { 1397 zone_entry_t *zentp, zent; 1398 int arg, retv; 1399 boolean_t output = B_FALSE, verbose = B_FALSE, parsable = B_FALSE; 1400 zone_state_t min_state = ZONE_STATE_RUNNING; 1401 zoneid_t zone_id = getzoneid(); 1402 1403 if (target_zone == NULL) { 1404 /* all zones: default view to running but allow override */ 1405 optind = 0; 1406 while ((arg = getopt(argc, argv, "?cipv")) != EOF) { 1407 switch (arg) { 1408 case '?': 1409 sub_usage(SHELP_LIST, CMD_LIST); 1410 return (optopt == '?' ? Z_OK : Z_USAGE); 1411 /* 1412 * The 'i' and 'c' options are not mutually 1413 * exclusive so if 'c' is given, then min_state 1414 * is set to 0 (ZONE_STATE_CONFIGURED) which is 1415 * the lowest possible state. If 'i' is given, 1416 * then min_state is set to be the lowest state 1417 * so far. 1418 */ 1419 case 'c': 1420 min_state = ZONE_STATE_CONFIGURED; 1421 break; 1422 case 'i': 1423 min_state = min(ZONE_STATE_INSTALLED, 1424 min_state); 1425 1426 break; 1427 case 'p': 1428 parsable = B_TRUE; 1429 break; 1430 case 'v': 1431 verbose = B_TRUE; 1432 break; 1433 default: 1434 sub_usage(SHELP_LIST, CMD_LIST); 1435 return (Z_USAGE); 1436 } 1437 } 1438 if (parsable && verbose) { 1439 zerror(gettext("%s -p and -v are mutually exclusive."), 1440 cmd_to_str(CMD_LIST)); 1441 return (Z_ERR); 1442 } 1443 if (zone_id == GLOBAL_ZONEID || is_system_labeled()) { 1444 retv = zone_print_list(min_state, verbose, parsable); 1445 } else { 1446 retv = Z_OK; 1447 fake_up_local_zone(zone_id, &zent); 1448 zone_print(&zent, verbose, parsable); 1449 } 1450 return (retv); 1451 } 1452 1453 /* 1454 * Specific target zone: disallow -i/-c suboptions. 1455 */ 1456 optind = 0; 1457 while ((arg = getopt(argc, argv, "?pv")) != EOF) { 1458 switch (arg) { 1459 case '?': 1460 sub_usage(SHELP_LIST, CMD_LIST); 1461 return (optopt == '?' ? Z_OK : Z_USAGE); 1462 case 'p': 1463 parsable = B_TRUE; 1464 break; 1465 case 'v': 1466 verbose = B_TRUE; 1467 break; 1468 default: 1469 sub_usage(SHELP_LIST, CMD_LIST); 1470 return (Z_USAGE); 1471 } 1472 } 1473 if (parsable && verbose) { 1474 zerror(gettext("%s -p and -v are mutually exclusive."), 1475 cmd_to_str(CMD_LIST)); 1476 return (Z_ERR); 1477 } 1478 if (argc > optind) { 1479 sub_usage(SHELP_LIST, CMD_LIST); 1480 return (Z_USAGE); 1481 } 1482 if (zone_id != GLOBAL_ZONEID) { 1483 fake_up_local_zone(zone_id, &zent); 1484 /* 1485 * main() will issue a Z_NO_ZONE error if it cannot get an 1486 * id for target_zone, which in a non-global zone should 1487 * happen for any zone name except `zonename`. Thus we 1488 * assert() that here but don't otherwise check. 1489 */ 1490 assert(strcmp(zent.zname, target_zone) == 0); 1491 zone_print(&zent, verbose, parsable); 1492 output = B_TRUE; 1493 } else if ((zentp = lookup_running_zone(target_zone)) != NULL) { 1494 zone_print(zentp, verbose, parsable); 1495 output = B_TRUE; 1496 } else if (lookup_zone_info(target_zone, ZONE_ID_UNDEFINED, 1497 &zent) == Z_OK) { 1498 zone_print(&zent, verbose, parsable); 1499 output = B_TRUE; 1500 } 1501 return (output ? Z_OK : Z_ERR); 1502 } 1503 1504 static void 1505 sigterm(int sig) 1506 { 1507 /* 1508 * Ignore SIG{INT,TERM}, so we don't end up in an infinite loop, 1509 * then propagate the signal to our process group. 1510 */ 1511 (void) sigset(SIGINT, SIG_IGN); 1512 (void) sigset(SIGTERM, SIG_IGN); 1513 (void) kill(0, sig); 1514 child_killed = B_TRUE; 1515 } 1516 1517 static int 1518 do_subproc(char *cmdbuf) 1519 { 1520 char inbuf[1024]; /* arbitrary large amount */ 1521 FILE *file; 1522 1523 child_killed = B_FALSE; 1524 /* 1525 * We use popen(3c) to launch child processes for [un]install; 1526 * this library call does not return a PID, so we have to kill 1527 * the whole process group. To avoid killing our parent, we 1528 * become a process group leader here. But doing so can wreak 1529 * havoc with reading from stdin when launched by a non-job-control 1530 * shell, so we close stdin and reopen it as /dev/null first. 1531 */ 1532 (void) close(STDIN_FILENO); 1533 (void) open("/dev/null", O_RDONLY); 1534 (void) setpgid(0, 0); 1535 (void) sigset(SIGINT, sigterm); 1536 (void) sigset(SIGTERM, sigterm); 1537 file = popen(cmdbuf, "r"); 1538 for (;;) { 1539 if (child_killed || fgets(inbuf, sizeof (inbuf), file) == NULL) 1540 break; 1541 (void) fputs(inbuf, stdout); 1542 } 1543 (void) sigset(SIGINT, SIG_DFL); 1544 (void) sigset(SIGTERM, SIG_DFL); 1545 return (pclose(file)); 1546 } 1547 1548 static int 1549 subproc_status(const char *cmd, int status) 1550 { 1551 if (WIFEXITED(status)) { 1552 int exit_code = WEXITSTATUS(status); 1553 1554 if (exit_code == 0) 1555 return (Z_OK); 1556 zerror(gettext("'%s' failed with exit code %d."), cmd, 1557 exit_code); 1558 } else if (WIFSIGNALED(status)) { 1559 int signal = WTERMSIG(status); 1560 char sigstr[SIG2STR_MAX]; 1561 1562 if (sig2str(signal, sigstr) == 0) { 1563 zerror(gettext("'%s' terminated by signal SIG%s."), cmd, 1564 sigstr); 1565 } else { 1566 zerror(gettext("'%s' terminated by an unknown signal."), 1567 cmd); 1568 } 1569 } else { 1570 zerror(gettext("'%s' failed for unknown reasons."), cmd); 1571 } 1572 return (Z_ERR); 1573 } 1574 1575 /* 1576 * Various sanity checks; make sure: 1577 * 1. We're in the global zone. 1578 * 2. The calling user has sufficient privilege. 1579 * 3. The target zone is neither the global zone nor anything starting with 1580 * "SUNW". 1581 * 4a. If we're looking for a 'not running' (i.e., configured or installed) 1582 * zone, the name service knows about it. 1583 * 4b. For some operations which expect a zone not to be running, that it is 1584 * not already running (or ready). 1585 */ 1586 static int 1587 sanity_check(char *zone, int cmd_num, boolean_t running, 1588 boolean_t unsafe_when_running) 1589 { 1590 zone_entry_t *zent; 1591 priv_set_t *privset; 1592 zone_state_t state; 1593 char kernzone[ZONENAME_MAX]; 1594 FILE *fp; 1595 1596 if (getzoneid() != GLOBAL_ZONEID) { 1597 switch (cmd_num) { 1598 case CMD_HALT: 1599 zerror(gettext("use %s to %s this zone."), "halt(1M)", 1600 cmd_to_str(cmd_num)); 1601 break; 1602 case CMD_REBOOT: 1603 zerror(gettext("use %s to %s this zone."), 1604 "reboot(1M)", cmd_to_str(cmd_num)); 1605 break; 1606 default: 1607 zerror(gettext("must be in the global zone to %s a " 1608 "zone."), cmd_to_str(cmd_num)); 1609 break; 1610 } 1611 return (Z_ERR); 1612 } 1613 1614 if ((privset = priv_allocset()) == NULL) { 1615 zerror(gettext("%s failed"), "priv_allocset"); 1616 return (Z_ERR); 1617 } 1618 1619 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1620 zerror(gettext("%s failed"), "getppriv"); 1621 priv_freeset(privset); 1622 return (Z_ERR); 1623 } 1624 1625 if (priv_isfullset(privset) == B_FALSE) { 1626 zerror(gettext("only a privileged user may %s a zone."), 1627 cmd_to_str(cmd_num)); 1628 priv_freeset(privset); 1629 return (Z_ERR); 1630 } 1631 priv_freeset(privset); 1632 1633 if (zone == NULL) { 1634 zerror(gettext("no zone specified")); 1635 return (Z_ERR); 1636 } 1637 1638 if (strcmp(zone, GLOBAL_ZONENAME) == 0) { 1639 zerror(gettext("%s operation is invalid for the global zone."), 1640 cmd_to_str(cmd_num)); 1641 return (Z_ERR); 1642 } 1643 1644 if (strncmp(zone, "SUNW", 4) == 0) { 1645 zerror(gettext("%s operation is invalid for zones starting " 1646 "with SUNW."), cmd_to_str(cmd_num)); 1647 return (Z_ERR); 1648 } 1649 1650 if (!zonecfg_in_alt_root()) { 1651 zent = lookup_running_zone(zone); 1652 } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) { 1653 zent = NULL; 1654 } else { 1655 if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), 1656 kernzone, sizeof (kernzone)) == 0) 1657 zent = lookup_running_zone(kernzone); 1658 else 1659 zent = NULL; 1660 zonecfg_close_scratch(fp); 1661 } 1662 1663 /* 1664 * Look up from the kernel for 'running' zones. 1665 */ 1666 if (running) { 1667 if (zent == NULL) { 1668 zerror(gettext("not running")); 1669 return (Z_ERR); 1670 } 1671 } else { 1672 int err; 1673 1674 if (unsafe_when_running && zent != NULL) { 1675 /* check whether the zone is ready or running */ 1676 if ((err = zone_get_state(zent->zname, 1677 &zent->zstate_num)) != Z_OK) { 1678 errno = err; 1679 zperror2(zent->zname, 1680 gettext("could not get state")); 1681 /* can't tell, so hedge */ 1682 zent->zstate_str = "ready/running"; 1683 } else { 1684 zent->zstate_str = 1685 zone_state_str(zent->zstate_num); 1686 } 1687 zerror(gettext("%s operation is invalid for %s zones."), 1688 cmd_to_str(cmd_num), zent->zstate_str); 1689 return (Z_ERR); 1690 } 1691 if ((err = zone_get_state(zone, &state)) != Z_OK) { 1692 errno = err; 1693 zperror2(zone, gettext("could not get state")); 1694 return (Z_ERR); 1695 } 1696 switch (cmd_num) { 1697 case CMD_UNINSTALL: 1698 if (state == ZONE_STATE_CONFIGURED) { 1699 zerror(gettext("is already in state '%s'."), 1700 zone_state_str(ZONE_STATE_CONFIGURED)); 1701 return (Z_ERR); 1702 } 1703 break; 1704 case CMD_ATTACH: 1705 case CMD_CLONE: 1706 case CMD_INSTALL: 1707 if (state == ZONE_STATE_INSTALLED) { 1708 zerror(gettext("is already %s."), 1709 zone_state_str(ZONE_STATE_INSTALLED)); 1710 return (Z_ERR); 1711 } else if (state == ZONE_STATE_INCOMPLETE) { 1712 zerror(gettext("zone is %s; %s required."), 1713 zone_state_str(ZONE_STATE_INCOMPLETE), 1714 cmd_to_str(CMD_UNINSTALL)); 1715 return (Z_ERR); 1716 } 1717 break; 1718 case CMD_DETACH: 1719 case CMD_MOVE: 1720 case CMD_READY: 1721 case CMD_BOOT: 1722 case CMD_MOUNT: 1723 if (state < ZONE_STATE_INSTALLED) { 1724 zerror(gettext("must be %s before %s."), 1725 zone_state_str(ZONE_STATE_INSTALLED), 1726 cmd_to_str(cmd_num)); 1727 return (Z_ERR); 1728 } 1729 break; 1730 case CMD_VERIFY: 1731 if (state == ZONE_STATE_INCOMPLETE) { 1732 zerror(gettext("zone is %s; %s required."), 1733 zone_state_str(ZONE_STATE_INCOMPLETE), 1734 cmd_to_str(CMD_UNINSTALL)); 1735 return (Z_ERR); 1736 } 1737 break; 1738 case CMD_UNMOUNT: 1739 if (state != ZONE_STATE_MOUNTED) { 1740 zerror(gettext("must be %s before %s."), 1741 zone_state_str(ZONE_STATE_MOUNTED), 1742 cmd_to_str(cmd_num)); 1743 return (Z_ERR); 1744 } 1745 break; 1746 } 1747 } 1748 return (Z_OK); 1749 } 1750 1751 static int 1752 halt_func(int argc, char *argv[]) 1753 { 1754 zone_cmd_arg_t zarg; 1755 int arg; 1756 1757 if (zonecfg_in_alt_root()) { 1758 zerror(gettext("cannot halt zone in alternate root")); 1759 return (Z_ERR); 1760 } 1761 1762 optind = 0; 1763 if ((arg = getopt(argc, argv, "?")) != EOF) { 1764 switch (arg) { 1765 case '?': 1766 sub_usage(SHELP_HALT, CMD_HALT); 1767 return (optopt == '?' ? Z_OK : Z_USAGE); 1768 default: 1769 sub_usage(SHELP_HALT, CMD_HALT); 1770 return (Z_USAGE); 1771 } 1772 } 1773 if (argc > optind) { 1774 sub_usage(SHELP_HALT, CMD_HALT); 1775 return (Z_USAGE); 1776 } 1777 /* 1778 * zoneadmd should be the one to decide whether or not to proceed, 1779 * so even though it seems that the fourth parameter below should 1780 * perhaps be B_TRUE, it really shouldn't be. 1781 */ 1782 if (sanity_check(target_zone, CMD_HALT, B_FALSE, B_FALSE) != Z_OK) 1783 return (Z_ERR); 1784 1785 zarg.cmd = Z_HALT; 1786 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR); 1787 } 1788 1789 static int 1790 reboot_func(int argc, char *argv[]) 1791 { 1792 zone_cmd_arg_t zarg; 1793 int arg; 1794 1795 if (zonecfg_in_alt_root()) { 1796 zerror(gettext("cannot reboot zone in alternate root")); 1797 return (Z_ERR); 1798 } 1799 1800 optind = 0; 1801 if ((arg = getopt(argc, argv, "?")) != EOF) { 1802 switch (arg) { 1803 case '?': 1804 sub_usage(SHELP_REBOOT, CMD_REBOOT); 1805 return (optopt == '?' ? Z_OK : Z_USAGE); 1806 default: 1807 sub_usage(SHELP_REBOOT, CMD_REBOOT); 1808 return (Z_USAGE); 1809 } 1810 } 1811 1812 zarg.bootbuf[0] = '\0'; 1813 for (; optind < argc; optind++) { 1814 if (strlcat(zarg.bootbuf, argv[optind], 1815 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) { 1816 zerror(gettext("Boot argument list too long")); 1817 return (Z_ERR); 1818 } 1819 if (optind < argc - 1) 1820 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >= 1821 sizeof (zarg.bootbuf)) { 1822 zerror(gettext("Boot argument list too long")); 1823 return (Z_ERR); 1824 } 1825 } 1826 1827 1828 /* 1829 * zoneadmd should be the one to decide whether or not to proceed, 1830 * so even though it seems that the fourth parameter below should 1831 * perhaps be B_TRUE, it really shouldn't be. 1832 */ 1833 if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE) != Z_OK) 1834 return (Z_ERR); 1835 if (verify_details(CMD_REBOOT) != Z_OK) 1836 return (Z_ERR); 1837 1838 zarg.cmd = Z_REBOOT; 1839 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR); 1840 } 1841 1842 static int 1843 verify_rctls(zone_dochandle_t handle) 1844 { 1845 struct zone_rctltab rctltab; 1846 size_t rbs = rctlblk_size(); 1847 rctlblk_t *rctlblk; 1848 int error = Z_INVAL; 1849 1850 if ((rctlblk = malloc(rbs)) == NULL) { 1851 zerror(gettext("failed to allocate %lu bytes: %s"), rbs, 1852 strerror(errno)); 1853 return (Z_NOMEM); 1854 } 1855 1856 if (zonecfg_setrctlent(handle) != Z_OK) { 1857 zerror(gettext("zonecfg_setrctlent failed")); 1858 free(rctlblk); 1859 return (error); 1860 } 1861 1862 rctltab.zone_rctl_valptr = NULL; 1863 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { 1864 struct zone_rctlvaltab *rctlval; 1865 const char *name = rctltab.zone_rctl_name; 1866 1867 if (!zonecfg_is_rctl(name)) { 1868 zerror(gettext("WARNING: Ignoring unrecognized rctl " 1869 "'%s'."), name); 1870 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 1871 rctltab.zone_rctl_valptr = NULL; 1872 continue; 1873 } 1874 1875 for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL; 1876 rctlval = rctlval->zone_rctlval_next) { 1877 if (zonecfg_construct_rctlblk(rctlval, rctlblk) 1878 != Z_OK) { 1879 zerror(gettext("invalid rctl value: " 1880 "(priv=%s,limit=%s,action%s)"), 1881 rctlval->zone_rctlval_priv, 1882 rctlval->zone_rctlval_limit, 1883 rctlval->zone_rctlval_action); 1884 goto out; 1885 } 1886 if (!zonecfg_valid_rctl(name, rctlblk)) { 1887 zerror(gettext("(priv=%s,limit=%s,action=%s) " 1888 "is not a valid value for rctl '%s'"), 1889 rctlval->zone_rctlval_priv, 1890 rctlval->zone_rctlval_limit, 1891 rctlval->zone_rctlval_action, 1892 name); 1893 goto out; 1894 } 1895 } 1896 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 1897 } 1898 rctltab.zone_rctl_valptr = NULL; 1899 error = Z_OK; 1900 out: 1901 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 1902 (void) zonecfg_endrctlent(handle); 1903 free(rctlblk); 1904 return (error); 1905 } 1906 1907 static int 1908 verify_pool(zone_dochandle_t handle) 1909 { 1910 char poolname[MAXPATHLEN]; 1911 pool_conf_t *poolconf; 1912 pool_t *pool; 1913 int status; 1914 int error; 1915 1916 /* 1917 * This ends up being very similar to the check done in zoneadmd. 1918 */ 1919 error = zonecfg_get_pool(handle, poolname, sizeof (poolname)); 1920 if (error == Z_NO_ENTRY || (error == Z_OK && strlen(poolname) == 0)) { 1921 /* 1922 * No pool specified. 1923 */ 1924 return (0); 1925 } 1926 if (error != Z_OK) { 1927 zperror(gettext("Unable to retrieve pool name from " 1928 "configuration"), B_TRUE); 1929 return (error); 1930 } 1931 /* 1932 * Don't do anything if pools aren't enabled. 1933 */ 1934 if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED) { 1935 zerror(gettext("WARNING: pools facility not active; " 1936 "zone will not be bound to pool '%s'."), poolname); 1937 return (Z_OK); 1938 } 1939 /* 1940 * Try to provide a sane error message if the requested pool doesn't 1941 * exist. It isn't clear that pools-related failures should 1942 * necessarily translate to a failure to verify the zone configuration, 1943 * hence they are not considered errors. 1944 */ 1945 if ((poolconf = pool_conf_alloc()) == NULL) { 1946 zerror(gettext("WARNING: pool_conf_alloc failed; " 1947 "using default pool")); 1948 return (Z_OK); 1949 } 1950 if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) != 1951 PO_SUCCESS) { 1952 zerror(gettext("WARNING: pool_conf_open failed; " 1953 "using default pool")); 1954 pool_conf_free(poolconf); 1955 return (Z_OK); 1956 } 1957 pool = pool_get_pool(poolconf, poolname); 1958 (void) pool_conf_close(poolconf); 1959 pool_conf_free(poolconf); 1960 if (pool == NULL) { 1961 zerror(gettext("WARNING: pool '%s' not found. " 1962 "using default pool"), poolname); 1963 } 1964 1965 return (Z_OK); 1966 } 1967 1968 static int 1969 verify_ipd(zone_dochandle_t handle) 1970 { 1971 int return_code = Z_OK; 1972 struct zone_fstab fstab; 1973 struct stat st; 1974 char specdir[MAXPATHLEN]; 1975 1976 if (zonecfg_setipdent(handle) != Z_OK) { 1977 /* 1978 * TRANSLATION_NOTE 1979 * inherit-pkg-dirs is a literal that should not be translated. 1980 */ 1981 (void) fprintf(stderr, gettext("could not verify " 1982 "inherit-pkg-dirs: unable to enumerate mounts\n")); 1983 return (Z_ERR); 1984 } 1985 while (zonecfg_getipdent(handle, &fstab) == Z_OK) { 1986 /* 1987 * Verify fs_dir exists. 1988 */ 1989 (void) snprintf(specdir, sizeof (specdir), "%s%s", 1990 zonecfg_get_root(), fstab.zone_fs_dir); 1991 if (stat(specdir, &st) != 0) { 1992 /* 1993 * TRANSLATION_NOTE 1994 * inherit-pkg-dir is a literal that should not be 1995 * translated. 1996 */ 1997 (void) fprintf(stderr, gettext("could not verify " 1998 "inherit-pkg-dir %s: %s\n"), 1999 fstab.zone_fs_dir, strerror(errno)); 2000 return_code = Z_ERR; 2001 } 2002 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 2003 /* 2004 * TRANSLATION_NOTE 2005 * inherit-pkg-dir and NFS are literals that should 2006 * not be translated. 2007 */ 2008 (void) fprintf(stderr, gettext("cannot verify " 2009 "inherit-pkg-dir %s: NFS mounted file system.\n" 2010 "\tA local file system must be used.\n"), 2011 fstab.zone_fs_dir); 2012 return_code = Z_ERR; 2013 } 2014 } 2015 (void) zonecfg_endipdent(handle); 2016 2017 return (return_code); 2018 } 2019 2020 /* 2021 * Verify that the special device/file system exists and is valid. 2022 */ 2023 static int 2024 verify_fs_special(struct zone_fstab *fstab) 2025 { 2026 struct stat st; 2027 2028 if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) 2029 return (verify_fs_zfs(fstab)); 2030 2031 if (stat(fstab->zone_fs_special, &st) != 0) { 2032 (void) fprintf(stderr, gettext("could not verify fs " 2033 "%s: could not access %s: %s\n"), fstab->zone_fs_dir, 2034 fstab->zone_fs_special, strerror(errno)); 2035 return (Z_ERR); 2036 } 2037 2038 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 2039 /* 2040 * TRANSLATION_NOTE 2041 * fs and NFS are literals that should 2042 * not be translated. 2043 */ 2044 (void) fprintf(stderr, gettext("cannot verify " 2045 "fs %s: NFS mounted file system.\n" 2046 "\tA local file system must be used.\n"), 2047 fstab->zone_fs_special); 2048 return (Z_ERR); 2049 } 2050 2051 return (Z_OK); 2052 } 2053 2054 static int 2055 verify_filesystems(zone_dochandle_t handle) 2056 { 2057 int return_code = Z_OK; 2058 struct zone_fstab fstab; 2059 char cmdbuf[MAXPATHLEN]; 2060 struct stat st; 2061 2062 /* 2063 * No need to verify inherit-pkg-dir fs types, as their type is 2064 * implicitly lofs, which is known. Therefore, the types are only 2065 * verified for regular file systems below. 2066 * 2067 * Since the actual mount point is not known until the dependent mounts 2068 * are performed, we don't attempt any path validation here: that will 2069 * happen later when zoneadmd actually does the mounts. 2070 */ 2071 if (zonecfg_setfsent(handle) != Z_OK) { 2072 (void) fprintf(stderr, gettext("could not verify file systems: " 2073 "unable to enumerate mounts\n")); 2074 return (Z_ERR); 2075 } 2076 while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 2077 if (!zonecfg_valid_fs_type(fstab.zone_fs_type)) { 2078 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2079 "type %s is not allowed.\n"), fstab.zone_fs_dir, 2080 fstab.zone_fs_type); 2081 return_code = Z_ERR; 2082 goto next_fs; 2083 } 2084 /* 2085 * Verify /usr/lib/fs/<fstype>/mount exists. 2086 */ 2087 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/mount", 2088 fstab.zone_fs_type) > sizeof (cmdbuf)) { 2089 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2090 "type %s is too long.\n"), fstab.zone_fs_dir, 2091 fstab.zone_fs_type); 2092 return_code = Z_ERR; 2093 goto next_fs; 2094 } 2095 if (stat(cmdbuf, &st) != 0) { 2096 (void) fprintf(stderr, gettext("could not verify fs " 2097 "%s: could not access %s: %s\n"), fstab.zone_fs_dir, 2098 cmdbuf, strerror(errno)); 2099 return_code = Z_ERR; 2100 goto next_fs; 2101 } 2102 if (!S_ISREG(st.st_mode)) { 2103 (void) fprintf(stderr, gettext("could not verify fs " 2104 "%s: %s is not a regular file\n"), 2105 fstab.zone_fs_dir, cmdbuf); 2106 return_code = Z_ERR; 2107 goto next_fs; 2108 } 2109 /* 2110 * Verify /usr/lib/fs/<fstype>/fsck exists iff zone_fs_raw is 2111 * set. 2112 */ 2113 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck", 2114 fstab.zone_fs_type) > sizeof (cmdbuf)) { 2115 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2116 "type %s is too long.\n"), fstab.zone_fs_dir, 2117 fstab.zone_fs_type); 2118 return_code = Z_ERR; 2119 goto next_fs; 2120 } 2121 if (fstab.zone_fs_raw[0] == '\0' && stat(cmdbuf, &st) == 0) { 2122 (void) fprintf(stderr, gettext("could not verify fs " 2123 "%s: must specify 'raw' device for %s " 2124 "file systems\n"), 2125 fstab.zone_fs_dir, fstab.zone_fs_type); 2126 return_code = Z_ERR; 2127 goto next_fs; 2128 } 2129 if (fstab.zone_fs_raw[0] != '\0' && 2130 (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) { 2131 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2132 "'raw' device specified but " 2133 "no fsck executable exists for %s\n"), 2134 fstab.zone_fs_dir, fstab.zone_fs_type); 2135 return_code = Z_ERR; 2136 goto next_fs; 2137 } 2138 2139 /* Verify fs_special. */ 2140 if ((return_code = verify_fs_special(&fstab)) != Z_OK) 2141 goto next_fs; 2142 2143 /* Verify fs_raw. */ 2144 if (fstab.zone_fs_raw[0] != '\0' && 2145 stat(fstab.zone_fs_raw, &st) != 0) { 2146 /* 2147 * TRANSLATION_NOTE 2148 * fs is a literal that should not be translated. 2149 */ 2150 (void) fprintf(stderr, gettext("could not verify fs " 2151 "%s: could not access %s: %s\n"), fstab.zone_fs_dir, 2152 fstab.zone_fs_raw, strerror(errno)); 2153 return_code = Z_ERR; 2154 goto next_fs; 2155 } 2156 next_fs: 2157 zonecfg_free_fs_option_list(fstab.zone_fs_options); 2158 } 2159 (void) zonecfg_endfsent(handle); 2160 2161 return (return_code); 2162 } 2163 2164 static int 2165 verify_limitpriv(zone_dochandle_t handle) 2166 { 2167 char *privname = NULL; 2168 int err; 2169 priv_set_t *privs; 2170 2171 if ((privs = priv_allocset()) == NULL) { 2172 zperror(gettext("failed to allocate privilege set"), B_FALSE); 2173 return (Z_NOMEM); 2174 } 2175 err = zonecfg_get_privset(handle, privs, &privname); 2176 switch (err) { 2177 case Z_OK: 2178 break; 2179 case Z_PRIV_PROHIBITED: 2180 (void) fprintf(stderr, gettext("privilege \"%s\" is not " 2181 "permitted within the zone's privilege set\n"), privname); 2182 break; 2183 case Z_PRIV_REQUIRED: 2184 (void) fprintf(stderr, gettext("required privilege \"%s\" is " 2185 "missing from the zone's privilege set\n"), privname); 2186 break; 2187 case Z_PRIV_UNKNOWN: 2188 (void) fprintf(stderr, gettext("unknown privilege \"%s\" " 2189 "specified in the zone's privilege set\n"), privname); 2190 break; 2191 default: 2192 zperror( 2193 gettext("failed to determine the zone's privilege set"), 2194 B_TRUE); 2195 break; 2196 } 2197 free(privname); 2198 priv_freeset(privs); 2199 return (err); 2200 } 2201 2202 static void 2203 free_local_netifs(int if_cnt, struct net_if **if_list) 2204 { 2205 int i; 2206 2207 for (i = 0; i < if_cnt; i++) { 2208 free(if_list[i]->name); 2209 free(if_list[i]); 2210 } 2211 free(if_list); 2212 } 2213 2214 /* 2215 * Get a list of the network interfaces, along with their address families, 2216 * that are plumbed in the global zone. See if_tcp(7p) for a description 2217 * of the ioctls used here. 2218 */ 2219 static int 2220 get_local_netifs(int *if_cnt, struct net_if ***if_list) 2221 { 2222 int s; 2223 int i; 2224 int res = Z_OK; 2225 int space_needed; 2226 int cnt = 0; 2227 struct lifnum if_num; 2228 struct lifconf if_conf; 2229 struct lifreq *if_reqp; 2230 char *if_buf; 2231 struct net_if **local_ifs = NULL; 2232 2233 *if_cnt = 0; 2234 *if_list = NULL; 2235 2236 if ((s = socket(SOCKET_AF(AF_INET), SOCK_DGRAM, 0)) < 0) 2237 return (Z_ERR); 2238 2239 /* 2240 * Come back here in the unlikely event that the number of interfaces 2241 * increases between the time we get the count and the time we do the 2242 * SIOCGLIFCONF ioctl. 2243 */ 2244 retry: 2245 /* Get the number of interfaces. */ 2246 if_num.lifn_family = AF_UNSPEC; 2247 if_num.lifn_flags = LIFC_NOXMIT; 2248 if (ioctl(s, SIOCGLIFNUM, &if_num) < 0) { 2249 (void) close(s); 2250 return (Z_ERR); 2251 } 2252 2253 /* Get the interface configuration list. */ 2254 space_needed = if_num.lifn_count * sizeof (struct lifreq); 2255 if ((if_buf = malloc(space_needed)) == NULL) { 2256 (void) close(s); 2257 return (Z_ERR); 2258 } 2259 if_conf.lifc_family = AF_UNSPEC; 2260 if_conf.lifc_flags = LIFC_NOXMIT; 2261 if_conf.lifc_len = space_needed; 2262 if_conf.lifc_buf = if_buf; 2263 if (ioctl(s, SIOCGLIFCONF, &if_conf) < 0) { 2264 free(if_buf); 2265 /* 2266 * SIOCGLIFCONF returns EINVAL if the buffer we passed in is 2267 * too small. In this case go back and get the new if cnt. 2268 */ 2269 if (errno == EINVAL) 2270 goto retry; 2271 2272 (void) close(s); 2273 return (Z_ERR); 2274 } 2275 (void) close(s); 2276 2277 /* Get the name and address family for each interface. */ 2278 if_reqp = if_conf.lifc_req; 2279 for (i = 0; i < (if_conf.lifc_len / sizeof (struct lifreq)); i++) { 2280 struct net_if **p; 2281 struct lifreq req; 2282 2283 if (strcmp(LOOPBACK_IF, if_reqp->lifr_name) == 0) { 2284 if_reqp++; 2285 continue; 2286 } 2287 2288 if ((s = socket(SOCKET_AF(if_reqp->lifr_addr.ss_family), 2289 SOCK_DGRAM, 0)) == -1) { 2290 res = Z_ERR; 2291 break; 2292 } 2293 2294 (void) strncpy(req.lifr_name, if_reqp->lifr_name, 2295 sizeof (req.lifr_name)); 2296 if (ioctl(s, SIOCGLIFADDR, &req) < 0) { 2297 (void) close(s); 2298 if_reqp++; 2299 continue; 2300 } 2301 2302 if ((p = (struct net_if **)realloc(local_ifs, 2303 sizeof (struct net_if *) * (cnt + 1))) == NULL) { 2304 res = Z_ERR; 2305 break; 2306 } 2307 local_ifs = p; 2308 2309 if ((local_ifs[cnt] = malloc(sizeof (struct net_if))) == NULL) { 2310 res = Z_ERR; 2311 break; 2312 } 2313 2314 if ((local_ifs[cnt]->name = strdup(if_reqp->lifr_name)) 2315 == NULL) { 2316 free(local_ifs[cnt]); 2317 res = Z_ERR; 2318 break; 2319 } 2320 local_ifs[cnt]->af = req.lifr_addr.ss_family; 2321 cnt++; 2322 2323 (void) close(s); 2324 if_reqp++; 2325 } 2326 2327 free(if_buf); 2328 2329 if (res != Z_OK) { 2330 free_local_netifs(cnt, local_ifs); 2331 } else { 2332 *if_cnt = cnt; 2333 *if_list = local_ifs; 2334 } 2335 2336 return (res); 2337 } 2338 2339 static char * 2340 af2str(int af) 2341 { 2342 switch (af) { 2343 case AF_INET: 2344 return ("IPv4"); 2345 case AF_INET6: 2346 return ("IPv6"); 2347 default: 2348 return ("Unknown"); 2349 } 2350 } 2351 2352 /* 2353 * Cross check the network interface name and address family with the 2354 * interfaces that are set up in the global zone so that we can print the 2355 * appropriate error message. 2356 */ 2357 static void 2358 print_net_err(char *phys, char *addr, int af, char *msg) 2359 { 2360 int i; 2361 int local_if_cnt = 0; 2362 struct net_if **local_ifs = NULL; 2363 boolean_t found_if = B_FALSE; 2364 boolean_t found_af = B_FALSE; 2365 2366 if (get_local_netifs(&local_if_cnt, &local_ifs) != Z_OK) { 2367 (void) fprintf(stderr, 2368 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"), 2369 "net", "address", addr, "physical", phys, msg); 2370 return; 2371 } 2372 2373 for (i = 0; i < local_if_cnt; i++) { 2374 if (strcmp(phys, local_ifs[i]->name) == 0) { 2375 found_if = B_TRUE; 2376 if (af == local_ifs[i]->af) { 2377 found_af = B_TRUE; 2378 break; 2379 } 2380 } 2381 } 2382 2383 free_local_netifs(local_if_cnt, local_ifs); 2384 2385 if (!found_if) { 2386 (void) fprintf(stderr, 2387 gettext("could not verify %s %s=%s\n\t" 2388 "network interface %s is not plumbed in the global zone\n"), 2389 "net", "physical", phys, phys); 2390 return; 2391 } 2392 2393 /* 2394 * Print this error if we were unable to find the address family 2395 * for this interface. If the af variable is not initialized to 2396 * to something meaningful by the caller (not AF_UNSPEC) then we 2397 * also skip this message since it wouldn't be informative. 2398 */ 2399 if (!found_af && af != AF_UNSPEC) { 2400 (void) fprintf(stderr, 2401 gettext("could not verify %s %s=%s %s=%s\n\tthe %s address " 2402 "family is not configured on this interface in the\n\t" 2403 "global zone\n"), 2404 "net", "address", addr, "physical", phys, af2str(af)); 2405 return; 2406 } 2407 2408 (void) fprintf(stderr, 2409 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"), 2410 "net", "address", addr, "physical", phys, msg); 2411 } 2412 2413 static int 2414 verify_handle(int cmd_num, zone_dochandle_t handle) 2415 { 2416 struct zone_nwiftab nwiftab; 2417 int return_code = Z_OK; 2418 int err; 2419 boolean_t in_alt_root; 2420 2421 in_alt_root = zonecfg_in_alt_root(); 2422 if (in_alt_root) 2423 goto no_net; 2424 2425 if ((err = zonecfg_setnwifent(handle)) != Z_OK) { 2426 errno = err; 2427 zperror(cmd_to_str(cmd_num), B_TRUE); 2428 zonecfg_fini_handle(handle); 2429 return (Z_ERR); 2430 } 2431 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) { 2432 struct lifreq lifr; 2433 sa_family_t af = AF_UNSPEC; 2434 int so, res; 2435 2436 /* skip any loopback interfaces */ 2437 if (strcmp(nwiftab.zone_nwif_physical, "lo0") == 0) 2438 continue; 2439 if ((res = zonecfg_valid_net_address(nwiftab.zone_nwif_address, 2440 &lifr)) != Z_OK) { 2441 print_net_err(nwiftab.zone_nwif_physical, 2442 nwiftab.zone_nwif_address, af, 2443 zonecfg_strerror(res)); 2444 return_code = Z_ERR; 2445 continue; 2446 } 2447 af = lifr.lifr_addr.ss_family; 2448 (void) memset(&lifr, 0, sizeof (lifr)); 2449 (void) strlcpy(lifr.lifr_name, nwiftab.zone_nwif_physical, 2450 sizeof (lifr.lifr_name)); 2451 lifr.lifr_addr.ss_family = af; 2452 if ((so = socket(af, SOCK_DGRAM, 0)) < 0) { 2453 (void) fprintf(stderr, gettext("could not verify %s " 2454 "%s=%s %s=%s: could not get socket: %s\n"), "net", 2455 "address", nwiftab.zone_nwif_address, "physical", 2456 nwiftab.zone_nwif_physical, strerror(errno)); 2457 return_code = Z_ERR; 2458 continue; 2459 } 2460 if (ioctl(so, SIOCGLIFFLAGS, &lifr) < 0) { 2461 print_net_err(nwiftab.zone_nwif_physical, 2462 nwiftab.zone_nwif_address, af, 2463 strerror(errno)); 2464 return_code = Z_ERR; 2465 } 2466 (void) close(so); 2467 } 2468 (void) zonecfg_endnwifent(handle); 2469 no_net: 2470 2471 /* verify that lofs has not been excluded from the kernel */ 2472 if (!(cmd_num == CMD_DETACH || cmd_num == CMD_ATTACH || 2473 cmd_num == CMD_MOVE || cmd_num == CMD_CLONE) && 2474 modctl(MODLOAD, 1, "fs/lofs", NULL) != 0) { 2475 if (errno == ENXIO) 2476 (void) fprintf(stderr, gettext("could not verify " 2477 "lofs(7FS): possibly excluded in /etc/system\n")); 2478 else 2479 (void) fprintf(stderr, gettext("could not verify " 2480 "lofs(7FS): %s\n"), strerror(errno)); 2481 return_code = Z_ERR; 2482 } 2483 2484 if (verify_filesystems(handle) != Z_OK) 2485 return_code = Z_ERR; 2486 if (verify_ipd(handle) != Z_OK) 2487 return_code = Z_ERR; 2488 if (!in_alt_root && verify_rctls(handle) != Z_OK) 2489 return_code = Z_ERR; 2490 if (!in_alt_root && verify_pool(handle) != Z_OK) 2491 return_code = Z_ERR; 2492 if (!in_alt_root && verify_datasets(handle) != Z_OK) 2493 return_code = Z_ERR; 2494 2495 /* 2496 * As the "mount" command is used for patching/upgrading of zones 2497 * or other maintenance processes, the zone's privilege set is not 2498 * checked in this case. Instead, the default, safe set of 2499 * privileges will be used when this zone is created in the 2500 * kernel. 2501 */ 2502 if (!in_alt_root && cmd_num != CMD_MOUNT && 2503 verify_limitpriv(handle) != Z_OK) 2504 return_code = Z_ERR; 2505 2506 return (return_code); 2507 } 2508 2509 static int 2510 verify_details(int cmd_num) 2511 { 2512 zone_dochandle_t handle; 2513 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN]; 2514 int return_code = Z_OK; 2515 int err; 2516 2517 if ((handle = zonecfg_init_handle()) == NULL) { 2518 zperror(cmd_to_str(cmd_num), B_TRUE); 2519 return (Z_ERR); 2520 } 2521 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 2522 errno = err; 2523 zperror(cmd_to_str(cmd_num), B_TRUE); 2524 zonecfg_fini_handle(handle); 2525 return (Z_ERR); 2526 } 2527 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) != 2528 Z_OK) { 2529 errno = err; 2530 zperror(cmd_to_str(cmd_num), B_TRUE); 2531 zonecfg_fini_handle(handle); 2532 return (Z_ERR); 2533 } 2534 /* 2535 * zonecfg_get_zonepath() gets its data from the XML repository. 2536 * Verify this against the index file, which is checked first by 2537 * zone_get_zonepath(). If they don't match, bail out. 2538 */ 2539 if ((err = zone_get_zonepath(target_zone, checkpath, 2540 sizeof (checkpath))) != Z_OK) { 2541 errno = err; 2542 zperror2(target_zone, gettext("could not get zone path")); 2543 return (Z_ERR); 2544 } 2545 if (strcmp(zonepath, checkpath) != 0) { 2546 /* 2547 * TRANSLATION_NOTE 2548 * XML and zonepath are literals that should not be translated. 2549 */ 2550 (void) fprintf(stderr, gettext("The XML repository has " 2551 "zonepath '%s',\nbut the index file has zonepath '%s'.\n" 2552 "These must match, so fix the incorrect entry.\n"), 2553 zonepath, checkpath); 2554 return (Z_ERR); 2555 } 2556 if (validate_zonepath(zonepath, cmd_num) != Z_OK) { 2557 (void) fprintf(stderr, gettext("could not verify zonepath %s " 2558 "because of the above errors.\n"), zonepath); 2559 return_code = Z_ERR; 2560 } 2561 2562 if (verify_handle(cmd_num, handle) != Z_OK) 2563 return_code = Z_ERR; 2564 2565 zonecfg_fini_handle(handle); 2566 if (return_code == Z_ERR) 2567 (void) fprintf(stderr, 2568 gettext("%s: zone %s failed to verify\n"), 2569 execname, target_zone); 2570 return (return_code); 2571 } 2572 2573 static int 2574 verify_func(int argc, char *argv[]) 2575 { 2576 int arg; 2577 2578 optind = 0; 2579 if ((arg = getopt(argc, argv, "?")) != EOF) { 2580 switch (arg) { 2581 case '?': 2582 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2583 return (optopt == '?' ? Z_OK : Z_USAGE); 2584 default: 2585 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2586 return (Z_USAGE); 2587 } 2588 } 2589 if (argc > optind) { 2590 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2591 return (Z_USAGE); 2592 } 2593 if (sanity_check(target_zone, CMD_VERIFY, B_FALSE, B_FALSE) != Z_OK) 2594 return (Z_ERR); 2595 return (verify_details(CMD_VERIFY)); 2596 } 2597 2598 #define LUCREATEZONE "/usr/lib/lu/lucreatezone" 2599 2600 static int 2601 install_func(int argc, char *argv[]) 2602 { 2603 /* 9: "exec " and " -z " */ 2604 char cmdbuf[sizeof (LUCREATEZONE) + ZONENAME_MAX + 9]; 2605 int lockfd; 2606 int err, arg; 2607 char zonepath[MAXPATHLEN]; 2608 int status; 2609 boolean_t nodataset = B_FALSE; 2610 2611 if (zonecfg_in_alt_root()) { 2612 zerror(gettext("cannot install zone in alternate root")); 2613 return (Z_ERR); 2614 } 2615 2616 optind = 0; 2617 if ((arg = getopt(argc, argv, "?x:")) != EOF) { 2618 switch (arg) { 2619 case '?': 2620 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2621 return (optopt == '?' ? Z_OK : Z_USAGE); 2622 case 'x': 2623 if (strcmp(optarg, "nodataset") != 0) { 2624 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2625 return (Z_USAGE); 2626 } 2627 nodataset = B_TRUE; 2628 break; 2629 default: 2630 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2631 return (Z_USAGE); 2632 } 2633 } 2634 if (argc > optind) { 2635 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2636 return (Z_USAGE); 2637 } 2638 if (sanity_check(target_zone, CMD_INSTALL, B_FALSE, B_TRUE) != Z_OK) 2639 return (Z_ERR); 2640 if (verify_details(CMD_INSTALL) != Z_OK) 2641 return (Z_ERR); 2642 2643 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 2644 zerror(gettext("another %s may have an operation in progress."), 2645 "zoneadm"); 2646 return (Z_ERR); 2647 } 2648 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 2649 if (err != Z_OK) { 2650 errno = err; 2651 zperror2(target_zone, gettext("could not set state")); 2652 goto done; 2653 } 2654 2655 /* 2656 * According to the Application Packaging Developer's Guide, a 2657 * "checkinstall" script when included in a package is executed as 2658 * the user "install", if such a user exists, or by the user 2659 * "nobody". In order to support this dubious behavior, the path 2660 * to the zone being constructed is opened up during the life of 2661 * the command laying down the zone's root file system. Once this 2662 * has completed, regardless of whether it was successful, the 2663 * path to the zone is again restricted. 2664 */ 2665 if ((err = zone_get_zonepath(target_zone, zonepath, 2666 sizeof (zonepath))) != Z_OK) { 2667 errno = err; 2668 zperror2(target_zone, gettext("could not get zone path")); 2669 goto done; 2670 } 2671 2672 if (!nodataset) 2673 create_zfs_zonepath(zonepath); 2674 2675 if (chmod(zonepath, DEFAULT_DIR_MODE) != 0) { 2676 zperror(zonepath, B_FALSE); 2677 err = Z_ERR; 2678 goto done; 2679 } 2680 2681 /* 2682 * "exec" the command so that the returned status is that of 2683 * LUCREATEZONE and not the shell. 2684 */ 2685 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " LUCREATEZONE " -z %s", 2686 target_zone); 2687 status = do_subproc(cmdbuf); 2688 if (chmod(zonepath, S_IRWXU) != 0) { 2689 zperror(zonepath, B_FALSE); 2690 err = Z_ERR; 2691 goto done; 2692 } 2693 if ((err = subproc_status(LUCREATEZONE, status)) != Z_OK) 2694 goto done; 2695 2696 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 2697 errno = err; 2698 zperror2(target_zone, gettext("could not set state")); 2699 goto done; 2700 } 2701 2702 done: 2703 release_lock_file(lockfd); 2704 return ((err == Z_OK) ? Z_OK : Z_ERR); 2705 } 2706 2707 /* 2708 * Check that the inherited pkg dirs are the same for the clone and its source. 2709 * The easiest way to do that is check that the list of ipds is the same 2710 * by matching each one against the other. This algorithm should be fine since 2711 * the list of ipds should not be that long. 2712 */ 2713 static int 2714 valid_ipd_clone(zone_dochandle_t s_handle, char *source_zone, 2715 zone_dochandle_t t_handle, char *target_zone) 2716 { 2717 int err; 2718 int res = Z_OK; 2719 int s_cnt = 0; 2720 int t_cnt = 0; 2721 struct zone_fstab s_fstab; 2722 struct zone_fstab t_fstab; 2723 2724 /* 2725 * First check the source of the clone against the target. 2726 */ 2727 if ((err = zonecfg_setipdent(s_handle)) != Z_OK) { 2728 errno = err; 2729 zperror2(source_zone, gettext("could not enumerate " 2730 "inherit-pkg-dirs")); 2731 return (Z_ERR); 2732 } 2733 2734 while (zonecfg_getipdent(s_handle, &s_fstab) == Z_OK) { 2735 boolean_t match = B_FALSE; 2736 2737 s_cnt++; 2738 2739 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 2740 errno = err; 2741 zperror2(target_zone, gettext("could not enumerate " 2742 "inherit-pkg-dirs")); 2743 (void) zonecfg_endipdent(s_handle); 2744 return (Z_ERR); 2745 } 2746 2747 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) { 2748 if (strcmp(s_fstab.zone_fs_dir, t_fstab.zone_fs_dir) 2749 == 0) { 2750 match = B_TRUE; 2751 break; 2752 } 2753 } 2754 (void) zonecfg_endipdent(t_handle); 2755 2756 if (!match) { 2757 (void) fprintf(stderr, gettext("inherit-pkg-dir " 2758 "'%s' is not configured in zone %s.\n"), 2759 s_fstab.zone_fs_dir, target_zone); 2760 res = Z_ERR; 2761 } 2762 } 2763 2764 (void) zonecfg_endipdent(s_handle); 2765 2766 /* skip the next check if we already have errors */ 2767 if (res == Z_ERR) 2768 return (res); 2769 2770 /* 2771 * Now check the number of ipds in the target so we can verify 2772 * that the source is not a subset of the target. 2773 */ 2774 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 2775 errno = err; 2776 zperror2(target_zone, gettext("could not enumerate " 2777 "inherit-pkg-dirs")); 2778 return (Z_ERR); 2779 } 2780 2781 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) 2782 t_cnt++; 2783 2784 (void) zonecfg_endipdent(t_handle); 2785 2786 if (t_cnt != s_cnt) { 2787 (void) fprintf(stderr, gettext("Zone %s is configured " 2788 "with inherit-pkg-dirs that are not configured in zone " 2789 "%s.\n"), target_zone, source_zone); 2790 res = Z_ERR; 2791 } 2792 2793 return (res); 2794 } 2795 2796 static void 2797 warn_dev_match(zone_dochandle_t s_handle, char *source_zone, 2798 zone_dochandle_t t_handle, char *target_zone) 2799 { 2800 int err; 2801 struct zone_devtab s_devtab; 2802 struct zone_devtab t_devtab; 2803 2804 if ((err = zonecfg_setdevent(t_handle)) != Z_OK) { 2805 errno = err; 2806 zperror2(target_zone, gettext("could not enumerate devices")); 2807 return; 2808 } 2809 2810 while (zonecfg_getdevent(t_handle, &t_devtab) == Z_OK) { 2811 if ((err = zonecfg_setdevent(s_handle)) != Z_OK) { 2812 errno = err; 2813 zperror2(source_zone, 2814 gettext("could not enumerate devices")); 2815 (void) zonecfg_enddevent(t_handle); 2816 return; 2817 } 2818 2819 while (zonecfg_getdevent(s_handle, &s_devtab) == Z_OK) { 2820 /* 2821 * Use fnmatch to catch the case where wildcards 2822 * were used in one zone and the other has an 2823 * explicit entry (e.g. /dev/dsk/c0t0d0s6 vs. 2824 * /dev/\*dsk/c0t0d0s6). 2825 */ 2826 if (fnmatch(t_devtab.zone_dev_match, 2827 s_devtab.zone_dev_match, FNM_PATHNAME) == 0 || 2828 fnmatch(s_devtab.zone_dev_match, 2829 t_devtab.zone_dev_match, FNM_PATHNAME) == 0) { 2830 (void) fprintf(stderr, 2831 gettext("WARNING: device '%s' " 2832 "is configured in both zones.\n"), 2833 t_devtab.zone_dev_match); 2834 break; 2835 } 2836 } 2837 (void) zonecfg_enddevent(s_handle); 2838 } 2839 2840 (void) zonecfg_enddevent(t_handle); 2841 } 2842 2843 /* 2844 * Check if the specified mount option (opt) is contained within the 2845 * options string. 2846 */ 2847 static boolean_t 2848 opt_match(char *opt, char *options) 2849 { 2850 char *p; 2851 char *lastp; 2852 2853 if ((p = strtok_r(options, ",", &lastp)) != NULL) { 2854 if (strcmp(p, opt) == 0) 2855 return (B_TRUE); 2856 while ((p = strtok_r(NULL, ",", &lastp)) != NULL) { 2857 if (strcmp(p, opt) == 0) 2858 return (B_TRUE); 2859 } 2860 } 2861 2862 return (B_FALSE); 2863 } 2864 2865 #define RW_LOFS "WARNING: read-write lofs file system on '%s' is configured " \ 2866 "in both zones.\n" 2867 2868 static void 2869 print_fs_warnings(struct zone_fstab *s_fstab, struct zone_fstab *t_fstab) 2870 { 2871 /* 2872 * It is ok to have shared lofs mounted fs but we want to warn if 2873 * either is rw since this will effect the other zone. 2874 */ 2875 if (strcmp(t_fstab->zone_fs_type, "lofs") == 0) { 2876 zone_fsopt_t *optp; 2877 2878 /* The default is rw so no options means rw */ 2879 if (t_fstab->zone_fs_options == NULL || 2880 s_fstab->zone_fs_options == NULL) { 2881 (void) fprintf(stderr, gettext(RW_LOFS), 2882 t_fstab->zone_fs_special); 2883 return; 2884 } 2885 2886 for (optp = s_fstab->zone_fs_options; optp != NULL; 2887 optp = optp->zone_fsopt_next) { 2888 if (opt_match("rw", optp->zone_fsopt_opt)) { 2889 (void) fprintf(stderr, gettext(RW_LOFS), 2890 s_fstab->zone_fs_special); 2891 return; 2892 } 2893 } 2894 2895 for (optp = t_fstab->zone_fs_options; optp != NULL; 2896 optp = optp->zone_fsopt_next) { 2897 if (opt_match("rw", optp->zone_fsopt_opt)) { 2898 (void) fprintf(stderr, gettext(RW_LOFS), 2899 t_fstab->zone_fs_special); 2900 return; 2901 } 2902 } 2903 2904 return; 2905 } 2906 2907 /* 2908 * TRANSLATION_NOTE 2909 * The first variable is the file system type and the second is 2910 * the file system special device. For example, 2911 * WARNING: ufs file system on '/dev/dsk/c0t0d0s0' ... 2912 */ 2913 (void) fprintf(stderr, gettext("WARNING: %s file system on '%s' " 2914 "is configured in both zones.\n"), t_fstab->zone_fs_type, 2915 t_fstab->zone_fs_special); 2916 } 2917 2918 static void 2919 warn_fs_match(zone_dochandle_t s_handle, char *source_zone, 2920 zone_dochandle_t t_handle, char *target_zone) 2921 { 2922 int err; 2923 struct zone_fstab s_fstab; 2924 struct zone_fstab t_fstab; 2925 2926 if ((err = zonecfg_setfsent(t_handle)) != Z_OK) { 2927 errno = err; 2928 zperror2(target_zone, 2929 gettext("could not enumerate file systems")); 2930 return; 2931 } 2932 2933 while (zonecfg_getfsent(t_handle, &t_fstab) == Z_OK) { 2934 if ((err = zonecfg_setfsent(s_handle)) != Z_OK) { 2935 errno = err; 2936 zperror2(source_zone, 2937 gettext("could not enumerate file systems")); 2938 (void) zonecfg_endfsent(t_handle); 2939 return; 2940 } 2941 2942 while (zonecfg_getfsent(s_handle, &s_fstab) == Z_OK) { 2943 if (strcmp(t_fstab.zone_fs_special, 2944 s_fstab.zone_fs_special) == 0) { 2945 print_fs_warnings(&s_fstab, &t_fstab); 2946 break; 2947 } 2948 } 2949 (void) zonecfg_endfsent(s_handle); 2950 } 2951 2952 (void) zonecfg_endfsent(t_handle); 2953 } 2954 2955 /* 2956 * We don't catch the case where you used the same IP address but 2957 * it is not an exact string match. For example, 192.9.0.128 vs. 192.09.0.128. 2958 * However, we're not going to worry about that but we will check for 2959 * a possible netmask on one of the addresses (e.g. 10.0.0.1 and 10.0.0.1/24) 2960 * and handle that case as a match. 2961 */ 2962 static void 2963 warn_ip_match(zone_dochandle_t s_handle, char *source_zone, 2964 zone_dochandle_t t_handle, char *target_zone) 2965 { 2966 int err; 2967 struct zone_nwiftab s_nwiftab; 2968 struct zone_nwiftab t_nwiftab; 2969 2970 if ((err = zonecfg_setnwifent(t_handle)) != Z_OK) { 2971 errno = err; 2972 zperror2(target_zone, 2973 gettext("could not enumerate network interfaces")); 2974 return; 2975 } 2976 2977 while (zonecfg_getnwifent(t_handle, &t_nwiftab) == Z_OK) { 2978 char *p; 2979 2980 /* remove an (optional) netmask from the address */ 2981 if ((p = strchr(t_nwiftab.zone_nwif_address, '/')) != NULL) 2982 *p = '\0'; 2983 2984 if ((err = zonecfg_setnwifent(s_handle)) != Z_OK) { 2985 errno = err; 2986 zperror2(source_zone, 2987 gettext("could not enumerate network interfaces")); 2988 (void) zonecfg_endnwifent(t_handle); 2989 return; 2990 } 2991 2992 while (zonecfg_getnwifent(s_handle, &s_nwiftab) == Z_OK) { 2993 /* remove an (optional) netmask from the address */ 2994 if ((p = strchr(s_nwiftab.zone_nwif_address, '/')) 2995 != NULL) 2996 *p = '\0'; 2997 2998 if (strcmp(t_nwiftab.zone_nwif_address, 2999 s_nwiftab.zone_nwif_address) == 0) { 3000 (void) fprintf(stderr, 3001 gettext("WARNING: network address '%s' " 3002 "is configured in both zones.\n"), 3003 t_nwiftab.zone_nwif_address); 3004 break; 3005 } 3006 } 3007 (void) zonecfg_endnwifent(s_handle); 3008 } 3009 3010 (void) zonecfg_endnwifent(t_handle); 3011 } 3012 3013 static void 3014 warn_dataset_match(zone_dochandle_t s_handle, char *source_zone, 3015 zone_dochandle_t t_handle, char *target_zone) 3016 { 3017 int err; 3018 struct zone_dstab s_dstab; 3019 struct zone_dstab t_dstab; 3020 3021 if ((err = zonecfg_setdsent(t_handle)) != Z_OK) { 3022 errno = err; 3023 zperror2(target_zone, gettext("could not enumerate datasets")); 3024 return; 3025 } 3026 3027 while (zonecfg_getdsent(t_handle, &t_dstab) == Z_OK) { 3028 if ((err = zonecfg_setdsent(s_handle)) != Z_OK) { 3029 errno = err; 3030 zperror2(source_zone, 3031 gettext("could not enumerate datasets")); 3032 (void) zonecfg_enddsent(t_handle); 3033 return; 3034 } 3035 3036 while (zonecfg_getdsent(s_handle, &s_dstab) == Z_OK) { 3037 if (strcmp(t_dstab.zone_dataset_name, 3038 s_dstab.zone_dataset_name) == 0) { 3039 (void) fprintf(stderr, 3040 gettext("WARNING: dataset '%s' " 3041 "is configured in both zones.\n"), 3042 t_dstab.zone_dataset_name); 3043 break; 3044 } 3045 } 3046 (void) zonecfg_enddsent(s_handle); 3047 } 3048 3049 (void) zonecfg_enddsent(t_handle); 3050 } 3051 3052 static int 3053 validate_clone(char *source_zone, char *target_zone) 3054 { 3055 int err = Z_OK; 3056 zone_dochandle_t s_handle; 3057 zone_dochandle_t t_handle; 3058 3059 if ((t_handle = zonecfg_init_handle()) == NULL) { 3060 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3061 return (Z_ERR); 3062 } 3063 if ((err = zonecfg_get_handle(target_zone, t_handle)) != Z_OK) { 3064 errno = err; 3065 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3066 zonecfg_fini_handle(t_handle); 3067 return (Z_ERR); 3068 } 3069 3070 if ((s_handle = zonecfg_init_handle()) == NULL) { 3071 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3072 zonecfg_fini_handle(t_handle); 3073 return (Z_ERR); 3074 } 3075 if ((err = zonecfg_get_handle(source_zone, s_handle)) != Z_OK) { 3076 errno = err; 3077 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3078 goto done; 3079 } 3080 3081 /* verify new zone has same inherit-pkg-dirs */ 3082 err = valid_ipd_clone(s_handle, source_zone, t_handle, target_zone); 3083 3084 /* warn about imported fs's which are the same */ 3085 warn_fs_match(s_handle, source_zone, t_handle, target_zone); 3086 3087 /* warn about imported IP addresses which are the same */ 3088 warn_ip_match(s_handle, source_zone, t_handle, target_zone); 3089 3090 /* warn about imported devices which are the same */ 3091 warn_dev_match(s_handle, source_zone, t_handle, target_zone); 3092 3093 /* warn about imported datasets which are the same */ 3094 warn_dataset_match(s_handle, source_zone, t_handle, target_zone); 3095 3096 done: 3097 zonecfg_fini_handle(t_handle); 3098 zonecfg_fini_handle(s_handle); 3099 3100 return ((err == Z_OK) ? Z_OK : Z_ERR); 3101 } 3102 3103 static int 3104 copy_zone(char *src, char *dst) 3105 { 3106 boolean_t out_null = B_FALSE; 3107 int status; 3108 int err; 3109 char *outfile; 3110 char cmdbuf[MAXPATHLEN * 2 + 128]; 3111 3112 if ((outfile = tempnam("/var/log", "zone")) == NULL) { 3113 outfile = "/dev/null"; 3114 out_null = B_TRUE; 3115 } 3116 3117 /* 3118 * Use find to get the list of files to copy. We need to skip 3119 * files of type "socket" since cpio can't handle those but that 3120 * should be ok since the app will recreate the socket when it runs. 3121 * We also need to filter out anything under the .zfs subdir. Since 3122 * find is running depth-first, we need the extra egrep to filter .zfs. 3123 */ 3124 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3125 "cd %s && /usr/bin/find . -type s -prune -o -depth -print | " 3126 "/usr/bin/egrep -v '^\\./\\.zfs$|^\\./\\.zfs/' | " 3127 "/usr/bin/cpio -pdmuP@ %s > %s 2>&1", 3128 src, dst, outfile); 3129 3130 status = do_subproc(cmdbuf); 3131 3132 if ((err = subproc_status("copy", status)) != Z_OK) { 3133 if (!out_null) 3134 (void) fprintf(stderr, gettext("\nThe copy failed.\n" 3135 "More information can be found in %s\n"), outfile); 3136 return (err); 3137 } 3138 3139 if (!out_null) 3140 (void) unlink(outfile); 3141 3142 return (Z_OK); 3143 } 3144 3145 /* 3146 * Run sys-unconfig on a zone. This will leave the zone in the installed 3147 * state as long as there were no errors during the sys-unconfig. 3148 */ 3149 static int 3150 unconfigure_zone(char *zonepath) 3151 { 3152 int err; 3153 int status; 3154 struct stat unconfig_buf; 3155 zone_cmd_arg_t zarg; 3156 char cmdbuf[MAXPATHLEN + 51]; 3157 3158 /* The zone has to be installed in order to mount the scratch zone. */ 3159 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 3160 errno = err; 3161 zperror2(target_zone, gettext("could not set state")); 3162 return (Z_ERR); 3163 } 3164 3165 /* 3166 * Trusted Extensions requires that cloned zones use the 3167 * same sysid configuration, so it is not appropriate to 3168 * unconfigure the zone. 3169 */ 3170 if (is_system_labeled()) 3171 return (Z_OK); 3172 3173 /* 3174 * Check if the zone is already sys-unconfiged. This saves us 3175 * the work of bringing up the scratch zone so we can unconfigure it. 3176 */ 3177 (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s/root/etc/.UNCONFIGURED", 3178 zonepath); 3179 if (stat(cmdbuf, &unconfig_buf) == 0) 3180 return (Z_OK); 3181 3182 zarg.cmd = Z_MOUNT; 3183 if (call_zoneadmd(target_zone, &zarg) != 0) { 3184 zerror(gettext("call to %s failed"), "zoneadmd"); 3185 (void) zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3186 return (Z_ERR); 3187 } 3188 3189 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3190 "/usr/sbin/zlogin -S %s /usr/sbin/sys-unconfig -R /a", target_zone); 3191 3192 status = do_subproc(cmdbuf); 3193 if ((err = subproc_status("sys-unconfig", status)) != Z_OK) { 3194 errno = err; 3195 zperror2(target_zone, gettext("sys-unconfig failed\n")); 3196 (void) zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3197 } 3198 3199 zarg.cmd = Z_UNMOUNT; 3200 if (call_zoneadmd(target_zone, &zarg) != 0) { 3201 zerror(gettext("call to %s failed"), "zoneadmd"); 3202 (void) fprintf(stderr, gettext("could not unmount zone\n")); 3203 return (Z_ERR); 3204 } 3205 3206 return ((err == Z_OK) ? Z_OK : Z_ERR); 3207 } 3208 3209 /* ARGSUSED */ 3210 static int 3211 zfm_print(const char *p, void *r) { 3212 zerror(" %s\n", p); 3213 return (0); 3214 } 3215 3216 int 3217 clone_copy(char *source_zonepath, char *zonepath) 3218 { 3219 int err; 3220 3221 /* Don't clone the zone if anything is still mounted there */ 3222 if (zonecfg_find_mounts(source_zonepath, NULL, NULL)) { 3223 zerror(gettext("These file systems are mounted on " 3224 "subdirectories of %s.\n"), source_zonepath); 3225 (void) zonecfg_find_mounts(source_zonepath, zfm_print, NULL); 3226 return (Z_ERR); 3227 } 3228 3229 /* 3230 * Attempt to create a ZFS fs for the zonepath. As usual, we don't 3231 * care if this works or not since we always have the default behavior 3232 * of a simple directory for the zonepath. 3233 */ 3234 create_zfs_zonepath(zonepath); 3235 3236 (void) printf(gettext("Copying %s..."), source_zonepath); 3237 (void) fflush(stdout); 3238 3239 err = copy_zone(source_zonepath, zonepath); 3240 3241 (void) printf("\n"); 3242 3243 return (err); 3244 } 3245 3246 static int 3247 clone_func(int argc, char *argv[]) 3248 { 3249 char *source_zone = NULL; 3250 int lockfd; 3251 int err, arg; 3252 char zonepath[MAXPATHLEN]; 3253 char source_zonepath[MAXPATHLEN]; 3254 zone_state_t state; 3255 zone_entry_t *zent; 3256 char *method = NULL; 3257 char *snapshot = NULL; 3258 3259 if (zonecfg_in_alt_root()) { 3260 zerror(gettext("cannot clone zone in alternate root")); 3261 return (Z_ERR); 3262 } 3263 3264 optind = 0; 3265 if ((arg = getopt(argc, argv, "?m:s:")) != EOF) { 3266 switch (arg) { 3267 case '?': 3268 sub_usage(SHELP_CLONE, CMD_CLONE); 3269 return (optopt == '?' ? Z_OK : Z_USAGE); 3270 case 'm': 3271 method = optarg; 3272 break; 3273 case 's': 3274 snapshot = optarg; 3275 break; 3276 default: 3277 sub_usage(SHELP_CLONE, CMD_CLONE); 3278 return (Z_USAGE); 3279 } 3280 } 3281 if (argc != (optind + 1) || 3282 (method != NULL && strcmp(method, "copy") != 0)) { 3283 sub_usage(SHELP_CLONE, CMD_CLONE); 3284 return (Z_USAGE); 3285 } 3286 source_zone = argv[optind]; 3287 if (sanity_check(target_zone, CMD_CLONE, B_FALSE, B_TRUE) != Z_OK) 3288 return (Z_ERR); 3289 if (verify_details(CMD_CLONE) != Z_OK) 3290 return (Z_ERR); 3291 3292 /* 3293 * We also need to do some extra validation on the source zone. 3294 */ 3295 if (strcmp(source_zone, GLOBAL_ZONENAME) == 0) { 3296 zerror(gettext("%s operation is invalid for the global zone."), 3297 cmd_to_str(CMD_CLONE)); 3298 return (Z_ERR); 3299 } 3300 3301 if (strncmp(source_zone, "SUNW", 4) == 0) { 3302 zerror(gettext("%s operation is invalid for zones starting " 3303 "with SUNW."), cmd_to_str(CMD_CLONE)); 3304 return (Z_ERR); 3305 } 3306 3307 zent = lookup_running_zone(source_zone); 3308 if (zent != NULL) { 3309 /* check whether the zone is ready or running */ 3310 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) 3311 != Z_OK) { 3312 errno = err; 3313 zperror2(zent->zname, gettext("could not get state")); 3314 /* can't tell, so hedge */ 3315 zent->zstate_str = "ready/running"; 3316 } else { 3317 zent->zstate_str = zone_state_str(zent->zstate_num); 3318 } 3319 zerror(gettext("%s operation is invalid for %s zones."), 3320 cmd_to_str(CMD_CLONE), zent->zstate_str); 3321 return (Z_ERR); 3322 } 3323 3324 if ((err = zone_get_state(source_zone, &state)) != Z_OK) { 3325 errno = err; 3326 zperror2(source_zone, gettext("could not get state")); 3327 return (Z_ERR); 3328 } 3329 if (state != ZONE_STATE_INSTALLED) { 3330 (void) fprintf(stderr, 3331 gettext("%s: zone %s is %s; %s is required.\n"), 3332 execname, source_zone, zone_state_str(state), 3333 zone_state_str(ZONE_STATE_INSTALLED)); 3334 return (Z_ERR); 3335 } 3336 3337 /* 3338 * The source zone checks out ok, continue with the clone. 3339 */ 3340 3341 if (validate_clone(source_zone, target_zone) != Z_OK) 3342 return (Z_ERR); 3343 3344 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3345 zerror(gettext("another %s may have an operation in progress."), 3346 "zoneadm"); 3347 return (Z_ERR); 3348 } 3349 3350 if ((err = zone_get_zonepath(source_zone, source_zonepath, 3351 sizeof (source_zonepath))) != Z_OK) { 3352 errno = err; 3353 zperror2(source_zone, gettext("could not get zone path")); 3354 goto done; 3355 } 3356 3357 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3358 != Z_OK) { 3359 errno = err; 3360 zperror2(target_zone, gettext("could not get zone path")); 3361 goto done; 3362 } 3363 3364 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 3365 != Z_OK) { 3366 errno = err; 3367 zperror2(target_zone, gettext("could not set state")); 3368 goto done; 3369 } 3370 3371 if (snapshot != NULL) { 3372 err = clone_snapshot_zfs(snapshot, zonepath); 3373 } else { 3374 /* 3375 * We always copy the clone unless the source is ZFS and a 3376 * ZFS clone worked. We fallback to copying if the ZFS clone 3377 * fails for some reason. 3378 */ 3379 err = Z_ERR; 3380 if (method == NULL && is_zonepath_zfs(source_zonepath)) 3381 err = clone_zfs(source_zone, source_zonepath, zonepath); 3382 3383 if (err != Z_OK) 3384 err = clone_copy(source_zonepath, zonepath); 3385 } 3386 3387 if (err == Z_OK) 3388 err = unconfigure_zone(zonepath); 3389 3390 done: 3391 release_lock_file(lockfd); 3392 return ((err == Z_OK) ? Z_OK : Z_ERR); 3393 } 3394 3395 #define RMCOMMAND "/usr/bin/rm -rf" 3396 3397 /* 3398 * Used when removing a zonepath after uninstalling or cleaning up after 3399 * the move subcommand. This handles a zonepath that has non-standard 3400 * contents so that we will only cleanup the stuff we know about and leave 3401 * any user data alone. 3402 * 3403 * If the "all" parameter is true then we should remove the whole zonepath 3404 * even if it has non-standard files/directories in it. This can be used when 3405 * we need to cleanup after moving the zonepath across file systems. 3406 * 3407 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND 3408 * and not the shell. 3409 */ 3410 static int 3411 cleanup_zonepath(char *zonepath, boolean_t all) 3412 { 3413 int status; 3414 int i; 3415 boolean_t non_std = B_FALSE; 3416 struct dirent *dp; 3417 DIR *dirp; 3418 char *std_entries[] = {"dev", "lu", "root", NULL}; 3419 /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ 3420 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; 3421 3422 /* 3423 * We shouldn't need these checks but lets be paranoid since we 3424 * could blow away the whole system here if we got the wrong zonepath. 3425 */ 3426 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) { 3427 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath); 3428 return (Z_INVAL); 3429 } 3430 3431 /* 3432 * If the dirpath is already gone (maybe it was manually removed) then 3433 * we just return Z_OK so that the cleanup is successful. 3434 */ 3435 if ((dirp = opendir(zonepath)) == NULL) 3436 return (Z_OK); 3437 3438 /* 3439 * Look through the zonepath directory to see if there are any 3440 * non-standard files/dirs. Also skip .zfs since that might be 3441 * there but we'll handle ZFS file systems as a special case. 3442 */ 3443 while ((dp = readdir(dirp)) != NULL) { 3444 if (strcmp(dp->d_name, ".") == 0 || 3445 strcmp(dp->d_name, "..") == 0 || 3446 strcmp(dp->d_name, ".zfs") == 0) 3447 continue; 3448 3449 for (i = 0; std_entries[i] != NULL; i++) 3450 if (strcmp(dp->d_name, std_entries[i]) == 0) 3451 break; 3452 3453 if (std_entries[i] == NULL) 3454 non_std = B_TRUE; 3455 } 3456 (void) closedir(dirp); 3457 3458 if (!all && non_std) { 3459 /* 3460 * There are extra, non-standard directories/files in the 3461 * zonepath so we don't want to remove the zonepath. We 3462 * just want to remove the standard directories and leave 3463 * the user data alone. 3464 */ 3465 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND); 3466 3467 for (i = 0; std_entries[i] != NULL; i++) { 3468 char tmpbuf[MAXPATHLEN]; 3469 3470 if (snprintf(tmpbuf, sizeof (tmpbuf), " %s/%s", 3471 zonepath, std_entries[i]) >= sizeof (tmpbuf) || 3472 strlcat(cmdbuf, tmpbuf, sizeof (cmdbuf)) >= 3473 sizeof (cmdbuf)) { 3474 (void) fprintf(stderr, 3475 gettext("path is too long\n")); 3476 return (Z_INVAL); 3477 } 3478 } 3479 3480 status = do_subproc(cmdbuf); 3481 3482 (void) fprintf(stderr, gettext("WARNING: Unable to completely " 3483 "remove %s\nbecause it contains additional user data. " 3484 "Only the standard directory\nentries have been " 3485 "removed.\n"), 3486 zonepath); 3487 3488 return (subproc_status(RMCOMMAND, status)); 3489 } 3490 3491 /* 3492 * There is nothing unexpected in the zonepath, try to get rid of the 3493 * whole zonepath directory. 3494 * 3495 * If the zonepath is its own zfs file system, try to destroy the 3496 * file system. If that fails for some reason (e.g. it has clones) 3497 * then we'll just remove the contents of the zonepath. 3498 */ 3499 if (is_zonepath_zfs(zonepath)) { 3500 if (destroy_zfs(zonepath) == Z_OK) 3501 return (Z_OK); 3502 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND 3503 " %s/*", zonepath); 3504 status = do_subproc(cmdbuf); 3505 return (subproc_status(RMCOMMAND, status)); 3506 } 3507 3508 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3509 zonepath); 3510 status = do_subproc(cmdbuf); 3511 return (subproc_status(RMCOMMAND, status)); 3512 } 3513 3514 static int 3515 move_func(int argc, char *argv[]) 3516 { 3517 char *new_zonepath = NULL; 3518 int lockfd; 3519 int err, arg; 3520 char zonepath[MAXPATHLEN]; 3521 zone_dochandle_t handle; 3522 boolean_t fast; 3523 boolean_t is_zfs = B_FALSE; 3524 struct dirent *dp; 3525 DIR *dirp; 3526 boolean_t empty = B_TRUE; 3527 boolean_t revert; 3528 struct stat zonepath_buf; 3529 struct stat new_zonepath_buf; 3530 3531 if (zonecfg_in_alt_root()) { 3532 zerror(gettext("cannot move zone in alternate root")); 3533 return (Z_ERR); 3534 } 3535 3536 optind = 0; 3537 if ((arg = getopt(argc, argv, "?")) != EOF) { 3538 switch (arg) { 3539 case '?': 3540 sub_usage(SHELP_MOVE, CMD_MOVE); 3541 return (optopt == '?' ? Z_OK : Z_USAGE); 3542 default: 3543 sub_usage(SHELP_MOVE, CMD_MOVE); 3544 return (Z_USAGE); 3545 } 3546 } 3547 if (argc != (optind + 1)) { 3548 sub_usage(SHELP_MOVE, CMD_MOVE); 3549 return (Z_USAGE); 3550 } 3551 new_zonepath = argv[optind]; 3552 if (sanity_check(target_zone, CMD_MOVE, B_FALSE, B_TRUE) != Z_OK) 3553 return (Z_ERR); 3554 if (verify_details(CMD_MOVE) != Z_OK) 3555 return (Z_ERR); 3556 3557 /* 3558 * Check out the new zonepath. This has the side effect of creating 3559 * a directory for the new zonepath. We depend on this later when we 3560 * stat to see if we are doing a cross file system move or not. 3561 */ 3562 if (validate_zonepath(new_zonepath, CMD_MOVE) != Z_OK) 3563 return (Z_ERR); 3564 3565 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3566 != Z_OK) { 3567 errno = err; 3568 zperror2(target_zone, gettext("could not get zone path")); 3569 return (Z_ERR); 3570 } 3571 3572 if (stat(zonepath, &zonepath_buf) == -1) { 3573 zperror(gettext("could not stat zone path"), B_FALSE); 3574 return (Z_ERR); 3575 } 3576 3577 if (stat(new_zonepath, &new_zonepath_buf) == -1) { 3578 zperror(gettext("could not stat new zone path"), B_FALSE); 3579 return (Z_ERR); 3580 } 3581 3582 /* 3583 * Check if the destination directory is empty. 3584 */ 3585 if ((dirp = opendir(new_zonepath)) == NULL) { 3586 zperror(gettext("could not open new zone path"), B_FALSE); 3587 return (Z_ERR); 3588 } 3589 while ((dp = readdir(dirp)) != (struct dirent *)0) { 3590 if (strcmp(dp->d_name, ".") == 0 || 3591 strcmp(dp->d_name, "..") == 0) 3592 continue; 3593 empty = B_FALSE; 3594 break; 3595 } 3596 (void) closedir(dirp); 3597 3598 /* Error if there is anything in the destination directory. */ 3599 if (!empty) { 3600 (void) fprintf(stderr, gettext("could not move zone to %s: " 3601 "directory not empty\n"), new_zonepath); 3602 return (Z_ERR); 3603 } 3604 3605 /* Don't move the zone if anything is still mounted there */ 3606 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { 3607 zerror(gettext("These file systems are mounted on " 3608 "subdirectories of %s.\n"), zonepath); 3609 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3610 return (Z_ERR); 3611 } 3612 3613 /* 3614 * Check if we are moving in the same file system and can do a fast 3615 * move or if we are crossing file systems and have to copy the data. 3616 */ 3617 fast = (zonepath_buf.st_dev == new_zonepath_buf.st_dev); 3618 3619 if ((handle = zonecfg_init_handle()) == NULL) { 3620 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3621 return (Z_ERR); 3622 } 3623 3624 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 3625 errno = err; 3626 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3627 zonecfg_fini_handle(handle); 3628 return (Z_ERR); 3629 } 3630 3631 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3632 zerror(gettext("another %s may have an operation in progress."), 3633 "zoneadm"); 3634 zonecfg_fini_handle(handle); 3635 return (Z_ERR); 3636 } 3637 3638 /* 3639 * We're making some file system changes now so we have to clean up 3640 * the file system before we are done. This will either clean up the 3641 * new zonepath if the zonecfg update failed or it will clean up the 3642 * old zonepath if everything is ok. 3643 */ 3644 revert = B_TRUE; 3645 3646 if (is_zonepath_zfs(zonepath) && 3647 move_zfs(zonepath, new_zonepath) != Z_ERR) { 3648 is_zfs = B_TRUE; 3649 3650 } else if (fast) { 3651 /* same file system, use rename for a quick move */ 3652 3653 /* 3654 * Remove the new_zonepath directory that got created above 3655 * during the validation. It gets in the way of the rename. 3656 */ 3657 if (rmdir(new_zonepath) != 0) { 3658 zperror(gettext("could not rmdir new zone path"), 3659 B_FALSE); 3660 zonecfg_fini_handle(handle); 3661 release_lock_file(lockfd); 3662 return (Z_ERR); 3663 } 3664 3665 if (rename(zonepath, new_zonepath) != 0) { 3666 /* 3667 * If this fails we don't need to do all of the 3668 * cleanup that happens for the rest of the code 3669 * so just return from this error. 3670 */ 3671 zperror(gettext("could not move zone"), B_FALSE); 3672 zonecfg_fini_handle(handle); 3673 release_lock_file(lockfd); 3674 return (Z_ERR); 3675 } 3676 3677 } else { 3678 /* 3679 * Attempt to create a ZFS fs for the new zonepath. As usual, 3680 * we don't care if this works or not since we always have the 3681 * default behavior of a simple directory for the zonepath. 3682 */ 3683 create_zfs_zonepath(new_zonepath); 3684 3685 (void) printf(gettext( 3686 "Moving across file systems; copying zonepath %s..."), 3687 zonepath); 3688 (void) fflush(stdout); 3689 3690 err = copy_zone(zonepath, new_zonepath); 3691 3692 (void) printf("\n"); 3693 if (err != Z_OK) 3694 goto done; 3695 } 3696 3697 if ((err = zonecfg_set_zonepath(handle, new_zonepath)) != Z_OK) { 3698 errno = err; 3699 zperror(gettext("could not set new zonepath"), B_TRUE); 3700 goto done; 3701 } 3702 3703 if ((err = zonecfg_save(handle)) != Z_OK) { 3704 errno = err; 3705 zperror(gettext("zonecfg save failed"), B_TRUE); 3706 goto done; 3707 } 3708 3709 revert = B_FALSE; 3710 3711 done: 3712 zonecfg_fini_handle(handle); 3713 release_lock_file(lockfd); 3714 3715 /* 3716 * Clean up the file system based on how things went. We either 3717 * clean up the new zonepath if the operation failed for some reason 3718 * or we clean up the old zonepath if everything is ok. 3719 */ 3720 if (revert) { 3721 /* The zonecfg update failed, cleanup the new zonepath. */ 3722 if (is_zfs) { 3723 if (move_zfs(new_zonepath, zonepath) == Z_ERR) { 3724 (void) fprintf(stderr, gettext("could not " 3725 "restore zonepath, the zfs mountpoint is " 3726 "set as:\n%s\n"), new_zonepath); 3727 /* 3728 * err is already != Z_OK since we're reverting 3729 */ 3730 } 3731 3732 } else if (fast) { 3733 if (rename(new_zonepath, zonepath) != 0) { 3734 zperror(gettext("could not restore zonepath"), 3735 B_FALSE); 3736 /* 3737 * err is already != Z_OK since we're reverting 3738 */ 3739 } 3740 } else { 3741 (void) printf(gettext("Cleaning up zonepath %s..."), 3742 new_zonepath); 3743 (void) fflush(stdout); 3744 err = cleanup_zonepath(new_zonepath, B_TRUE); 3745 (void) printf("\n"); 3746 3747 if (err != Z_OK) { 3748 errno = err; 3749 zperror(gettext("could not remove new " 3750 "zonepath"), B_TRUE); 3751 } else { 3752 /* 3753 * Because we're reverting we know the mainline 3754 * code failed but we just reused the err 3755 * variable so we reset it back to Z_ERR. 3756 */ 3757 err = Z_ERR; 3758 } 3759 } 3760 3761 } else { 3762 /* The move was successful, cleanup the old zonepath. */ 3763 if (!is_zfs && !fast) { 3764 (void) printf( 3765 gettext("Cleaning up zonepath %s..."), zonepath); 3766 (void) fflush(stdout); 3767 err = cleanup_zonepath(zonepath, B_TRUE); 3768 (void) printf("\n"); 3769 3770 if (err != Z_OK) { 3771 errno = err; 3772 zperror(gettext("could not remove zonepath"), 3773 B_TRUE); 3774 } 3775 } 3776 } 3777 3778 return ((err == Z_OK) ? Z_OK : Z_ERR); 3779 } 3780 3781 static int 3782 detach_func(int argc, char *argv[]) 3783 { 3784 int lockfd; 3785 int err, arg; 3786 char zonepath[MAXPATHLEN]; 3787 zone_dochandle_t handle; 3788 boolean_t execute = B_TRUE; 3789 3790 if (zonecfg_in_alt_root()) { 3791 zerror(gettext("cannot detach zone in alternate root")); 3792 return (Z_ERR); 3793 } 3794 3795 optind = 0; 3796 if ((arg = getopt(argc, argv, "?n")) != EOF) { 3797 switch (arg) { 3798 case '?': 3799 sub_usage(SHELP_DETACH, CMD_DETACH); 3800 return (optopt == '?' ? Z_OK : Z_USAGE); 3801 case 'n': 3802 execute = B_FALSE; 3803 break; 3804 default: 3805 sub_usage(SHELP_DETACH, CMD_DETACH); 3806 return (Z_USAGE); 3807 } 3808 } 3809 if (execute) { 3810 if (sanity_check(target_zone, CMD_DETACH, B_FALSE, B_TRUE) 3811 != Z_OK) 3812 return (Z_ERR); 3813 if (verify_details(CMD_DETACH) != Z_OK) 3814 return (Z_ERR); 3815 } else { 3816 /* 3817 * We want a dry-run to work for a non-privileged user so we 3818 * only do minimal validation. 3819 */ 3820 if (getzoneid() != GLOBAL_ZONEID) { 3821 zerror(gettext("must be in the global zone to %s a " 3822 "zone."), cmd_to_str(CMD_DETACH)); 3823 return (Z_ERR); 3824 } 3825 3826 if (target_zone == NULL) { 3827 zerror(gettext("no zone specified")); 3828 return (Z_ERR); 3829 } 3830 3831 if (strcmp(target_zone, GLOBAL_ZONENAME) == 0) { 3832 zerror(gettext("%s operation is invalid for the " 3833 "global zone."), cmd_to_str(CMD_DETACH)); 3834 return (Z_ERR); 3835 } 3836 } 3837 3838 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3839 != Z_OK) { 3840 errno = err; 3841 zperror2(target_zone, gettext("could not get zone path")); 3842 return (Z_ERR); 3843 } 3844 3845 /* Don't detach the zone if anything is still mounted there */ 3846 if (execute && zonecfg_find_mounts(zonepath, NULL, NULL)) { 3847 zerror(gettext("These file systems are mounted on " 3848 "subdirectories of %s.\n"), zonepath); 3849 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3850 return (Z_ERR); 3851 } 3852 3853 if ((handle = zonecfg_init_handle()) == NULL) { 3854 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3855 return (Z_ERR); 3856 } 3857 3858 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 3859 errno = err; 3860 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3861 zonecfg_fini_handle(handle); 3862 return (Z_ERR); 3863 } 3864 3865 if (execute && grab_lock_file(target_zone, &lockfd) != Z_OK) { 3866 zerror(gettext("another %s may have an operation in progress."), 3867 "zoneadm"); 3868 zonecfg_fini_handle(handle); 3869 return (Z_ERR); 3870 } 3871 3872 if ((err = zonecfg_get_detach_info(handle, B_TRUE)) != Z_OK) { 3873 errno = err; 3874 zperror(gettext("getting the detach information failed"), 3875 B_TRUE); 3876 goto done; 3877 } 3878 3879 if ((err = zonecfg_detach_save(handle, (execute ? 0 : ZONE_DRY_RUN))) 3880 != Z_OK) { 3881 errno = err; 3882 zperror(gettext("saving the detach manifest failed"), B_TRUE); 3883 goto done; 3884 } 3885 3886 /* 3887 * Set the zone state back to configured unless we are running with the 3888 * no-execute option. 3889 */ 3890 if (execute && (err = zone_set_state(target_zone, 3891 ZONE_STATE_CONFIGURED)) != Z_OK) { 3892 errno = err; 3893 zperror(gettext("could not reset state"), B_TRUE); 3894 } 3895 3896 done: 3897 zonecfg_fini_handle(handle); 3898 if (execute) 3899 release_lock_file(lockfd); 3900 3901 return ((err == Z_OK) ? Z_OK : Z_ERR); 3902 } 3903 3904 /* 3905 * During attach we go through and fix up the /dev entries for the zone 3906 * we are attaching. In order to regenerate /dev with the correct devices, 3907 * the old /dev will be removed, the zone readied (which generates a new 3908 * /dev) then halted, then we use the info from the manifest to update 3909 * the modes, owners, etc. on the new /dev. 3910 */ 3911 static int 3912 dev_fix(zone_dochandle_t handle) 3913 { 3914 int res; 3915 int err; 3916 int status; 3917 struct zone_devpermtab devtab; 3918 zone_cmd_arg_t zarg; 3919 char devpath[MAXPATHLEN]; 3920 /* 6: "exec " and " " */ 3921 char cmdbuf[sizeof (RMCOMMAND) + MAXPATHLEN + 6]; 3922 3923 if ((res = zonecfg_get_zonepath(handle, devpath, sizeof (devpath))) 3924 != Z_OK) 3925 return (res); 3926 3927 if (strlcat(devpath, "/dev", sizeof (devpath)) >= sizeof (devpath)) 3928 return (Z_TOO_BIG); 3929 3930 /* 3931 * "exec" the command so that the returned status is that of 3932 * RMCOMMAND and not the shell. 3933 */ 3934 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3935 devpath); 3936 status = do_subproc(cmdbuf); 3937 if ((err = subproc_status(RMCOMMAND, status)) != Z_OK) { 3938 (void) fprintf(stderr, 3939 gettext("could not remove existing /dev\n")); 3940 return (Z_ERR); 3941 } 3942 3943 /* In order to ready the zone, it must be in the installed state */ 3944 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 3945 errno = err; 3946 zperror(gettext("could not reset state"), B_TRUE); 3947 return (Z_ERR); 3948 } 3949 3950 /* We have to ready the zone to regen the dev tree */ 3951 zarg.cmd = Z_READY; 3952 if (call_zoneadmd(target_zone, &zarg) != 0) { 3953 zerror(gettext("call to %s failed"), "zoneadmd"); 3954 return (Z_ERR); 3955 } 3956 3957 zarg.cmd = Z_HALT; 3958 if (call_zoneadmd(target_zone, &zarg) != 0) { 3959 zerror(gettext("call to %s failed"), "zoneadmd"); 3960 return (Z_ERR); 3961 } 3962 3963 if (zonecfg_setdevperment(handle) != Z_OK) { 3964 (void) fprintf(stderr, 3965 gettext("unable to enumerate device entries\n")); 3966 return (Z_ERR); 3967 } 3968 3969 while (zonecfg_getdevperment(handle, &devtab) == Z_OK) { 3970 int err; 3971 3972 if ((err = zonecfg_devperms_apply(handle, 3973 devtab.zone_devperm_name, devtab.zone_devperm_uid, 3974 devtab.zone_devperm_gid, devtab.zone_devperm_mode, 3975 devtab.zone_devperm_acl)) != Z_OK && err != Z_INVAL) 3976 (void) fprintf(stderr, gettext("error updating device " 3977 "%s: %s\n"), devtab.zone_devperm_name, 3978 zonecfg_strerror(err)); 3979 3980 free(devtab.zone_devperm_acl); 3981 } 3982 3983 (void) zonecfg_enddevperment(handle); 3984 3985 return (Z_OK); 3986 } 3987 3988 /* 3989 * Validate attaching a zone but don't actually do the work. The zone 3990 * does not have to exist, so there is some complexity getting a new zone 3991 * configuration set up so that we can perform the validation. This is 3992 * handled within zonecfg_attach_manifest() which returns two handles; one 3993 * for the the full configuration to validate (rem_handle) and the other 3994 * (local_handle) containing only the zone configuration derived from the 3995 * manifest. 3996 */ 3997 static int 3998 dryrun_attach(char *manifest_path) 3999 { 4000 int fd; 4001 int err; 4002 int res; 4003 zone_dochandle_t local_handle; 4004 zone_dochandle_t rem_handle = NULL; 4005 4006 if (strcmp(manifest_path, "-") == 0) { 4007 fd = 0; 4008 } else if ((fd = open(manifest_path, O_RDONLY)) < 0) { 4009 zperror(gettext("could not open manifest path"), B_FALSE); 4010 return (Z_ERR); 4011 } 4012 4013 if ((local_handle = zonecfg_init_handle()) == NULL) { 4014 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4015 res = Z_ERR; 4016 goto done; 4017 } 4018 4019 if ((rem_handle = zonecfg_init_handle()) == NULL) { 4020 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4021 res = Z_ERR; 4022 goto done; 4023 } 4024 4025 if ((err = zonecfg_attach_manifest(fd, local_handle, rem_handle)) 4026 != Z_OK) { 4027 if (err == Z_INVALID_DOCUMENT) 4028 zerror(gettext("Cannot attach to an earlier release " 4029 "of the operating system")); 4030 else 4031 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4032 res = Z_ERR; 4033 goto done; 4034 } 4035 4036 res = verify_handle(CMD_ATTACH, local_handle); 4037 4038 /* Get the detach information for the locally defined zone. */ 4039 if ((err = zonecfg_get_detach_info(local_handle, B_FALSE)) != Z_OK) { 4040 errno = err; 4041 zperror(gettext("getting the attach information failed"), 4042 B_TRUE); 4043 res = Z_ERR; 4044 } else { 4045 /* sw_cmp prints error msgs as necessary */ 4046 if (sw_cmp(local_handle, rem_handle, SW_CMP_NONE) != Z_OK) 4047 res = Z_ERR; 4048 } 4049 4050 done: 4051 if (strcmp(manifest_path, "-") != 0) 4052 (void) close(fd); 4053 4054 zonecfg_fini_handle(local_handle); 4055 zonecfg_fini_handle(rem_handle); 4056 4057 return ((res == Z_OK) ? Z_OK : Z_ERR); 4058 } 4059 4060 static int 4061 attach_func(int argc, char *argv[]) 4062 { 4063 int lockfd; 4064 int err, arg; 4065 boolean_t force = B_FALSE; 4066 zone_dochandle_t handle; 4067 zone_dochandle_t athandle = NULL; 4068 char zonepath[MAXPATHLEN]; 4069 boolean_t execute = B_TRUE; 4070 char *manifest_path; 4071 4072 if (zonecfg_in_alt_root()) { 4073 zerror(gettext("cannot attach zone in alternate root")); 4074 return (Z_ERR); 4075 } 4076 4077 optind = 0; 4078 if ((arg = getopt(argc, argv, "?Fn:")) != EOF) { 4079 switch (arg) { 4080 case '?': 4081 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4082 return (optopt == '?' ? Z_OK : Z_USAGE); 4083 case 'F': 4084 force = B_TRUE; 4085 break; 4086 case 'n': 4087 execute = B_FALSE; 4088 manifest_path = optarg; 4089 break; 4090 default: 4091 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4092 return (Z_USAGE); 4093 } 4094 } 4095 4096 /* 4097 * If the no-execute option was specified, we need to branch down 4098 * a completely different path since there is no zone required to be 4099 * configured for this option. 4100 */ 4101 if (!execute) 4102 return (dryrun_attach(manifest_path)); 4103 4104 if (sanity_check(target_zone, CMD_ATTACH, B_FALSE, B_TRUE) != Z_OK) 4105 return (Z_ERR); 4106 if (verify_details(CMD_ATTACH) != Z_OK) 4107 return (Z_ERR); 4108 4109 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 4110 != Z_OK) { 4111 errno = err; 4112 zperror2(target_zone, gettext("could not get zone path")); 4113 return (Z_ERR); 4114 } 4115 4116 if ((handle = zonecfg_init_handle()) == NULL) { 4117 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4118 return (Z_ERR); 4119 } 4120 4121 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 4122 errno = err; 4123 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4124 zonecfg_fini_handle(handle); 4125 return (Z_ERR); 4126 } 4127 4128 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4129 zerror(gettext("another %s may have an operation in progress."), 4130 "zoneadm"); 4131 zonecfg_fini_handle(handle); 4132 return (Z_ERR); 4133 } 4134 4135 if (force) 4136 goto forced; 4137 4138 if ((athandle = zonecfg_init_handle()) == NULL) { 4139 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4140 goto done; 4141 } 4142 4143 if ((err = zonecfg_get_attach_handle(zonepath, target_zone, B_TRUE, 4144 athandle)) != Z_OK) { 4145 if (err == Z_NO_ZONE) 4146 zerror(gettext("Not a detached zone")); 4147 else if (err == Z_INVALID_DOCUMENT) 4148 zerror(gettext("Cannot attach to an earlier release " 4149 "of the operating system")); 4150 else 4151 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4152 goto done; 4153 } 4154 4155 /* Get the detach information for the locally defined zone. */ 4156 if ((err = zonecfg_get_detach_info(handle, B_FALSE)) != Z_OK) { 4157 errno = err; 4158 zperror(gettext("getting the attach information failed"), 4159 B_TRUE); 4160 goto done; 4161 } 4162 4163 /* sw_cmp prints error msgs as necessary */ 4164 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) 4165 goto done; 4166 4167 if ((err = dev_fix(athandle)) != Z_OK) 4168 goto done; 4169 4170 forced: 4171 4172 zonecfg_rm_detached(handle, force); 4173 4174 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 4175 errno = err; 4176 zperror(gettext("could not reset state"), B_TRUE); 4177 } 4178 4179 done: 4180 zonecfg_fini_handle(handle); 4181 release_lock_file(lockfd); 4182 if (athandle != NULL) 4183 zonecfg_fini_handle(athandle); 4184 4185 return ((err == Z_OK) ? Z_OK : Z_ERR); 4186 } 4187 4188 /* 4189 * On input, TRUE => yes, FALSE => no. 4190 * On return, TRUE => 1, FALSE => 0, could not ask => -1. 4191 */ 4192 4193 static int 4194 ask_yesno(boolean_t default_answer, const char *question) 4195 { 4196 char line[64]; /* should be large enough to answer yes or no */ 4197 4198 if (!isatty(STDIN_FILENO)) 4199 return (-1); 4200 for (;;) { 4201 (void) printf("%s (%s)? ", question, 4202 default_answer ? "[y]/n" : "y/[n]"); 4203 if (fgets(line, sizeof (line), stdin) == NULL || 4204 line[0] == '\n') 4205 return (default_answer ? 1 : 0); 4206 if (tolower(line[0]) == 'y') 4207 return (1); 4208 if (tolower(line[0]) == 'n') 4209 return (0); 4210 } 4211 } 4212 4213 static int 4214 uninstall_func(int argc, char *argv[]) 4215 { 4216 char line[ZONENAME_MAX + 128]; /* Enough for "Are you sure ..." */ 4217 char rootpath[MAXPATHLEN], zonepath[MAXPATHLEN]; 4218 boolean_t force = B_FALSE; 4219 int lockfd, answer; 4220 int err, arg; 4221 4222 if (zonecfg_in_alt_root()) { 4223 zerror(gettext("cannot uninstall zone in alternate root")); 4224 return (Z_ERR); 4225 } 4226 4227 optind = 0; 4228 while ((arg = getopt(argc, argv, "?F")) != EOF) { 4229 switch (arg) { 4230 case '?': 4231 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4232 return (optopt == '?' ? Z_OK : Z_USAGE); 4233 case 'F': 4234 force = B_TRUE; 4235 break; 4236 default: 4237 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4238 return (Z_USAGE); 4239 } 4240 } 4241 if (argc > optind) { 4242 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4243 return (Z_USAGE); 4244 } 4245 4246 if (sanity_check(target_zone, CMD_UNINSTALL, B_FALSE, B_TRUE) != Z_OK) 4247 return (Z_ERR); 4248 4249 if (!force) { 4250 (void) snprintf(line, sizeof (line), 4251 gettext("Are you sure you want to %s zone %s"), 4252 cmd_to_str(CMD_UNINSTALL), target_zone); 4253 if ((answer = ask_yesno(B_FALSE, line)) == 0) { 4254 return (Z_OK); 4255 } else if (answer == -1) { 4256 zerror(gettext("Input not from terminal and -F " 4257 "not specified: %s not done."), 4258 cmd_to_str(CMD_UNINSTALL)); 4259 return (Z_ERR); 4260 } 4261 } 4262 4263 if ((err = zone_get_zonepath(target_zone, zonepath, 4264 sizeof (zonepath))) != Z_OK) { 4265 errno = err; 4266 zperror2(target_zone, gettext("could not get zone path")); 4267 return (Z_ERR); 4268 } 4269 if ((err = zone_get_rootpath(target_zone, rootpath, 4270 sizeof (rootpath))) != Z_OK) { 4271 errno = err; 4272 zperror2(target_zone, gettext("could not get root path")); 4273 return (Z_ERR); 4274 } 4275 4276 /* 4277 * If there seems to be a zoneadmd running for this zone, call it 4278 * to tell it that an uninstall is happening; if all goes well it 4279 * will then shut itself down. 4280 */ 4281 if (ping_zoneadmd(target_zone) == Z_OK) { 4282 zone_cmd_arg_t zarg; 4283 zarg.cmd = Z_NOTE_UNINSTALLING; 4284 /* we don't care too much if this fails... just plow on */ 4285 (void) call_zoneadmd(target_zone, &zarg); 4286 } 4287 4288 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4289 zerror(gettext("another %s may have an operation in progress."), 4290 "zoneadm"); 4291 return (Z_ERR); 4292 } 4293 4294 /* Don't uninstall the zone if anything is mounted there */ 4295 err = zonecfg_find_mounts(rootpath, NULL, NULL); 4296 if (err) { 4297 zerror(gettext("These file systems are mounted on " 4298 "subdirectories of %s.\n"), rootpath); 4299 (void) zonecfg_find_mounts(rootpath, zfm_print, NULL); 4300 return (Z_ERR); 4301 } 4302 4303 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4304 if (err != Z_OK) { 4305 errno = err; 4306 zperror2(target_zone, gettext("could not set state")); 4307 goto bad; 4308 } 4309 4310 if ((err = cleanup_zonepath(zonepath, B_FALSE)) != Z_OK) { 4311 errno = err; 4312 zperror2(target_zone, gettext("cleaning up zonepath failed")); 4313 goto bad; 4314 } 4315 4316 err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4317 if (err != Z_OK) { 4318 errno = err; 4319 zperror2(target_zone, gettext("could not reset state")); 4320 } 4321 bad: 4322 release_lock_file(lockfd); 4323 return (err); 4324 } 4325 4326 /* ARGSUSED */ 4327 static int 4328 mount_func(int argc, char *argv[]) 4329 { 4330 zone_cmd_arg_t zarg; 4331 4332 if (argc > 0) 4333 return (Z_USAGE); 4334 if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE) != Z_OK) 4335 return (Z_ERR); 4336 if (verify_details(CMD_MOUNT) != Z_OK) 4337 return (Z_ERR); 4338 4339 zarg.cmd = Z_MOUNT; 4340 if (call_zoneadmd(target_zone, &zarg) != 0) { 4341 zerror(gettext("call to %s failed"), "zoneadmd"); 4342 return (Z_ERR); 4343 } 4344 return (Z_OK); 4345 } 4346 4347 /* ARGSUSED */ 4348 static int 4349 unmount_func(int argc, char *argv[]) 4350 { 4351 zone_cmd_arg_t zarg; 4352 4353 if (argc > 0) 4354 return (Z_USAGE); 4355 if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE) != Z_OK) 4356 return (Z_ERR); 4357 4358 zarg.cmd = Z_UNMOUNT; 4359 if (call_zoneadmd(target_zone, &zarg) != 0) { 4360 zerror(gettext("call to %s failed"), "zoneadmd"); 4361 return (Z_ERR); 4362 } 4363 return (Z_OK); 4364 } 4365 4366 static int 4367 help_func(int argc, char *argv[]) 4368 { 4369 int arg, cmd_num; 4370 4371 if (argc == 0) { 4372 (void) usage(B_TRUE); 4373 return (Z_OK); 4374 } 4375 optind = 0; 4376 if ((arg = getopt(argc, argv, "?")) != EOF) { 4377 switch (arg) { 4378 case '?': 4379 sub_usage(SHELP_HELP, CMD_HELP); 4380 return (optopt == '?' ? Z_OK : Z_USAGE); 4381 default: 4382 sub_usage(SHELP_HELP, CMD_HELP); 4383 return (Z_USAGE); 4384 } 4385 } 4386 while (optind < argc) { 4387 /* Private commands have NULL short_usage; omit them */ 4388 if ((cmd_num = cmd_match(argv[optind])) < 0 || 4389 cmdtab[cmd_num].short_usage == NULL) { 4390 sub_usage(SHELP_HELP, CMD_HELP); 4391 return (Z_USAGE); 4392 } 4393 sub_usage(cmdtab[cmd_num].short_usage, cmd_num); 4394 optind++; 4395 } 4396 return (Z_OK); 4397 } 4398 4399 /* 4400 * Returns: CMD_MIN thru CMD_MAX on success, -1 on error 4401 */ 4402 4403 static int 4404 cmd_match(char *cmd) 4405 { 4406 int i; 4407 4408 for (i = CMD_MIN; i <= CMD_MAX; i++) { 4409 /* return only if there is an exact match */ 4410 if (strcmp(cmd, cmdtab[i].cmd_name) == 0) 4411 return (cmdtab[i].cmd_num); 4412 } 4413 return (-1); 4414 } 4415 4416 static int 4417 parse_and_run(int argc, char *argv[]) 4418 { 4419 int i = cmd_match(argv[0]); 4420 4421 if (i < 0) 4422 return (usage(B_FALSE)); 4423 return (cmdtab[i].handler(argc - 1, &(argv[1]))); 4424 } 4425 4426 static char * 4427 get_execbasename(char *execfullname) 4428 { 4429 char *last_slash, *execbasename; 4430 4431 /* guard against '/' at end of command invocation */ 4432 for (;;) { 4433 last_slash = strrchr(execfullname, '/'); 4434 if (last_slash == NULL) { 4435 execbasename = execfullname; 4436 break; 4437 } else { 4438 execbasename = last_slash + 1; 4439 if (*execbasename == '\0') { 4440 *last_slash = '\0'; 4441 continue; 4442 } 4443 break; 4444 } 4445 } 4446 return (execbasename); 4447 } 4448 4449 int 4450 main(int argc, char **argv) 4451 { 4452 int arg; 4453 zoneid_t zid; 4454 struct stat st; 4455 4456 if ((locale = setlocale(LC_ALL, "")) == NULL) 4457 locale = "C"; 4458 (void) textdomain(TEXT_DOMAIN); 4459 setbuf(stdout, NULL); 4460 (void) sigset(SIGHUP, SIG_IGN); 4461 execname = get_execbasename(argv[0]); 4462 target_zone = NULL; 4463 if (chdir("/") != 0) { 4464 zerror(gettext("could not change directory to /.")); 4465 exit(Z_ERR); 4466 } 4467 4468 if (init_zfs() != Z_OK) 4469 exit(Z_ERR); 4470 4471 while ((arg = getopt(argc, argv, "?z:R:")) != EOF) { 4472 switch (arg) { 4473 case '?': 4474 return (usage(B_TRUE)); 4475 case 'z': 4476 target_zone = optarg; 4477 break; 4478 case 'R': /* private option for admin/install use */ 4479 if (*optarg != '/') { 4480 zerror(gettext("root path must be absolute.")); 4481 exit(Z_ERR); 4482 } 4483 if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { 4484 zerror( 4485 gettext("root path must be a directory.")); 4486 exit(Z_ERR); 4487 } 4488 zonecfg_set_root(optarg); 4489 break; 4490 default: 4491 return (usage(B_FALSE)); 4492 } 4493 } 4494 4495 if (optind >= argc) 4496 return (usage(B_FALSE)); 4497 if (target_zone != NULL && zone_get_id(target_zone, &zid) != 0) { 4498 errno = Z_NO_ZONE; 4499 zperror(target_zone, B_TRUE); 4500 exit(Z_ERR); 4501 } 4502 return (parse_and_run(argc - optind, &argv[optind])); 4503 } 4504