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 /* 2507 * The interface failed to come up. We continue on 2508 * anyway for the sake of consistency: a zone is not 2509 * shut down if the interface fails any time after 2510 * boot, nor does the global zone fail to boot if an 2511 * interface fails. 2512 */ 2513 (void) fprintf(stderr, 2514 gettext("WARNING: skipping interface '%s' which " 2515 "may not be present/plumbed in the global zone.\n"), 2516 nwiftab.zone_nwif_physical); 2517 2518 } 2519 (void) close(so); 2520 } 2521 (void) zonecfg_endnwifent(handle); 2522 no_net: 2523 2524 /* verify that lofs has not been excluded from the kernel */ 2525 if (!(cmd_num == CMD_DETACH || cmd_num == CMD_ATTACH || 2526 cmd_num == CMD_MOVE || cmd_num == CMD_CLONE) && 2527 modctl(MODLOAD, 1, "fs/lofs", NULL) != 0) { 2528 if (errno == ENXIO) 2529 (void) fprintf(stderr, gettext("could not verify " 2530 "lofs(7FS): possibly excluded in /etc/system\n")); 2531 else 2532 (void) fprintf(stderr, gettext("could not verify " 2533 "lofs(7FS): %s\n"), strerror(errno)); 2534 return_code = Z_ERR; 2535 } 2536 2537 if (verify_filesystems(handle) != Z_OK) 2538 return_code = Z_ERR; 2539 if (verify_ipd(handle) != Z_OK) 2540 return_code = Z_ERR; 2541 if (!in_alt_root && verify_rctls(handle) != Z_OK) 2542 return_code = Z_ERR; 2543 if (!in_alt_root && verify_pool(handle) != Z_OK) 2544 return_code = Z_ERR; 2545 if (!in_alt_root && verify_datasets(handle) != Z_OK) 2546 return_code = Z_ERR; 2547 2548 /* 2549 * As the "mount" command is used for patching/upgrading of zones 2550 * or other maintenance processes, the zone's privilege set is not 2551 * checked in this case. Instead, the default, safe set of 2552 * privileges will be used when this zone is created in the 2553 * kernel. 2554 */ 2555 if (!in_alt_root && cmd_num != CMD_MOUNT && 2556 verify_limitpriv(handle) != Z_OK) 2557 return_code = Z_ERR; 2558 2559 return (return_code); 2560 } 2561 2562 static int 2563 verify_details(int cmd_num) 2564 { 2565 zone_dochandle_t handle; 2566 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN]; 2567 int return_code = Z_OK; 2568 int err; 2569 2570 if ((handle = zonecfg_init_handle()) == NULL) { 2571 zperror(cmd_to_str(cmd_num), B_TRUE); 2572 return (Z_ERR); 2573 } 2574 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 2575 errno = err; 2576 zperror(cmd_to_str(cmd_num), B_TRUE); 2577 zonecfg_fini_handle(handle); 2578 return (Z_ERR); 2579 } 2580 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) != 2581 Z_OK) { 2582 errno = err; 2583 zperror(cmd_to_str(cmd_num), B_TRUE); 2584 zonecfg_fini_handle(handle); 2585 return (Z_ERR); 2586 } 2587 /* 2588 * zonecfg_get_zonepath() gets its data from the XML repository. 2589 * Verify this against the index file, which is checked first by 2590 * zone_get_zonepath(). If they don't match, bail out. 2591 */ 2592 if ((err = zone_get_zonepath(target_zone, checkpath, 2593 sizeof (checkpath))) != Z_OK) { 2594 errno = err; 2595 zperror2(target_zone, gettext("could not get zone path")); 2596 return (Z_ERR); 2597 } 2598 if (strcmp(zonepath, checkpath) != 0) { 2599 /* 2600 * TRANSLATION_NOTE 2601 * XML and zonepath are literals that should not be translated. 2602 */ 2603 (void) fprintf(stderr, gettext("The XML repository has " 2604 "zonepath '%s',\nbut the index file has zonepath '%s'.\n" 2605 "These must match, so fix the incorrect entry.\n"), 2606 zonepath, checkpath); 2607 return (Z_ERR); 2608 } 2609 if (validate_zonepath(zonepath, cmd_num) != Z_OK) { 2610 (void) fprintf(stderr, gettext("could not verify zonepath %s " 2611 "because of the above errors.\n"), zonepath); 2612 return_code = Z_ERR; 2613 } 2614 2615 if (verify_handle(cmd_num, handle) != Z_OK) 2616 return_code = Z_ERR; 2617 2618 zonecfg_fini_handle(handle); 2619 if (return_code == Z_ERR) 2620 (void) fprintf(stderr, 2621 gettext("%s: zone %s failed to verify\n"), 2622 execname, target_zone); 2623 return (return_code); 2624 } 2625 2626 static int 2627 verify_func(int argc, char *argv[]) 2628 { 2629 int arg; 2630 2631 optind = 0; 2632 if ((arg = getopt(argc, argv, "?")) != EOF) { 2633 switch (arg) { 2634 case '?': 2635 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2636 return (optopt == '?' ? Z_OK : Z_USAGE); 2637 default: 2638 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2639 return (Z_USAGE); 2640 } 2641 } 2642 if (argc > optind) { 2643 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2644 return (Z_USAGE); 2645 } 2646 if (sanity_check(target_zone, CMD_VERIFY, B_FALSE, B_FALSE) != Z_OK) 2647 return (Z_ERR); 2648 return (verify_details(CMD_VERIFY)); 2649 } 2650 2651 #define LUCREATEZONE "/usr/lib/lu/lucreatezone" 2652 2653 static int 2654 install_func(int argc, char *argv[]) 2655 { 2656 /* 9: "exec " and " -z " */ 2657 char cmdbuf[sizeof (LUCREATEZONE) + ZONENAME_MAX + 9]; 2658 int lockfd; 2659 int err, arg; 2660 char zonepath[MAXPATHLEN]; 2661 int status; 2662 boolean_t nodataset = B_FALSE; 2663 2664 if (zonecfg_in_alt_root()) { 2665 zerror(gettext("cannot install zone in alternate root")); 2666 return (Z_ERR); 2667 } 2668 2669 optind = 0; 2670 if ((arg = getopt(argc, argv, "?x:")) != EOF) { 2671 switch (arg) { 2672 case '?': 2673 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2674 return (optopt == '?' ? Z_OK : Z_USAGE); 2675 case 'x': 2676 if (strcmp(optarg, "nodataset") != 0) { 2677 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2678 return (Z_USAGE); 2679 } 2680 nodataset = B_TRUE; 2681 break; 2682 default: 2683 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2684 return (Z_USAGE); 2685 } 2686 } 2687 if (argc > optind) { 2688 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2689 return (Z_USAGE); 2690 } 2691 if (sanity_check(target_zone, CMD_INSTALL, B_FALSE, B_TRUE) != Z_OK) 2692 return (Z_ERR); 2693 if (verify_details(CMD_INSTALL) != Z_OK) 2694 return (Z_ERR); 2695 2696 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 2697 zerror(gettext("another %s may have an operation in progress."), 2698 "zoneadm"); 2699 return (Z_ERR); 2700 } 2701 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 2702 if (err != Z_OK) { 2703 errno = err; 2704 zperror2(target_zone, gettext("could not set state")); 2705 goto done; 2706 } 2707 2708 /* 2709 * According to the Application Packaging Developer's Guide, a 2710 * "checkinstall" script when included in a package is executed as 2711 * the user "install", if such a user exists, or by the user 2712 * "nobody". In order to support this dubious behavior, the path 2713 * to the zone being constructed is opened up during the life of 2714 * the command laying down the zone's root file system. Once this 2715 * has completed, regardless of whether it was successful, the 2716 * path to the zone is again restricted. 2717 */ 2718 if ((err = zone_get_zonepath(target_zone, zonepath, 2719 sizeof (zonepath))) != Z_OK) { 2720 errno = err; 2721 zperror2(target_zone, gettext("could not get zone path")); 2722 goto done; 2723 } 2724 2725 if (!nodataset) 2726 create_zfs_zonepath(zonepath); 2727 2728 if (chmod(zonepath, DEFAULT_DIR_MODE) != 0) { 2729 zperror(zonepath, B_FALSE); 2730 err = Z_ERR; 2731 goto done; 2732 } 2733 2734 /* 2735 * "exec" the command so that the returned status is that of 2736 * LUCREATEZONE and not the shell. 2737 */ 2738 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " LUCREATEZONE " -z %s", 2739 target_zone); 2740 status = do_subproc(cmdbuf); 2741 if (chmod(zonepath, S_IRWXU) != 0) { 2742 zperror(zonepath, B_FALSE); 2743 err = Z_ERR; 2744 goto done; 2745 } 2746 if ((err = subproc_status(LUCREATEZONE, status)) != Z_OK) 2747 goto done; 2748 2749 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 2750 errno = err; 2751 zperror2(target_zone, gettext("could not set state")); 2752 goto done; 2753 } 2754 2755 done: 2756 release_lock_file(lockfd); 2757 return ((err == Z_OK) ? Z_OK : Z_ERR); 2758 } 2759 2760 /* 2761 * Check that the inherited pkg dirs are the same for the clone and its source. 2762 * The easiest way to do that is check that the list of ipds is the same 2763 * by matching each one against the other. This algorithm should be fine since 2764 * the list of ipds should not be that long. 2765 */ 2766 static int 2767 valid_ipd_clone(zone_dochandle_t s_handle, char *source_zone, 2768 zone_dochandle_t t_handle, char *target_zone) 2769 { 2770 int err; 2771 int res = Z_OK; 2772 int s_cnt = 0; 2773 int t_cnt = 0; 2774 struct zone_fstab s_fstab; 2775 struct zone_fstab t_fstab; 2776 2777 /* 2778 * First check the source of the clone against the target. 2779 */ 2780 if ((err = zonecfg_setipdent(s_handle)) != Z_OK) { 2781 errno = err; 2782 zperror2(source_zone, gettext("could not enumerate " 2783 "inherit-pkg-dirs")); 2784 return (Z_ERR); 2785 } 2786 2787 while (zonecfg_getipdent(s_handle, &s_fstab) == Z_OK) { 2788 boolean_t match = B_FALSE; 2789 2790 s_cnt++; 2791 2792 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 2793 errno = err; 2794 zperror2(target_zone, gettext("could not enumerate " 2795 "inherit-pkg-dirs")); 2796 (void) zonecfg_endipdent(s_handle); 2797 return (Z_ERR); 2798 } 2799 2800 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) { 2801 if (strcmp(s_fstab.zone_fs_dir, t_fstab.zone_fs_dir) 2802 == 0) { 2803 match = B_TRUE; 2804 break; 2805 } 2806 } 2807 (void) zonecfg_endipdent(t_handle); 2808 2809 if (!match) { 2810 (void) fprintf(stderr, gettext("inherit-pkg-dir " 2811 "'%s' is not configured in zone %s.\n"), 2812 s_fstab.zone_fs_dir, target_zone); 2813 res = Z_ERR; 2814 } 2815 } 2816 2817 (void) zonecfg_endipdent(s_handle); 2818 2819 /* skip the next check if we already have errors */ 2820 if (res == Z_ERR) 2821 return (res); 2822 2823 /* 2824 * Now check the number of ipds in the target so we can verify 2825 * that the source is not a subset of the target. 2826 */ 2827 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 2828 errno = err; 2829 zperror2(target_zone, gettext("could not enumerate " 2830 "inherit-pkg-dirs")); 2831 return (Z_ERR); 2832 } 2833 2834 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) 2835 t_cnt++; 2836 2837 (void) zonecfg_endipdent(t_handle); 2838 2839 if (t_cnt != s_cnt) { 2840 (void) fprintf(stderr, gettext("Zone %s is configured " 2841 "with inherit-pkg-dirs that are not configured in zone " 2842 "%s.\n"), target_zone, source_zone); 2843 res = Z_ERR; 2844 } 2845 2846 return (res); 2847 } 2848 2849 static void 2850 warn_dev_match(zone_dochandle_t s_handle, char *source_zone, 2851 zone_dochandle_t t_handle, char *target_zone) 2852 { 2853 int err; 2854 struct zone_devtab s_devtab; 2855 struct zone_devtab t_devtab; 2856 2857 if ((err = zonecfg_setdevent(t_handle)) != Z_OK) { 2858 errno = err; 2859 zperror2(target_zone, gettext("could not enumerate devices")); 2860 return; 2861 } 2862 2863 while (zonecfg_getdevent(t_handle, &t_devtab) == Z_OK) { 2864 if ((err = zonecfg_setdevent(s_handle)) != Z_OK) { 2865 errno = err; 2866 zperror2(source_zone, 2867 gettext("could not enumerate devices")); 2868 (void) zonecfg_enddevent(t_handle); 2869 return; 2870 } 2871 2872 while (zonecfg_getdevent(s_handle, &s_devtab) == Z_OK) { 2873 /* 2874 * Use fnmatch to catch the case where wildcards 2875 * were used in one zone and the other has an 2876 * explicit entry (e.g. /dev/dsk/c0t0d0s6 vs. 2877 * /dev/\*dsk/c0t0d0s6). 2878 */ 2879 if (fnmatch(t_devtab.zone_dev_match, 2880 s_devtab.zone_dev_match, FNM_PATHNAME) == 0 || 2881 fnmatch(s_devtab.zone_dev_match, 2882 t_devtab.zone_dev_match, FNM_PATHNAME) == 0) { 2883 (void) fprintf(stderr, 2884 gettext("WARNING: device '%s' " 2885 "is configured in both zones.\n"), 2886 t_devtab.zone_dev_match); 2887 break; 2888 } 2889 } 2890 (void) zonecfg_enddevent(s_handle); 2891 } 2892 2893 (void) zonecfg_enddevent(t_handle); 2894 } 2895 2896 /* 2897 * Check if the specified mount option (opt) is contained within the 2898 * options string. 2899 */ 2900 static boolean_t 2901 opt_match(char *opt, char *options) 2902 { 2903 char *p; 2904 char *lastp; 2905 2906 if ((p = strtok_r(options, ",", &lastp)) != NULL) { 2907 if (strcmp(p, opt) == 0) 2908 return (B_TRUE); 2909 while ((p = strtok_r(NULL, ",", &lastp)) != NULL) { 2910 if (strcmp(p, opt) == 0) 2911 return (B_TRUE); 2912 } 2913 } 2914 2915 return (B_FALSE); 2916 } 2917 2918 #define RW_LOFS "WARNING: read-write lofs file system on '%s' is configured " \ 2919 "in both zones.\n" 2920 2921 static void 2922 print_fs_warnings(struct zone_fstab *s_fstab, struct zone_fstab *t_fstab) 2923 { 2924 /* 2925 * It is ok to have shared lofs mounted fs but we want to warn if 2926 * either is rw since this will effect the other zone. 2927 */ 2928 if (strcmp(t_fstab->zone_fs_type, "lofs") == 0) { 2929 zone_fsopt_t *optp; 2930 2931 /* The default is rw so no options means rw */ 2932 if (t_fstab->zone_fs_options == NULL || 2933 s_fstab->zone_fs_options == NULL) { 2934 (void) fprintf(stderr, gettext(RW_LOFS), 2935 t_fstab->zone_fs_special); 2936 return; 2937 } 2938 2939 for (optp = s_fstab->zone_fs_options; optp != NULL; 2940 optp = optp->zone_fsopt_next) { 2941 if (opt_match("rw", optp->zone_fsopt_opt)) { 2942 (void) fprintf(stderr, gettext(RW_LOFS), 2943 s_fstab->zone_fs_special); 2944 return; 2945 } 2946 } 2947 2948 for (optp = t_fstab->zone_fs_options; optp != NULL; 2949 optp = optp->zone_fsopt_next) { 2950 if (opt_match("rw", optp->zone_fsopt_opt)) { 2951 (void) fprintf(stderr, gettext(RW_LOFS), 2952 t_fstab->zone_fs_special); 2953 return; 2954 } 2955 } 2956 2957 return; 2958 } 2959 2960 /* 2961 * TRANSLATION_NOTE 2962 * The first variable is the file system type and the second is 2963 * the file system special device. For example, 2964 * WARNING: ufs file system on '/dev/dsk/c0t0d0s0' ... 2965 */ 2966 (void) fprintf(stderr, gettext("WARNING: %s file system on '%s' " 2967 "is configured in both zones.\n"), t_fstab->zone_fs_type, 2968 t_fstab->zone_fs_special); 2969 } 2970 2971 static void 2972 warn_fs_match(zone_dochandle_t s_handle, char *source_zone, 2973 zone_dochandle_t t_handle, char *target_zone) 2974 { 2975 int err; 2976 struct zone_fstab s_fstab; 2977 struct zone_fstab t_fstab; 2978 2979 if ((err = zonecfg_setfsent(t_handle)) != Z_OK) { 2980 errno = err; 2981 zperror2(target_zone, 2982 gettext("could not enumerate file systems")); 2983 return; 2984 } 2985 2986 while (zonecfg_getfsent(t_handle, &t_fstab) == Z_OK) { 2987 if ((err = zonecfg_setfsent(s_handle)) != Z_OK) { 2988 errno = err; 2989 zperror2(source_zone, 2990 gettext("could not enumerate file systems")); 2991 (void) zonecfg_endfsent(t_handle); 2992 return; 2993 } 2994 2995 while (zonecfg_getfsent(s_handle, &s_fstab) == Z_OK) { 2996 if (strcmp(t_fstab.zone_fs_special, 2997 s_fstab.zone_fs_special) == 0) { 2998 print_fs_warnings(&s_fstab, &t_fstab); 2999 break; 3000 } 3001 } 3002 (void) zonecfg_endfsent(s_handle); 3003 } 3004 3005 (void) zonecfg_endfsent(t_handle); 3006 } 3007 3008 /* 3009 * We don't catch the case where you used the same IP address but 3010 * it is not an exact string match. For example, 192.9.0.128 vs. 192.09.0.128. 3011 * However, we're not going to worry about that but we will check for 3012 * a possible netmask on one of the addresses (e.g. 10.0.0.1 and 10.0.0.1/24) 3013 * and handle that case as a match. 3014 */ 3015 static void 3016 warn_ip_match(zone_dochandle_t s_handle, char *source_zone, 3017 zone_dochandle_t t_handle, char *target_zone) 3018 { 3019 int err; 3020 struct zone_nwiftab s_nwiftab; 3021 struct zone_nwiftab t_nwiftab; 3022 3023 if ((err = zonecfg_setnwifent(t_handle)) != Z_OK) { 3024 errno = err; 3025 zperror2(target_zone, 3026 gettext("could not enumerate network interfaces")); 3027 return; 3028 } 3029 3030 while (zonecfg_getnwifent(t_handle, &t_nwiftab) == Z_OK) { 3031 char *p; 3032 3033 /* remove an (optional) netmask from the address */ 3034 if ((p = strchr(t_nwiftab.zone_nwif_address, '/')) != NULL) 3035 *p = '\0'; 3036 3037 if ((err = zonecfg_setnwifent(s_handle)) != Z_OK) { 3038 errno = err; 3039 zperror2(source_zone, 3040 gettext("could not enumerate network interfaces")); 3041 (void) zonecfg_endnwifent(t_handle); 3042 return; 3043 } 3044 3045 while (zonecfg_getnwifent(s_handle, &s_nwiftab) == Z_OK) { 3046 /* remove an (optional) netmask from the address */ 3047 if ((p = strchr(s_nwiftab.zone_nwif_address, '/')) 3048 != NULL) 3049 *p = '\0'; 3050 3051 if (strcmp(t_nwiftab.zone_nwif_address, 3052 s_nwiftab.zone_nwif_address) == 0) { 3053 (void) fprintf(stderr, 3054 gettext("WARNING: network address '%s' " 3055 "is configured in both zones.\n"), 3056 t_nwiftab.zone_nwif_address); 3057 break; 3058 } 3059 } 3060 (void) zonecfg_endnwifent(s_handle); 3061 } 3062 3063 (void) zonecfg_endnwifent(t_handle); 3064 } 3065 3066 static void 3067 warn_dataset_match(zone_dochandle_t s_handle, char *source_zone, 3068 zone_dochandle_t t_handle, char *target_zone) 3069 { 3070 int err; 3071 struct zone_dstab s_dstab; 3072 struct zone_dstab t_dstab; 3073 3074 if ((err = zonecfg_setdsent(t_handle)) != Z_OK) { 3075 errno = err; 3076 zperror2(target_zone, gettext("could not enumerate datasets")); 3077 return; 3078 } 3079 3080 while (zonecfg_getdsent(t_handle, &t_dstab) == Z_OK) { 3081 if ((err = zonecfg_setdsent(s_handle)) != Z_OK) { 3082 errno = err; 3083 zperror2(source_zone, 3084 gettext("could not enumerate datasets")); 3085 (void) zonecfg_enddsent(t_handle); 3086 return; 3087 } 3088 3089 while (zonecfg_getdsent(s_handle, &s_dstab) == Z_OK) { 3090 if (strcmp(t_dstab.zone_dataset_name, 3091 s_dstab.zone_dataset_name) == 0) { 3092 (void) fprintf(stderr, 3093 gettext("WARNING: dataset '%s' " 3094 "is configured in both zones.\n"), 3095 t_dstab.zone_dataset_name); 3096 break; 3097 } 3098 } 3099 (void) zonecfg_enddsent(s_handle); 3100 } 3101 3102 (void) zonecfg_enddsent(t_handle); 3103 } 3104 3105 static int 3106 validate_clone(char *source_zone, char *target_zone) 3107 { 3108 int err = Z_OK; 3109 zone_dochandle_t s_handle; 3110 zone_dochandle_t t_handle; 3111 3112 if ((t_handle = zonecfg_init_handle()) == NULL) { 3113 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3114 return (Z_ERR); 3115 } 3116 if ((err = zonecfg_get_handle(target_zone, t_handle)) != Z_OK) { 3117 errno = err; 3118 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3119 zonecfg_fini_handle(t_handle); 3120 return (Z_ERR); 3121 } 3122 3123 if ((s_handle = zonecfg_init_handle()) == NULL) { 3124 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3125 zonecfg_fini_handle(t_handle); 3126 return (Z_ERR); 3127 } 3128 if ((err = zonecfg_get_handle(source_zone, s_handle)) != Z_OK) { 3129 errno = err; 3130 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3131 goto done; 3132 } 3133 3134 /* verify new zone has same inherit-pkg-dirs */ 3135 err = valid_ipd_clone(s_handle, source_zone, t_handle, target_zone); 3136 3137 /* warn about imported fs's which are the same */ 3138 warn_fs_match(s_handle, source_zone, t_handle, target_zone); 3139 3140 /* warn about imported IP addresses which are the same */ 3141 warn_ip_match(s_handle, source_zone, t_handle, target_zone); 3142 3143 /* warn about imported devices which are the same */ 3144 warn_dev_match(s_handle, source_zone, t_handle, target_zone); 3145 3146 /* warn about imported datasets which are the same */ 3147 warn_dataset_match(s_handle, source_zone, t_handle, target_zone); 3148 3149 done: 3150 zonecfg_fini_handle(t_handle); 3151 zonecfg_fini_handle(s_handle); 3152 3153 return ((err == Z_OK) ? Z_OK : Z_ERR); 3154 } 3155 3156 static int 3157 copy_zone(char *src, char *dst) 3158 { 3159 boolean_t out_null = B_FALSE; 3160 int status; 3161 int err; 3162 char *outfile; 3163 char cmdbuf[MAXPATHLEN * 2 + 128]; 3164 3165 if ((outfile = tempnam("/var/log", "zone")) == NULL) { 3166 outfile = "/dev/null"; 3167 out_null = B_TRUE; 3168 } 3169 3170 /* 3171 * Use find to get the list of files to copy. We need to skip 3172 * files of type "socket" since cpio can't handle those but that 3173 * should be ok since the app will recreate the socket when it runs. 3174 * We also need to filter out anything under the .zfs subdir. Since 3175 * find is running depth-first, we need the extra egrep to filter .zfs. 3176 */ 3177 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3178 "cd %s && /usr/bin/find . -type s -prune -o -depth -print | " 3179 "/usr/bin/egrep -v '^\\./\\.zfs$|^\\./\\.zfs/' | " 3180 "/usr/bin/cpio -pdmuP@ %s > %s 2>&1", 3181 src, dst, outfile); 3182 3183 status = do_subproc(cmdbuf); 3184 3185 if ((err = subproc_status("copy", status)) != Z_OK) { 3186 if (!out_null) 3187 (void) fprintf(stderr, gettext("\nThe copy failed.\n" 3188 "More information can be found in %s\n"), outfile); 3189 return (err); 3190 } 3191 3192 if (!out_null) 3193 (void) unlink(outfile); 3194 3195 return (Z_OK); 3196 } 3197 3198 /* 3199 * Run sys-unconfig on a zone. This will leave the zone in the installed 3200 * state as long as there were no errors during the sys-unconfig. 3201 */ 3202 static int 3203 unconfigure_zone(char *zonepath) 3204 { 3205 int err; 3206 int status; 3207 struct stat unconfig_buf; 3208 zone_cmd_arg_t zarg; 3209 char cmdbuf[MAXPATHLEN + 51]; 3210 3211 /* The zone has to be installed in order to mount the scratch zone. */ 3212 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 3213 errno = err; 3214 zperror2(target_zone, gettext("could not set state")); 3215 return (Z_ERR); 3216 } 3217 3218 /* 3219 * Trusted Extensions requires that cloned zones use the 3220 * same sysid configuration, so it is not appropriate to 3221 * unconfigure the zone. 3222 */ 3223 if (is_system_labeled()) 3224 return (Z_OK); 3225 3226 /* 3227 * Check if the zone is already sys-unconfiged. This saves us 3228 * the work of bringing up the scratch zone so we can unconfigure it. 3229 */ 3230 (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s/root/etc/.UNCONFIGURED", 3231 zonepath); 3232 if (stat(cmdbuf, &unconfig_buf) == 0) 3233 return (Z_OK); 3234 3235 zarg.cmd = Z_MOUNT; 3236 if (call_zoneadmd(target_zone, &zarg) != 0) { 3237 zerror(gettext("call to %s failed"), "zoneadmd"); 3238 (void) zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3239 return (Z_ERR); 3240 } 3241 3242 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3243 "/usr/sbin/zlogin -S %s /usr/sbin/sys-unconfig -R /a", target_zone); 3244 3245 status = do_subproc(cmdbuf); 3246 if ((err = subproc_status("sys-unconfig", status)) != Z_OK) { 3247 errno = err; 3248 zperror2(target_zone, gettext("sys-unconfig failed\n")); 3249 (void) zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3250 } 3251 3252 zarg.cmd = Z_UNMOUNT; 3253 if (call_zoneadmd(target_zone, &zarg) != 0) { 3254 zerror(gettext("call to %s failed"), "zoneadmd"); 3255 (void) fprintf(stderr, gettext("could not unmount zone\n")); 3256 return (Z_ERR); 3257 } 3258 3259 return ((err == Z_OK) ? Z_OK : Z_ERR); 3260 } 3261 3262 /* ARGSUSED */ 3263 static int 3264 zfm_print(const char *p, void *r) { 3265 zerror(" %s\n", p); 3266 return (0); 3267 } 3268 3269 int 3270 clone_copy(char *source_zonepath, char *zonepath) 3271 { 3272 int err; 3273 3274 /* Don't clone the zone if anything is still mounted there */ 3275 if (zonecfg_find_mounts(source_zonepath, NULL, NULL)) { 3276 zerror(gettext("These file systems are mounted on " 3277 "subdirectories of %s.\n"), source_zonepath); 3278 (void) zonecfg_find_mounts(source_zonepath, zfm_print, NULL); 3279 return (Z_ERR); 3280 } 3281 3282 /* 3283 * Attempt to create a ZFS fs for the zonepath. As usual, we don't 3284 * care if this works or not since we always have the default behavior 3285 * of a simple directory for the zonepath. 3286 */ 3287 create_zfs_zonepath(zonepath); 3288 3289 (void) printf(gettext("Copying %s..."), source_zonepath); 3290 (void) fflush(stdout); 3291 3292 err = copy_zone(source_zonepath, zonepath); 3293 3294 (void) printf("\n"); 3295 3296 return (err); 3297 } 3298 3299 static int 3300 clone_func(int argc, char *argv[]) 3301 { 3302 char *source_zone = NULL; 3303 int lockfd; 3304 int err, arg; 3305 char zonepath[MAXPATHLEN]; 3306 char source_zonepath[MAXPATHLEN]; 3307 zone_state_t state; 3308 zone_entry_t *zent; 3309 char *method = NULL; 3310 char *snapshot = NULL; 3311 3312 if (zonecfg_in_alt_root()) { 3313 zerror(gettext("cannot clone zone in alternate root")); 3314 return (Z_ERR); 3315 } 3316 3317 optind = 0; 3318 if ((arg = getopt(argc, argv, "?m:s:")) != EOF) { 3319 switch (arg) { 3320 case '?': 3321 sub_usage(SHELP_CLONE, CMD_CLONE); 3322 return (optopt == '?' ? Z_OK : Z_USAGE); 3323 case 'm': 3324 method = optarg; 3325 break; 3326 case 's': 3327 snapshot = optarg; 3328 break; 3329 default: 3330 sub_usage(SHELP_CLONE, CMD_CLONE); 3331 return (Z_USAGE); 3332 } 3333 } 3334 if (argc != (optind + 1) || 3335 (method != NULL && strcmp(method, "copy") != 0)) { 3336 sub_usage(SHELP_CLONE, CMD_CLONE); 3337 return (Z_USAGE); 3338 } 3339 source_zone = argv[optind]; 3340 if (sanity_check(target_zone, CMD_CLONE, B_FALSE, B_TRUE) != Z_OK) 3341 return (Z_ERR); 3342 if (verify_details(CMD_CLONE) != Z_OK) 3343 return (Z_ERR); 3344 3345 /* 3346 * We also need to do some extra validation on the source zone. 3347 */ 3348 if (strcmp(source_zone, GLOBAL_ZONENAME) == 0) { 3349 zerror(gettext("%s operation is invalid for the global zone."), 3350 cmd_to_str(CMD_CLONE)); 3351 return (Z_ERR); 3352 } 3353 3354 if (strncmp(source_zone, "SUNW", 4) == 0) { 3355 zerror(gettext("%s operation is invalid for zones starting " 3356 "with SUNW."), cmd_to_str(CMD_CLONE)); 3357 return (Z_ERR); 3358 } 3359 3360 zent = lookup_running_zone(source_zone); 3361 if (zent != NULL) { 3362 /* check whether the zone is ready or running */ 3363 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) 3364 != Z_OK) { 3365 errno = err; 3366 zperror2(zent->zname, gettext("could not get state")); 3367 /* can't tell, so hedge */ 3368 zent->zstate_str = "ready/running"; 3369 } else { 3370 zent->zstate_str = zone_state_str(zent->zstate_num); 3371 } 3372 zerror(gettext("%s operation is invalid for %s zones."), 3373 cmd_to_str(CMD_CLONE), zent->zstate_str); 3374 return (Z_ERR); 3375 } 3376 3377 if ((err = zone_get_state(source_zone, &state)) != Z_OK) { 3378 errno = err; 3379 zperror2(source_zone, gettext("could not get state")); 3380 return (Z_ERR); 3381 } 3382 if (state != ZONE_STATE_INSTALLED) { 3383 (void) fprintf(stderr, 3384 gettext("%s: zone %s is %s; %s is required.\n"), 3385 execname, source_zone, zone_state_str(state), 3386 zone_state_str(ZONE_STATE_INSTALLED)); 3387 return (Z_ERR); 3388 } 3389 3390 /* 3391 * The source zone checks out ok, continue with the clone. 3392 */ 3393 3394 if (validate_clone(source_zone, target_zone) != Z_OK) 3395 return (Z_ERR); 3396 3397 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3398 zerror(gettext("another %s may have an operation in progress."), 3399 "zoneadm"); 3400 return (Z_ERR); 3401 } 3402 3403 if ((err = zone_get_zonepath(source_zone, source_zonepath, 3404 sizeof (source_zonepath))) != Z_OK) { 3405 errno = err; 3406 zperror2(source_zone, gettext("could not get zone path")); 3407 goto done; 3408 } 3409 3410 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3411 != Z_OK) { 3412 errno = err; 3413 zperror2(target_zone, gettext("could not get zone path")); 3414 goto done; 3415 } 3416 3417 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 3418 != Z_OK) { 3419 errno = err; 3420 zperror2(target_zone, gettext("could not set state")); 3421 goto done; 3422 } 3423 3424 if (snapshot != NULL) { 3425 err = clone_snapshot_zfs(snapshot, zonepath); 3426 } else { 3427 /* 3428 * We always copy the clone unless the source is ZFS and a 3429 * ZFS clone worked. We fallback to copying if the ZFS clone 3430 * fails for some reason. 3431 */ 3432 err = Z_ERR; 3433 if (method == NULL && is_zonepath_zfs(source_zonepath)) 3434 err = clone_zfs(source_zone, source_zonepath, zonepath); 3435 3436 if (err != Z_OK) 3437 err = clone_copy(source_zonepath, zonepath); 3438 } 3439 3440 if (err == Z_OK) 3441 err = unconfigure_zone(zonepath); 3442 3443 done: 3444 release_lock_file(lockfd); 3445 return ((err == Z_OK) ? Z_OK : Z_ERR); 3446 } 3447 3448 #define RMCOMMAND "/usr/bin/rm -rf" 3449 3450 /* 3451 * Used when removing a zonepath after uninstalling or cleaning up after 3452 * the move subcommand. This handles a zonepath that has non-standard 3453 * contents so that we will only cleanup the stuff we know about and leave 3454 * any user data alone. 3455 * 3456 * If the "all" parameter is true then we should remove the whole zonepath 3457 * even if it has non-standard files/directories in it. This can be used when 3458 * we need to cleanup after moving the zonepath across file systems. 3459 * 3460 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND 3461 * and not the shell. 3462 */ 3463 static int 3464 cleanup_zonepath(char *zonepath, boolean_t all) 3465 { 3466 int status; 3467 int i; 3468 boolean_t non_std = B_FALSE; 3469 struct dirent *dp; 3470 DIR *dirp; 3471 char *std_entries[] = {"dev", "lu", "root", NULL}; 3472 /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ 3473 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; 3474 3475 /* 3476 * We shouldn't need these checks but lets be paranoid since we 3477 * could blow away the whole system here if we got the wrong zonepath. 3478 */ 3479 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) { 3480 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath); 3481 return (Z_INVAL); 3482 } 3483 3484 /* 3485 * If the dirpath is already gone (maybe it was manually removed) then 3486 * we just return Z_OK so that the cleanup is successful. 3487 */ 3488 if ((dirp = opendir(zonepath)) == NULL) 3489 return (Z_OK); 3490 3491 /* 3492 * Look through the zonepath directory to see if there are any 3493 * non-standard files/dirs. Also skip .zfs since that might be 3494 * there but we'll handle ZFS file systems as a special case. 3495 */ 3496 while ((dp = readdir(dirp)) != NULL) { 3497 if (strcmp(dp->d_name, ".") == 0 || 3498 strcmp(dp->d_name, "..") == 0 || 3499 strcmp(dp->d_name, ".zfs") == 0) 3500 continue; 3501 3502 for (i = 0; std_entries[i] != NULL; i++) 3503 if (strcmp(dp->d_name, std_entries[i]) == 0) 3504 break; 3505 3506 if (std_entries[i] == NULL) 3507 non_std = B_TRUE; 3508 } 3509 (void) closedir(dirp); 3510 3511 if (!all && non_std) { 3512 /* 3513 * There are extra, non-standard directories/files in the 3514 * zonepath so we don't want to remove the zonepath. We 3515 * just want to remove the standard directories and leave 3516 * the user data alone. 3517 */ 3518 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND); 3519 3520 for (i = 0; std_entries[i] != NULL; i++) { 3521 char tmpbuf[MAXPATHLEN]; 3522 3523 if (snprintf(tmpbuf, sizeof (tmpbuf), " %s/%s", 3524 zonepath, std_entries[i]) >= sizeof (tmpbuf) || 3525 strlcat(cmdbuf, tmpbuf, sizeof (cmdbuf)) >= 3526 sizeof (cmdbuf)) { 3527 (void) fprintf(stderr, 3528 gettext("path is too long\n")); 3529 return (Z_INVAL); 3530 } 3531 } 3532 3533 status = do_subproc(cmdbuf); 3534 3535 (void) fprintf(stderr, gettext("WARNING: Unable to completely " 3536 "remove %s\nbecause it contains additional user data. " 3537 "Only the standard directory\nentries have been " 3538 "removed.\n"), 3539 zonepath); 3540 3541 return (subproc_status(RMCOMMAND, status)); 3542 } 3543 3544 /* 3545 * There is nothing unexpected in the zonepath, try to get rid of the 3546 * whole zonepath directory. 3547 * 3548 * If the zonepath is its own zfs file system, try to destroy the 3549 * file system. If that fails for some reason (e.g. it has clones) 3550 * then we'll just remove the contents of the zonepath. 3551 */ 3552 if (is_zonepath_zfs(zonepath)) { 3553 if (destroy_zfs(zonepath) == Z_OK) 3554 return (Z_OK); 3555 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND 3556 " %s/*", zonepath); 3557 status = do_subproc(cmdbuf); 3558 return (subproc_status(RMCOMMAND, status)); 3559 } 3560 3561 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3562 zonepath); 3563 status = do_subproc(cmdbuf); 3564 return (subproc_status(RMCOMMAND, status)); 3565 } 3566 3567 static int 3568 move_func(int argc, char *argv[]) 3569 { 3570 char *new_zonepath = NULL; 3571 int lockfd; 3572 int err, arg; 3573 char zonepath[MAXPATHLEN]; 3574 zone_dochandle_t handle; 3575 boolean_t fast; 3576 boolean_t is_zfs = B_FALSE; 3577 struct dirent *dp; 3578 DIR *dirp; 3579 boolean_t empty = B_TRUE; 3580 boolean_t revert; 3581 struct stat zonepath_buf; 3582 struct stat new_zonepath_buf; 3583 3584 if (zonecfg_in_alt_root()) { 3585 zerror(gettext("cannot move zone in alternate root")); 3586 return (Z_ERR); 3587 } 3588 3589 optind = 0; 3590 if ((arg = getopt(argc, argv, "?")) != EOF) { 3591 switch (arg) { 3592 case '?': 3593 sub_usage(SHELP_MOVE, CMD_MOVE); 3594 return (optopt == '?' ? Z_OK : Z_USAGE); 3595 default: 3596 sub_usage(SHELP_MOVE, CMD_MOVE); 3597 return (Z_USAGE); 3598 } 3599 } 3600 if (argc != (optind + 1)) { 3601 sub_usage(SHELP_MOVE, CMD_MOVE); 3602 return (Z_USAGE); 3603 } 3604 new_zonepath = argv[optind]; 3605 if (sanity_check(target_zone, CMD_MOVE, B_FALSE, B_TRUE) != Z_OK) 3606 return (Z_ERR); 3607 if (verify_details(CMD_MOVE) != Z_OK) 3608 return (Z_ERR); 3609 3610 /* 3611 * Check out the new zonepath. This has the side effect of creating 3612 * a directory for the new zonepath. We depend on this later when we 3613 * stat to see if we are doing a cross file system move or not. 3614 */ 3615 if (validate_zonepath(new_zonepath, CMD_MOVE) != Z_OK) 3616 return (Z_ERR); 3617 3618 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3619 != Z_OK) { 3620 errno = err; 3621 zperror2(target_zone, gettext("could not get zone path")); 3622 return (Z_ERR); 3623 } 3624 3625 if (stat(zonepath, &zonepath_buf) == -1) { 3626 zperror(gettext("could not stat zone path"), B_FALSE); 3627 return (Z_ERR); 3628 } 3629 3630 if (stat(new_zonepath, &new_zonepath_buf) == -1) { 3631 zperror(gettext("could not stat new zone path"), B_FALSE); 3632 return (Z_ERR); 3633 } 3634 3635 /* 3636 * Check if the destination directory is empty. 3637 */ 3638 if ((dirp = opendir(new_zonepath)) == NULL) { 3639 zperror(gettext("could not open new zone path"), B_FALSE); 3640 return (Z_ERR); 3641 } 3642 while ((dp = readdir(dirp)) != (struct dirent *)0) { 3643 if (strcmp(dp->d_name, ".") == 0 || 3644 strcmp(dp->d_name, "..") == 0) 3645 continue; 3646 empty = B_FALSE; 3647 break; 3648 } 3649 (void) closedir(dirp); 3650 3651 /* Error if there is anything in the destination directory. */ 3652 if (!empty) { 3653 (void) fprintf(stderr, gettext("could not move zone to %s: " 3654 "directory not empty\n"), new_zonepath); 3655 return (Z_ERR); 3656 } 3657 3658 /* Don't move the zone if anything is still mounted there */ 3659 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { 3660 zerror(gettext("These file systems are mounted on " 3661 "subdirectories of %s.\n"), zonepath); 3662 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3663 return (Z_ERR); 3664 } 3665 3666 /* 3667 * Check if we are moving in the same file system and can do a fast 3668 * move or if we are crossing file systems and have to copy the data. 3669 */ 3670 fast = (zonepath_buf.st_dev == new_zonepath_buf.st_dev); 3671 3672 if ((handle = zonecfg_init_handle()) == NULL) { 3673 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3674 return (Z_ERR); 3675 } 3676 3677 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 3678 errno = err; 3679 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 3680 zonecfg_fini_handle(handle); 3681 return (Z_ERR); 3682 } 3683 3684 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3685 zerror(gettext("another %s may have an operation in progress."), 3686 "zoneadm"); 3687 zonecfg_fini_handle(handle); 3688 return (Z_ERR); 3689 } 3690 3691 /* 3692 * We're making some file system changes now so we have to clean up 3693 * the file system before we are done. This will either clean up the 3694 * new zonepath if the zonecfg update failed or it will clean up the 3695 * old zonepath if everything is ok. 3696 */ 3697 revert = B_TRUE; 3698 3699 if (is_zonepath_zfs(zonepath) && 3700 move_zfs(zonepath, new_zonepath) != Z_ERR) { 3701 is_zfs = B_TRUE; 3702 3703 } else if (fast) { 3704 /* same file system, use rename for a quick move */ 3705 3706 /* 3707 * Remove the new_zonepath directory that got created above 3708 * during the validation. It gets in the way of the rename. 3709 */ 3710 if (rmdir(new_zonepath) != 0) { 3711 zperror(gettext("could not rmdir new zone path"), 3712 B_FALSE); 3713 zonecfg_fini_handle(handle); 3714 release_lock_file(lockfd); 3715 return (Z_ERR); 3716 } 3717 3718 if (rename(zonepath, new_zonepath) != 0) { 3719 /* 3720 * If this fails we don't need to do all of the 3721 * cleanup that happens for the rest of the code 3722 * so just return from this error. 3723 */ 3724 zperror(gettext("could not move zone"), B_FALSE); 3725 zonecfg_fini_handle(handle); 3726 release_lock_file(lockfd); 3727 return (Z_ERR); 3728 } 3729 3730 } else { 3731 /* 3732 * Attempt to create a ZFS fs for the new zonepath. As usual, 3733 * we don't care if this works or not since we always have the 3734 * default behavior of a simple directory for the zonepath. 3735 */ 3736 create_zfs_zonepath(new_zonepath); 3737 3738 (void) printf(gettext( 3739 "Moving across file systems; copying zonepath %s..."), 3740 zonepath); 3741 (void) fflush(stdout); 3742 3743 err = copy_zone(zonepath, new_zonepath); 3744 3745 (void) printf("\n"); 3746 if (err != Z_OK) 3747 goto done; 3748 } 3749 3750 if ((err = zonecfg_set_zonepath(handle, new_zonepath)) != Z_OK) { 3751 errno = err; 3752 zperror(gettext("could not set new zonepath"), B_TRUE); 3753 goto done; 3754 } 3755 3756 if ((err = zonecfg_save(handle)) != Z_OK) { 3757 errno = err; 3758 zperror(gettext("zonecfg save failed"), B_TRUE); 3759 goto done; 3760 } 3761 3762 revert = B_FALSE; 3763 3764 done: 3765 zonecfg_fini_handle(handle); 3766 release_lock_file(lockfd); 3767 3768 /* 3769 * Clean up the file system based on how things went. We either 3770 * clean up the new zonepath if the operation failed for some reason 3771 * or we clean up the old zonepath if everything is ok. 3772 */ 3773 if (revert) { 3774 /* The zonecfg update failed, cleanup the new zonepath. */ 3775 if (is_zfs) { 3776 if (move_zfs(new_zonepath, zonepath) == Z_ERR) { 3777 (void) fprintf(stderr, gettext("could not " 3778 "restore zonepath, the zfs mountpoint is " 3779 "set as:\n%s\n"), new_zonepath); 3780 /* 3781 * err is already != Z_OK since we're reverting 3782 */ 3783 } 3784 3785 } else if (fast) { 3786 if (rename(new_zonepath, zonepath) != 0) { 3787 zperror(gettext("could not restore zonepath"), 3788 B_FALSE); 3789 /* 3790 * err is already != Z_OK since we're reverting 3791 */ 3792 } 3793 } else { 3794 (void) printf(gettext("Cleaning up zonepath %s..."), 3795 new_zonepath); 3796 (void) fflush(stdout); 3797 err = cleanup_zonepath(new_zonepath, B_TRUE); 3798 (void) printf("\n"); 3799 3800 if (err != Z_OK) { 3801 errno = err; 3802 zperror(gettext("could not remove new " 3803 "zonepath"), B_TRUE); 3804 } else { 3805 /* 3806 * Because we're reverting we know the mainline 3807 * code failed but we just reused the err 3808 * variable so we reset it back to Z_ERR. 3809 */ 3810 err = Z_ERR; 3811 } 3812 } 3813 3814 } else { 3815 /* The move was successful, cleanup the old zonepath. */ 3816 if (!is_zfs && !fast) { 3817 (void) printf( 3818 gettext("Cleaning up zonepath %s..."), zonepath); 3819 (void) fflush(stdout); 3820 err = cleanup_zonepath(zonepath, B_TRUE); 3821 (void) printf("\n"); 3822 3823 if (err != Z_OK) { 3824 errno = err; 3825 zperror(gettext("could not remove zonepath"), 3826 B_TRUE); 3827 } 3828 } 3829 } 3830 3831 return ((err == Z_OK) ? Z_OK : Z_ERR); 3832 } 3833 3834 static int 3835 detach_func(int argc, char *argv[]) 3836 { 3837 int lockfd; 3838 int err, arg; 3839 char zonepath[MAXPATHLEN]; 3840 zone_dochandle_t handle; 3841 boolean_t execute = B_TRUE; 3842 3843 if (zonecfg_in_alt_root()) { 3844 zerror(gettext("cannot detach zone in alternate root")); 3845 return (Z_ERR); 3846 } 3847 3848 optind = 0; 3849 if ((arg = getopt(argc, argv, "?n")) != EOF) { 3850 switch (arg) { 3851 case '?': 3852 sub_usage(SHELP_DETACH, CMD_DETACH); 3853 return (optopt == '?' ? Z_OK : Z_USAGE); 3854 case 'n': 3855 execute = B_FALSE; 3856 break; 3857 default: 3858 sub_usage(SHELP_DETACH, CMD_DETACH); 3859 return (Z_USAGE); 3860 } 3861 } 3862 if (execute) { 3863 if (sanity_check(target_zone, CMD_DETACH, B_FALSE, B_TRUE) 3864 != Z_OK) 3865 return (Z_ERR); 3866 if (verify_details(CMD_DETACH) != Z_OK) 3867 return (Z_ERR); 3868 } else { 3869 /* 3870 * We want a dry-run to work for a non-privileged user so we 3871 * only do minimal validation. 3872 */ 3873 if (getzoneid() != GLOBAL_ZONEID) { 3874 zerror(gettext("must be in the global zone to %s a " 3875 "zone."), cmd_to_str(CMD_DETACH)); 3876 return (Z_ERR); 3877 } 3878 3879 if (target_zone == NULL) { 3880 zerror(gettext("no zone specified")); 3881 return (Z_ERR); 3882 } 3883 3884 if (strcmp(target_zone, GLOBAL_ZONENAME) == 0) { 3885 zerror(gettext("%s operation is invalid for the " 3886 "global zone."), cmd_to_str(CMD_DETACH)); 3887 return (Z_ERR); 3888 } 3889 } 3890 3891 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3892 != Z_OK) { 3893 errno = err; 3894 zperror2(target_zone, gettext("could not get zone path")); 3895 return (Z_ERR); 3896 } 3897 3898 /* Don't detach the zone if anything is still mounted there */ 3899 if (execute && zonecfg_find_mounts(zonepath, NULL, NULL)) { 3900 zerror(gettext("These file systems are mounted on " 3901 "subdirectories of %s.\n"), zonepath); 3902 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 3903 return (Z_ERR); 3904 } 3905 3906 if ((handle = zonecfg_init_handle()) == NULL) { 3907 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3908 return (Z_ERR); 3909 } 3910 3911 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 3912 errno = err; 3913 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 3914 zonecfg_fini_handle(handle); 3915 return (Z_ERR); 3916 } 3917 3918 if (execute && grab_lock_file(target_zone, &lockfd) != Z_OK) { 3919 zerror(gettext("another %s may have an operation in progress."), 3920 "zoneadm"); 3921 zonecfg_fini_handle(handle); 3922 return (Z_ERR); 3923 } 3924 3925 if ((err = zonecfg_get_detach_info(handle, B_TRUE)) != Z_OK) { 3926 errno = err; 3927 zperror(gettext("getting the detach information failed"), 3928 B_TRUE); 3929 goto done; 3930 } 3931 3932 if ((err = zonecfg_detach_save(handle, (execute ? 0 : ZONE_DRY_RUN))) 3933 != Z_OK) { 3934 errno = err; 3935 zperror(gettext("saving the detach manifest failed"), B_TRUE); 3936 goto done; 3937 } 3938 3939 /* 3940 * Set the zone state back to configured unless we are running with the 3941 * no-execute option. 3942 */ 3943 if (execute && (err = zone_set_state(target_zone, 3944 ZONE_STATE_CONFIGURED)) != Z_OK) { 3945 errno = err; 3946 zperror(gettext("could not reset state"), B_TRUE); 3947 } 3948 3949 done: 3950 zonecfg_fini_handle(handle); 3951 if (execute) 3952 release_lock_file(lockfd); 3953 3954 return ((err == Z_OK) ? Z_OK : Z_ERR); 3955 } 3956 3957 /* 3958 * During attach we go through and fix up the /dev entries for the zone 3959 * we are attaching. In order to regenerate /dev with the correct devices, 3960 * the old /dev will be removed, the zone readied (which generates a new 3961 * /dev) then halted, then we use the info from the manifest to update 3962 * the modes, owners, etc. on the new /dev. 3963 */ 3964 static int 3965 dev_fix(zone_dochandle_t handle) 3966 { 3967 int res; 3968 int err; 3969 int status; 3970 struct zone_devpermtab devtab; 3971 zone_cmd_arg_t zarg; 3972 char devpath[MAXPATHLEN]; 3973 /* 6: "exec " and " " */ 3974 char cmdbuf[sizeof (RMCOMMAND) + MAXPATHLEN + 6]; 3975 3976 if ((res = zonecfg_get_zonepath(handle, devpath, sizeof (devpath))) 3977 != Z_OK) 3978 return (res); 3979 3980 if (strlcat(devpath, "/dev", sizeof (devpath)) >= sizeof (devpath)) 3981 return (Z_TOO_BIG); 3982 3983 /* 3984 * "exec" the command so that the returned status is that of 3985 * RMCOMMAND and not the shell. 3986 */ 3987 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3988 devpath); 3989 status = do_subproc(cmdbuf); 3990 if ((err = subproc_status(RMCOMMAND, status)) != Z_OK) { 3991 (void) fprintf(stderr, 3992 gettext("could not remove existing /dev\n")); 3993 return (Z_ERR); 3994 } 3995 3996 /* In order to ready the zone, it must be in the installed state */ 3997 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 3998 errno = err; 3999 zperror(gettext("could not reset state"), B_TRUE); 4000 return (Z_ERR); 4001 } 4002 4003 /* We have to ready the zone to regen the dev tree */ 4004 zarg.cmd = Z_READY; 4005 if (call_zoneadmd(target_zone, &zarg) != 0) { 4006 zerror(gettext("call to %s failed"), "zoneadmd"); 4007 return (Z_ERR); 4008 } 4009 4010 zarg.cmd = Z_HALT; 4011 if (call_zoneadmd(target_zone, &zarg) != 0) { 4012 zerror(gettext("call to %s failed"), "zoneadmd"); 4013 return (Z_ERR); 4014 } 4015 4016 if (zonecfg_setdevperment(handle) != Z_OK) { 4017 (void) fprintf(stderr, 4018 gettext("unable to enumerate device entries\n")); 4019 return (Z_ERR); 4020 } 4021 4022 while (zonecfg_getdevperment(handle, &devtab) == Z_OK) { 4023 int err; 4024 4025 if ((err = zonecfg_devperms_apply(handle, 4026 devtab.zone_devperm_name, devtab.zone_devperm_uid, 4027 devtab.zone_devperm_gid, devtab.zone_devperm_mode, 4028 devtab.zone_devperm_acl)) != Z_OK && err != Z_INVAL) 4029 (void) fprintf(stderr, gettext("error updating device " 4030 "%s: %s\n"), devtab.zone_devperm_name, 4031 zonecfg_strerror(err)); 4032 4033 free(devtab.zone_devperm_acl); 4034 } 4035 4036 (void) zonecfg_enddevperment(handle); 4037 4038 return (Z_OK); 4039 } 4040 4041 /* 4042 * Validate attaching a zone but don't actually do the work. The zone 4043 * does not have to exist, so there is some complexity getting a new zone 4044 * configuration set up so that we can perform the validation. This is 4045 * handled within zonecfg_attach_manifest() which returns two handles; one 4046 * for the the full configuration to validate (rem_handle) and the other 4047 * (local_handle) containing only the zone configuration derived from the 4048 * manifest. 4049 */ 4050 static int 4051 dryrun_attach(char *manifest_path) 4052 { 4053 int fd; 4054 int err; 4055 int res; 4056 zone_dochandle_t local_handle; 4057 zone_dochandle_t rem_handle = NULL; 4058 4059 if (strcmp(manifest_path, "-") == 0) { 4060 fd = 0; 4061 } else if ((fd = open(manifest_path, O_RDONLY)) < 0) { 4062 zperror(gettext("could not open manifest path"), B_FALSE); 4063 return (Z_ERR); 4064 } 4065 4066 if ((local_handle = zonecfg_init_handle()) == NULL) { 4067 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4068 res = Z_ERR; 4069 goto done; 4070 } 4071 4072 if ((rem_handle = zonecfg_init_handle()) == NULL) { 4073 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4074 res = Z_ERR; 4075 goto done; 4076 } 4077 4078 if ((err = zonecfg_attach_manifest(fd, local_handle, rem_handle)) 4079 != Z_OK) { 4080 if (err == Z_INVALID_DOCUMENT) 4081 zerror(gettext("Cannot attach to an earlier release " 4082 "of the operating system")); 4083 else 4084 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4085 res = Z_ERR; 4086 goto done; 4087 } 4088 4089 res = verify_handle(CMD_ATTACH, local_handle); 4090 4091 /* Get the detach information for the locally defined zone. */ 4092 if ((err = zonecfg_get_detach_info(local_handle, B_FALSE)) != Z_OK) { 4093 errno = err; 4094 zperror(gettext("getting the attach information failed"), 4095 B_TRUE); 4096 res = Z_ERR; 4097 } else { 4098 /* sw_cmp prints error msgs as necessary */ 4099 if (sw_cmp(local_handle, rem_handle, SW_CMP_NONE) != Z_OK) 4100 res = Z_ERR; 4101 } 4102 4103 done: 4104 if (strcmp(manifest_path, "-") != 0) 4105 (void) close(fd); 4106 4107 zonecfg_fini_handle(local_handle); 4108 zonecfg_fini_handle(rem_handle); 4109 4110 return ((res == Z_OK) ? Z_OK : Z_ERR); 4111 } 4112 4113 static int 4114 attach_func(int argc, char *argv[]) 4115 { 4116 int lockfd; 4117 int err, arg; 4118 boolean_t force = B_FALSE; 4119 zone_dochandle_t handle; 4120 zone_dochandle_t athandle = NULL; 4121 char zonepath[MAXPATHLEN]; 4122 boolean_t execute = B_TRUE; 4123 char *manifest_path; 4124 4125 if (zonecfg_in_alt_root()) { 4126 zerror(gettext("cannot attach zone in alternate root")); 4127 return (Z_ERR); 4128 } 4129 4130 optind = 0; 4131 if ((arg = getopt(argc, argv, "?Fn:")) != EOF) { 4132 switch (arg) { 4133 case '?': 4134 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4135 return (optopt == '?' ? Z_OK : Z_USAGE); 4136 case 'F': 4137 force = B_TRUE; 4138 break; 4139 case 'n': 4140 execute = B_FALSE; 4141 manifest_path = optarg; 4142 break; 4143 default: 4144 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4145 return (Z_USAGE); 4146 } 4147 } 4148 4149 /* 4150 * If the no-execute option was specified, we need to branch down 4151 * a completely different path since there is no zone required to be 4152 * configured for this option. 4153 */ 4154 if (!execute) 4155 return (dryrun_attach(manifest_path)); 4156 4157 if (sanity_check(target_zone, CMD_ATTACH, B_FALSE, B_TRUE) != Z_OK) 4158 return (Z_ERR); 4159 if (verify_details(CMD_ATTACH) != Z_OK) 4160 return (Z_ERR); 4161 4162 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 4163 != Z_OK) { 4164 errno = err; 4165 zperror2(target_zone, gettext("could not get zone path")); 4166 return (Z_ERR); 4167 } 4168 4169 if ((handle = zonecfg_init_handle()) == NULL) { 4170 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4171 return (Z_ERR); 4172 } 4173 4174 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 4175 errno = err; 4176 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4177 zonecfg_fini_handle(handle); 4178 return (Z_ERR); 4179 } 4180 4181 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4182 zerror(gettext("another %s may have an operation in progress."), 4183 "zoneadm"); 4184 zonecfg_fini_handle(handle); 4185 return (Z_ERR); 4186 } 4187 4188 if (force) 4189 goto forced; 4190 4191 if ((athandle = zonecfg_init_handle()) == NULL) { 4192 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4193 goto done; 4194 } 4195 4196 if ((err = zonecfg_get_attach_handle(zonepath, target_zone, B_TRUE, 4197 athandle)) != Z_OK) { 4198 if (err == Z_NO_ZONE) 4199 zerror(gettext("Not a detached zone")); 4200 else if (err == Z_INVALID_DOCUMENT) 4201 zerror(gettext("Cannot attach to an earlier release " 4202 "of the operating system")); 4203 else 4204 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4205 goto done; 4206 } 4207 4208 /* Get the detach information for the locally defined zone. */ 4209 if ((err = zonecfg_get_detach_info(handle, B_FALSE)) != Z_OK) { 4210 errno = err; 4211 zperror(gettext("getting the attach information failed"), 4212 B_TRUE); 4213 goto done; 4214 } 4215 4216 /* sw_cmp prints error msgs as necessary */ 4217 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) 4218 goto done; 4219 4220 if ((err = dev_fix(athandle)) != Z_OK) 4221 goto done; 4222 4223 forced: 4224 4225 zonecfg_rm_detached(handle, force); 4226 4227 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 4228 errno = err; 4229 zperror(gettext("could not reset state"), B_TRUE); 4230 } 4231 4232 done: 4233 zonecfg_fini_handle(handle); 4234 release_lock_file(lockfd); 4235 if (athandle != NULL) 4236 zonecfg_fini_handle(athandle); 4237 4238 return ((err == Z_OK) ? Z_OK : Z_ERR); 4239 } 4240 4241 /* 4242 * On input, TRUE => yes, FALSE => no. 4243 * On return, TRUE => 1, FALSE => 0, could not ask => -1. 4244 */ 4245 4246 static int 4247 ask_yesno(boolean_t default_answer, const char *question) 4248 { 4249 char line[64]; /* should be large enough to answer yes or no */ 4250 4251 if (!isatty(STDIN_FILENO)) 4252 return (-1); 4253 for (;;) { 4254 (void) printf("%s (%s)? ", question, 4255 default_answer ? "[y]/n" : "y/[n]"); 4256 if (fgets(line, sizeof (line), stdin) == NULL || 4257 line[0] == '\n') 4258 return (default_answer ? 1 : 0); 4259 if (tolower(line[0]) == 'y') 4260 return (1); 4261 if (tolower(line[0]) == 'n') 4262 return (0); 4263 } 4264 } 4265 4266 static int 4267 uninstall_func(int argc, char *argv[]) 4268 { 4269 char line[ZONENAME_MAX + 128]; /* Enough for "Are you sure ..." */ 4270 char rootpath[MAXPATHLEN], zonepath[MAXPATHLEN]; 4271 boolean_t force = B_FALSE; 4272 int lockfd, answer; 4273 int err, arg; 4274 4275 if (zonecfg_in_alt_root()) { 4276 zerror(gettext("cannot uninstall zone in alternate root")); 4277 return (Z_ERR); 4278 } 4279 4280 optind = 0; 4281 while ((arg = getopt(argc, argv, "?F")) != EOF) { 4282 switch (arg) { 4283 case '?': 4284 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4285 return (optopt == '?' ? Z_OK : Z_USAGE); 4286 case 'F': 4287 force = B_TRUE; 4288 break; 4289 default: 4290 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4291 return (Z_USAGE); 4292 } 4293 } 4294 if (argc > optind) { 4295 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4296 return (Z_USAGE); 4297 } 4298 4299 if (sanity_check(target_zone, CMD_UNINSTALL, B_FALSE, B_TRUE) != Z_OK) 4300 return (Z_ERR); 4301 4302 if (!force) { 4303 (void) snprintf(line, sizeof (line), 4304 gettext("Are you sure you want to %s zone %s"), 4305 cmd_to_str(CMD_UNINSTALL), target_zone); 4306 if ((answer = ask_yesno(B_FALSE, line)) == 0) { 4307 return (Z_OK); 4308 } else if (answer == -1) { 4309 zerror(gettext("Input not from terminal and -F " 4310 "not specified: %s not done."), 4311 cmd_to_str(CMD_UNINSTALL)); 4312 return (Z_ERR); 4313 } 4314 } 4315 4316 if ((err = zone_get_zonepath(target_zone, zonepath, 4317 sizeof (zonepath))) != Z_OK) { 4318 errno = err; 4319 zperror2(target_zone, gettext("could not get zone path")); 4320 return (Z_ERR); 4321 } 4322 if ((err = zone_get_rootpath(target_zone, rootpath, 4323 sizeof (rootpath))) != Z_OK) { 4324 errno = err; 4325 zperror2(target_zone, gettext("could not get root path")); 4326 return (Z_ERR); 4327 } 4328 4329 /* 4330 * If there seems to be a zoneadmd running for this zone, call it 4331 * to tell it that an uninstall is happening; if all goes well it 4332 * will then shut itself down. 4333 */ 4334 if (ping_zoneadmd(target_zone) == Z_OK) { 4335 zone_cmd_arg_t zarg; 4336 zarg.cmd = Z_NOTE_UNINSTALLING; 4337 /* we don't care too much if this fails... just plow on */ 4338 (void) call_zoneadmd(target_zone, &zarg); 4339 } 4340 4341 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4342 zerror(gettext("another %s may have an operation in progress."), 4343 "zoneadm"); 4344 return (Z_ERR); 4345 } 4346 4347 /* Don't uninstall the zone if anything is mounted there */ 4348 err = zonecfg_find_mounts(rootpath, NULL, NULL); 4349 if (err) { 4350 zerror(gettext("These file systems are mounted on " 4351 "subdirectories of %s.\n"), rootpath); 4352 (void) zonecfg_find_mounts(rootpath, zfm_print, NULL); 4353 return (Z_ERR); 4354 } 4355 4356 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4357 if (err != Z_OK) { 4358 errno = err; 4359 zperror2(target_zone, gettext("could not set state")); 4360 goto bad; 4361 } 4362 4363 if ((err = cleanup_zonepath(zonepath, B_FALSE)) != Z_OK) { 4364 errno = err; 4365 zperror2(target_zone, gettext("cleaning up zonepath failed")); 4366 goto bad; 4367 } 4368 4369 err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4370 if (err != Z_OK) { 4371 errno = err; 4372 zperror2(target_zone, gettext("could not reset state")); 4373 } 4374 bad: 4375 release_lock_file(lockfd); 4376 return (err); 4377 } 4378 4379 /* ARGSUSED */ 4380 static int 4381 mount_func(int argc, char *argv[]) 4382 { 4383 zone_cmd_arg_t zarg; 4384 4385 if (argc > 0) 4386 return (Z_USAGE); 4387 if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE) != Z_OK) 4388 return (Z_ERR); 4389 if (verify_details(CMD_MOUNT) != Z_OK) 4390 return (Z_ERR); 4391 4392 zarg.cmd = Z_MOUNT; 4393 if (call_zoneadmd(target_zone, &zarg) != 0) { 4394 zerror(gettext("call to %s failed"), "zoneadmd"); 4395 return (Z_ERR); 4396 } 4397 return (Z_OK); 4398 } 4399 4400 /* ARGSUSED */ 4401 static int 4402 unmount_func(int argc, char *argv[]) 4403 { 4404 zone_cmd_arg_t zarg; 4405 4406 if (argc > 0) 4407 return (Z_USAGE); 4408 if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE) != Z_OK) 4409 return (Z_ERR); 4410 4411 zarg.cmd = Z_UNMOUNT; 4412 if (call_zoneadmd(target_zone, &zarg) != 0) { 4413 zerror(gettext("call to %s failed"), "zoneadmd"); 4414 return (Z_ERR); 4415 } 4416 return (Z_OK); 4417 } 4418 4419 static int 4420 mark_func(int argc, char *argv[]) 4421 { 4422 int err, lockfd; 4423 4424 if (argc != 1 || strcmp(argv[0], "incomplete") != 0) 4425 return (Z_USAGE); 4426 if (sanity_check(target_zone, CMD_MARK, B_FALSE, B_FALSE) != Z_OK) 4427 return (Z_ERR); 4428 4429 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4430 zerror(gettext("another %s may have an operation in progress."), 4431 "zoneadm"); 4432 return (Z_ERR); 4433 } 4434 4435 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4436 if (err != Z_OK) { 4437 errno = err; 4438 zperror2(target_zone, gettext("could not set state")); 4439 } 4440 release_lock_file(lockfd); 4441 4442 return (err); 4443 } 4444 4445 static int 4446 help_func(int argc, char *argv[]) 4447 { 4448 int arg, cmd_num; 4449 4450 if (argc == 0) { 4451 (void) usage(B_TRUE); 4452 return (Z_OK); 4453 } 4454 optind = 0; 4455 if ((arg = getopt(argc, argv, "?")) != EOF) { 4456 switch (arg) { 4457 case '?': 4458 sub_usage(SHELP_HELP, CMD_HELP); 4459 return (optopt == '?' ? Z_OK : Z_USAGE); 4460 default: 4461 sub_usage(SHELP_HELP, CMD_HELP); 4462 return (Z_USAGE); 4463 } 4464 } 4465 while (optind < argc) { 4466 /* Private commands have NULL short_usage; omit them */ 4467 if ((cmd_num = cmd_match(argv[optind])) < 0 || 4468 cmdtab[cmd_num].short_usage == NULL) { 4469 sub_usage(SHELP_HELP, CMD_HELP); 4470 return (Z_USAGE); 4471 } 4472 sub_usage(cmdtab[cmd_num].short_usage, cmd_num); 4473 optind++; 4474 } 4475 return (Z_OK); 4476 } 4477 4478 /* 4479 * Returns: CMD_MIN thru CMD_MAX on success, -1 on error 4480 */ 4481 4482 static int 4483 cmd_match(char *cmd) 4484 { 4485 int i; 4486 4487 for (i = CMD_MIN; i <= CMD_MAX; i++) { 4488 /* return only if there is an exact match */ 4489 if (strcmp(cmd, cmdtab[i].cmd_name) == 0) 4490 return (cmdtab[i].cmd_num); 4491 } 4492 return (-1); 4493 } 4494 4495 static int 4496 parse_and_run(int argc, char *argv[]) 4497 { 4498 int i = cmd_match(argv[0]); 4499 4500 if (i < 0) 4501 return (usage(B_FALSE)); 4502 return (cmdtab[i].handler(argc - 1, &(argv[1]))); 4503 } 4504 4505 static char * 4506 get_execbasename(char *execfullname) 4507 { 4508 char *last_slash, *execbasename; 4509 4510 /* guard against '/' at end of command invocation */ 4511 for (;;) { 4512 last_slash = strrchr(execfullname, '/'); 4513 if (last_slash == NULL) { 4514 execbasename = execfullname; 4515 break; 4516 } else { 4517 execbasename = last_slash + 1; 4518 if (*execbasename == '\0') { 4519 *last_slash = '\0'; 4520 continue; 4521 } 4522 break; 4523 } 4524 } 4525 return (execbasename); 4526 } 4527 4528 int 4529 main(int argc, char **argv) 4530 { 4531 int arg; 4532 zoneid_t zid; 4533 struct stat st; 4534 4535 if ((locale = setlocale(LC_ALL, "")) == NULL) 4536 locale = "C"; 4537 (void) textdomain(TEXT_DOMAIN); 4538 setbuf(stdout, NULL); 4539 (void) sigset(SIGHUP, SIG_IGN); 4540 execname = get_execbasename(argv[0]); 4541 target_zone = NULL; 4542 if (chdir("/") != 0) { 4543 zerror(gettext("could not change directory to /.")); 4544 exit(Z_ERR); 4545 } 4546 4547 if (init_zfs() != Z_OK) 4548 exit(Z_ERR); 4549 4550 while ((arg = getopt(argc, argv, "?u:z:R:")) != EOF) { 4551 switch (arg) { 4552 case '?': 4553 return (usage(B_TRUE)); 4554 case 'u': 4555 target_uuid = optarg; 4556 break; 4557 case 'z': 4558 target_zone = optarg; 4559 break; 4560 case 'R': /* private option for admin/install use */ 4561 if (*optarg != '/') { 4562 zerror(gettext("root path must be absolute.")); 4563 exit(Z_ERR); 4564 } 4565 if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { 4566 zerror( 4567 gettext("root path must be a directory.")); 4568 exit(Z_ERR); 4569 } 4570 zonecfg_set_root(optarg); 4571 break; 4572 default: 4573 return (usage(B_FALSE)); 4574 } 4575 } 4576 4577 if (optind >= argc) 4578 return (usage(B_FALSE)); 4579 4580 if (target_uuid != NULL && *target_uuid != '\0') { 4581 uuid_t uuid; 4582 static char newtarget[ZONENAME_MAX]; 4583 4584 if (uuid_parse(target_uuid, uuid) == -1) { 4585 zerror(gettext("illegal UUID value specified")); 4586 exit(Z_ERR); 4587 } 4588 if (zonecfg_get_name_by_uuid(uuid, newtarget, 4589 sizeof (newtarget)) == Z_OK) 4590 target_zone = newtarget; 4591 } 4592 4593 if (target_zone != NULL && zone_get_id(target_zone, &zid) != 0) { 4594 errno = Z_NO_ZONE; 4595 zperror(target_zone, B_TRUE); 4596 exit(Z_ERR); 4597 } 4598 return (parse_and_run(argc - optind, &argv[optind])); 4599 } 4600