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