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 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "@(#)zoneadm.c 1.65 08/05/07 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/brand.h>
59 #include <sys/param.h>
60 #include <sys/types.h>
61 #include <sys/stat.h>
62 #include <sys/statvfs.h>
63 #include <assert.h>
64 #include <sys/sockio.h>
65 #include <sys/mntent.h>
66 #include <limits.h>
67 #include <dirent.h>
68 #include <uuid/uuid.h>
69 #include <libdlpi.h>
70
71 #include <fcntl.h>
72 #include <door.h>
73 #include <macros.h>
74 #include <libgen.h>
75 #include <fnmatch.h>
76 #include <sys/modctl.h>
77 #include <libbrand.h>
78 #include <libscf.h>
79 #include <procfs.h>
80 #include <strings.h>
81
82 #include <pool.h>
83 #include <sys/pool.h>
84 #include <sys/priocntl.h>
85 #include <sys/fsspriocntl.h>
86
87 #include "zoneadm.h"
88
89 #define MAXARGS 8
90
91 /* Reflects kernel zone entries */
92 typedef struct zone_entry {
93 zoneid_t zid;
94 char zname[ZONENAME_MAX];
95 char *zstate_str;
96 zone_state_t zstate_num;
97 char zbrand[MAXNAMELEN];
98 char zroot[MAXPATHLEN];
99 char zuuid[UUID_PRINTABLE_STRING_LENGTH];
100 zone_iptype_t ziptype;
101 } zone_entry_t;
102
103 #define CLUSTER_BRAND_NAME "cluster"
104
105 static zone_entry_t *zents;
106 static size_t nzents;
107 static boolean_t is_native_zone = B_TRUE;
108 static boolean_t is_cluster_zone = B_FALSE;
109
110 #define LOOPBACK_IF "lo0"
111 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af))
112
113 struct net_if {
114 char *name;
115 int af;
116 };
117
118 /* 0755 is the default directory mode. */
119 #define DEFAULT_DIR_MODE \
120 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
121
122 struct cmd {
123 uint_t cmd_num; /* command number */
124 char *cmd_name; /* command name */
125 char *short_usage; /* short form help */
126 int (*handler)(int argc, char *argv[]); /* function to call */
127
128 };
129
130 #define SHELP_HELP "help"
131 #define SHELP_BOOT "boot [-- boot_arguments]"
132 #define SHELP_HALT "halt"
133 #define SHELP_READY "ready"
134 #define SHELP_REBOOT "reboot [-- boot_arguments]"
135 #define SHELP_LIST "list [-cipv]"
136 #define SHELP_VERIFY "verify"
137 #define SHELP_INSTALL "install [-x nodataset] [brand-specific args]"
138 #define SHELP_UNINSTALL "uninstall [-F]"
139 #define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename"
140 #define SHELP_MOVE "move zonepath"
141 #define SHELP_DETACH "detach [-n]"
142 #define SHELP_ATTACH "attach [-F] [-n <path>] [-u]"
143 #define SHELP_MARK "mark incomplete"
144
145 #define EXEC_PREFIX "exec "
146 #define EXEC_LEN (strlen(EXEC_PREFIX))
147 #define RMCOMMAND "/usr/bin/rm -rf"
148
149 static int cleanup_zonepath(char *, boolean_t);
150
151
152 static int help_func(int argc, char *argv[]);
153 static int ready_func(int argc, char *argv[]);
154 static int boot_func(int argc, char *argv[]);
155 static int halt_func(int argc, char *argv[]);
156 static int reboot_func(int argc, char *argv[]);
157 static int list_func(int argc, char *argv[]);
158 static int verify_func(int argc, char *argv[]);
159 static int install_func(int argc, char *argv[]);
160 static int uninstall_func(int argc, char *argv[]);
161 static int mount_func(int argc, char *argv[]);
162 static int unmount_func(int argc, char *argv[]);
163 static int clone_func(int argc, char *argv[]);
164 static int move_func(int argc, char *argv[]);
165 static int detach_func(int argc, char *argv[]);
166 static int attach_func(int argc, char *argv[]);
167 static int mark_func(int argc, char *argv[]);
168 static int apply_func(int argc, char *argv[]);
169 static int sanity_check(char *zone, int cmd_num, boolean_t running,
170 boolean_t unsafe_when_running, boolean_t force);
171 static int cmd_match(char *cmd);
172 static int verify_details(int, char *argv[]);
173 static int verify_brand(zone_dochandle_t, int, char *argv[]);
174 static int invoke_brand_handler(int, char *argv[]);
175
176 static struct cmd cmdtab[] = {
177 { CMD_HELP, "help", SHELP_HELP, help_func },
178 { CMD_BOOT, "boot", SHELP_BOOT, boot_func },
179 { CMD_HALT, "halt", SHELP_HALT, halt_func },
180 { CMD_READY, "ready", SHELP_READY, ready_func },
181 { CMD_REBOOT, "reboot", SHELP_REBOOT, reboot_func },
182 { CMD_LIST, "list", SHELP_LIST, list_func },
183 { CMD_VERIFY, "verify", SHELP_VERIFY, verify_func },
184 { CMD_INSTALL, "install", SHELP_INSTALL, install_func },
185 { CMD_UNINSTALL, "uninstall", SHELP_UNINSTALL,
186 uninstall_func },
187 /* mount and unmount are private commands for admin/install */
188 { CMD_MOUNT, "mount", NULL, mount_func },
189 { CMD_UNMOUNT, "unmount", NULL, unmount_func },
190 { CMD_CLONE, "clone", SHELP_CLONE, clone_func },
191 { CMD_MOVE, "move", SHELP_MOVE, move_func },
192 { CMD_DETACH, "detach", SHELP_DETACH, detach_func },
193 { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func },
194 { CMD_MARK, "mark", SHELP_MARK, mark_func },
195 { CMD_APPLY, "apply", NULL, apply_func }
196 };
197
198 /* global variables */
199
200 /* set early in main(), never modified thereafter, used all over the place */
201 static char *execname;
202 static char target_brand[MAXNAMELEN];
203 static char *locale;
204 char *target_zone;
205 static char *target_uuid;
206
207 /* used in do_subproc() and signal handler */
208 static volatile boolean_t child_killed;
209 /* used in attach_func() and signal handler */
210 static volatile boolean_t attach_interupted;
211 static int do_subproc_cnt = 0;
212
213 /*
214 * Used to indicate whether this zoneadm instance has another zoneadm
215 * instance in its ancestry.
216 */
217 static boolean_t zoneadm_is_nested = B_FALSE;
218
219 /* used to track nested zone-lock operations */
220 static int zone_lock_cnt = 0;
221
222 /* used to communicate lock status to children */
223 #define LOCK_ENV_VAR "_ZONEADM_LOCK_HELD"
224 static char zoneadm_lock_held[] = LOCK_ENV_VAR"=1";
225 static char zoneadm_lock_not_held[] = LOCK_ENV_VAR"=0";
226
227 char *
228 cmd_to_str(int cmd_num)
229 {
230 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
231 return (cmdtab[cmd_num].cmd_name);
232 }
233
234 /* This is a separate function because of gettext() wrapping. */
235 static char *
236 long_help(int cmd_num)
237 {
238 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX);
239 switch (cmd_num) {
240 case CMD_HELP:
241 return (gettext("Print usage message."));
242 case CMD_BOOT:
243 return (gettext("Activates (boots) specified zone. See "
244 "zoneadm(1m) for valid boot\n\targuments."));
245 case CMD_HALT:
246 return (gettext("Halts specified zone, bypassing shutdown "
247 "scripts and removing runtime\n\tresources of the zone."));
248 case CMD_READY:
249 return (gettext("Prepares a zone for running applications but "
250 "does not start any user\n\tprocesses in the zone."));
251 case CMD_REBOOT:
252 return (gettext("Restarts the zone (equivalent to a halt / "
253 "boot sequence).\n\tFails if the zone is not active. "
254 "See zoneadm(1m) for valid boot\n\targuments."));
255 case CMD_LIST:
256 return (gettext("Lists the current zones, or a "
257 "specific zone if indicated. By default,\n\tall "
258 "running zones are listed, though this can be "
259 "expanded to all\n\tinstalled zones with the -i "
260 "option or all configured zones with the\n\t-c "
261 "option. When used with the general -z <zone> and/or -u "
262 "<uuid-match>\n\toptions, lists only the specified "
263 "matching zone, but lists it\n\tregardless of its state, "
264 "and the -i and -c options are disallowed. The\n\t-v "
265 "option can be used to display verbose information: zone "
266 "name, id,\n\tcurrent state, root directory and options. "
267 "The -p option can be used\n\tto request machine-parsable "
268 "output. The -v and -p options are mutually\n\texclusive."
269 " If neither -v nor -p is used, just the zone name is "
270 "listed."));
271 case CMD_VERIFY:
272 return (gettext("Check to make sure the configuration "
273 "can safely be instantiated\n\ton the machine: "
274 "physical network interfaces exist, etc."));
275 case CMD_INSTALL:
276 return (gettext("Install the configuration on to the system. "
277 "The -x nodataset option\n\tcan be used to prevent the "
278 "creation of a new ZFS file system for the\n\tzone "
279 "(assuming the zonepath is within a ZFS file system).\n\t"
280 "All other arguments are passed to the brand installation "
281 "function;\n\tsee brand(4) for more information."));
282 case CMD_UNINSTALL:
283 return (gettext("Uninstall the configuration from the system. "
284 "The -F flag can be used\n\tto force the action."));
285 case CMD_CLONE:
286 return (gettext("Clone the installation of another zone. "
287 "The -m option can be used to\n\tspecify 'copy' which "
288 "forces a copy of the source zone. The -s option\n\t"
289 "can be used to specify the name of a ZFS snapshot "
290 "that was taken from\n\ta previous clone command. The "
291 "snapshot will be used as the source\n\tinstead of "
292 "creating a new ZFS snapshot."));
293 case CMD_MOVE:
294 return (gettext("Move the zone to a new zonepath."));
295 case CMD_DETACH:
296 return (gettext("Detach the zone from the system. The zone "
297 "state is changed to\n\t'configured' (but the files under "
298 "the zonepath are untouched).\n\tThe zone can subsequently "
299 "be attached, or can be moved to another\n\tsystem and "
300 "attached there. The -n option can be used to specify\n\t"
301 "'no-execute' mode. When -n is used, the information "
302 "needed to attach\n\tthe zone is sent to standard output "
303 "but the zone is not actually\n\tdetached."));
304 case CMD_ATTACH:
305 return (gettext("Attach the zone to the system. The zone "
306 "state must be 'configured'\n\tprior to attach; upon "
307 "successful completion, the zone state will be\n\t"
308 "'installed'. The system software on the current "
309 "system must be\n\tcompatible with the software on the "
310 "zone's original system or use\n\tthe -u option to update "
311 "the zone to the current system software.\n\tSpecify -F "
312 "to force the attach and skip software compatibility "
313 "tests.\n\tThe -n option can be used to specify "
314 "'no-execute' mode. When -n is\n\tused, the information "
315 "needed to attach the zone is read from the\n\tspecified "
316 "path and the configuration is only validated. The path "
317 "can\n\tbe '-' to specify standard input. The -F, -n and "
318 "-u options are\n\tmutually exclusive."));
319 case CMD_MARK:
320 return (gettext("Set the state of the zone. This can be used "
321 "to force the zone\n\tstate to 'incomplete' "
322 "administratively if some activity has rendered\n\tthe "
323 "zone permanently unusable. The only valid state that "
324 "may be\n\tspecified is 'incomplete'."));
325 default:
326 return ("");
327 }
328 /* NOTREACHED */
329 return (NULL);
330 }
331
332 /*
333 * Called with explicit B_TRUE when help is explicitly requested, B_FALSE for
334 * unexpected errors.
335 */
336
337 static int
338 usage(boolean_t explicit)
339 {
340 int i;
341 FILE *fd = explicit ? stdout : stderr;
342
343 (void) fprintf(fd, "%s:\t%s help\n", gettext("usage"), execname);
344 (void) fprintf(fd, "\t%s [-z <zone>] [-u <uuid-match>] list\n",
345 execname);
346 (void) fprintf(fd, "\t%s {-z <zone>|-u <uuid-match>} <%s>\n", execname,
347 gettext("subcommand"));
348 (void) fprintf(fd, "\n%s:\n\n", gettext("Subcommands"));
349 for (i = CMD_MIN; i <= CMD_MAX; i++) {
350 if (cmdtab[i].short_usage == NULL)
351 continue;
352 (void) fprintf(fd, "%s\n", cmdtab[i].short_usage);
353 if (explicit)
354 (void) fprintf(fd, "\t%s\n\n", long_help(i));
355 }
356 if (!explicit)
357 (void) fputs("\n", fd);
358 return (Z_USAGE);
359 }
360
361 static void
362 sub_usage(char *short_usage, int cmd_num)
363 {
364 (void) fprintf(stderr, "%s:\t%s\n", gettext("usage"), short_usage);
365 (void) fprintf(stderr, "\t%s\n", long_help(cmd_num));
366 }
367
368 /*
369 * zperror() is like perror(3c) except that this also prints the executable
370 * name at the start of the message, and takes a boolean indicating whether
371 * to call libc'c strerror() or that from libzonecfg.
372 */
373
374 void
375 zperror(const char *str, boolean_t zonecfg_error)
376 {
377 (void) fprintf(stderr, "%s: %s: %s\n", execname, str,
378 zonecfg_error ? zonecfg_strerror(errno) : strerror(errno));
379 }
380
381 /*
382 * zperror2() is very similar to zperror() above, except it also prints a
383 * supplied zone name after the executable.
384 *
385 * All current consumers of this function want libzonecfg's strerror() rather
386 * than libc's; if this ever changes, this function can be made more generic
387 * like zperror() above.
388 */
389
390 void
391 zperror2(const char *zone, const char *str)
392 {
393 (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str,
394 zonecfg_strerror(errno));
395 }
396
397 /* PRINTFLIKE1 */
398 void
399 zerror(const char *fmt, ...)
400 {
401 va_list alist;
402
403 va_start(alist, fmt);
404 (void) fprintf(stderr, "%s: ", execname);
405 if (target_zone != NULL)
406 (void) fprintf(stderr, "zone '%s': ", target_zone);
407 (void) vfprintf(stderr, fmt, alist);
408 (void) fprintf(stderr, "\n");
409 va_end(alist);
410 }
411
412 static void *
413 safe_calloc(size_t nelem, size_t elsize)
414 {
415 void *r = calloc(nelem, elsize);
416
417 if (r == NULL) {
418 zerror(gettext("failed to allocate %lu bytes: %s"),
419 (ulong_t)nelem * elsize, strerror(errno));
420 exit(Z_ERR);
421 }
422 return (r);
423 }
424
425 static void
426 zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable)
427 {
428 static boolean_t firsttime = B_TRUE;
429 char *ip_type_str;
430
431 if (zent->ziptype == ZS_EXCLUSIVE)
432 ip_type_str = "excl";
433 else
434 ip_type_str = "shared";
435
436 assert(!(verbose && parsable));
437 if (firsttime && verbose) {
438 firsttime = B_FALSE;
439 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
440 ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",
441 "IP");
442 }
443 if (!verbose) {
444 char *cp, *clim;
445
446 if (!parsable) {
447 (void) printf("%s\n", zent->zname);
448 return;
449 }
450 if (zent->zid == ZONE_ID_UNDEFINED)
451 (void) printf("-");
452 else
453 (void) printf("%lu", zent->zid);
454 (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
455 cp = zent->zroot;
456 while ((clim = strchr(cp, ':')) != NULL) {
457 (void) printf("%.*s\\:", clim - cp, cp);
458 cp = clim + 1;
459 }
460 (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
461 ip_type_str);
462 return;
463 }
464 if (zent->zstate_str != NULL) {
465 if (zent->zid == ZONE_ID_UNDEFINED)
466 (void) printf("%*s", ZONEID_WIDTH, "-");
467 else
468 (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
469 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
470 zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
471 }
472 }
473
474 static int
475 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
476 {
477 char root[MAXPATHLEN], *cp;
478 int err;
479 uuid_t uuid;
480
481 (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname));
482 (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot));
483 (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand));
484 zent->zstate_str = "???";
485
486 zent->zid = zid;
487
488 if (zonecfg_get_uuid(zone_name, uuid) == Z_OK &&
489 !uuid_is_null(uuid))
490 uuid_unparse(uuid, zent->zuuid);
491 else
492 zent->zuuid[0] = '\0';
493
494 /*
495 * For labeled zones which query the zone path of lower-level
496 * zones, the path needs to be adjusted to drop the final
497 * "/root" component. This adjusted path is then useful
498 * for reading down any exported directories from the
499 * lower-level zone.
500 */
501 if (is_system_labeled() && zent->zid != ZONE_ID_UNDEFINED) {
502 if (zone_getattr(zent->zid, ZONE_ATTR_ROOT, zent->zroot,
503 sizeof (zent->zroot)) == -1) {
504 zperror2(zent->zname,
505 gettext("could not get zone path."));
506 return (Z_ERR);
507 }
508 cp = zent->zroot + strlen(zent->zroot) - 5;
509 if (cp > zent->zroot && strcmp(cp, "/root") == 0)
510 *cp = 0;
511 } else {
512 if ((err = zone_get_zonepath(zent->zname, root,
513 sizeof (root))) != Z_OK) {
514 errno = err;
515 zperror2(zent->zname,
516 gettext("could not get zone path."));
517 return (Z_ERR);
518 }
519 (void) strlcpy(zent->zroot, root, sizeof (zent->zroot));
520 }
521
522 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) {
523 errno = err;
524 zperror2(zent->zname, gettext("could not get state"));
525 return (Z_ERR);
526 }
527 zent->zstate_str = zone_state_str(zent->zstate_num);
528
529 /*
530 * A zone's brand is only available in the .xml file describing it,
531 * which is only visible to the global zone. This causes
532 * zone_get_brand() to fail when called from within a non-global
533 * zone. Fortunately we only do this on labeled systems, where we
534 * know all zones are native.
535 */
536 if (getzoneid() != GLOBAL_ZONEID) {
537 assert(is_system_labeled() != 0);
538 (void) strlcpy(zent->zbrand, NATIVE_BRAND_NAME,
539 sizeof (zent->zbrand));
540 } else if (zone_get_brand(zent->zname, zent->zbrand,
541 sizeof (zent->zbrand)) != Z_OK) {
542 zperror2(zent->zname, gettext("could not get brand name"));
543 return (Z_ERR);
544 }
545
546 /*
547 * Get ip type of the zone.
548 * Note for global zone, ZS_SHARED is set always.
549 */
550 if (zid == GLOBAL_ZONEID) {
551 zent->ziptype = ZS_SHARED;
552 } else {
553
554 if (zent->zstate_num == ZONE_STATE_RUNNING) {
555 ushort_t flags;
556
557 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
558 sizeof (flags)) < 0) {
559 zperror2(zent->zname,
560 gettext("could not get zone flags"));
561 return (Z_ERR);
562 }
563 if (flags & ZF_NET_EXCL)
564 zent->ziptype = ZS_EXCLUSIVE;
565 else
566 zent->ziptype = ZS_SHARED;
567 } else {
568 zone_dochandle_t handle;
569
570 if ((handle = zonecfg_init_handle()) == NULL) {
571 zperror2(zent->zname,
572 gettext("could not init handle"));
573 return (Z_ERR);
574 }
575 if ((err = zonecfg_get_handle(zent->zname, handle))
576 != Z_OK) {
577 zperror2(zent->zname,
578 gettext("could not get handle"));
579 zonecfg_fini_handle(handle);
580 return (Z_ERR);
581 }
582
583 if ((err = zonecfg_get_iptype(handle, &zent->ziptype))
584 != Z_OK) {
585 zperror2(zent->zname,
586 gettext("could not get ip-type"));
587 zonecfg_fini_handle(handle);
588 return (Z_ERR);
589 }
590 zonecfg_fini_handle(handle);
591 }
592 }
593
594 return (Z_OK);
595 }
596
597 /*
598 * fetch_zents() calls zone_list(2) to find out how many zones are running
599 * (which is stored in the global nzents), then calls zone_list(2) again
600 * to fetch the list of running zones (stored in the global zents). This
601 * function may be called multiple times, so if zents is already set, we
602 * return immediately to save work.
603 */
604
605 static int
606 fetch_zents(void)
607 {
608 zoneid_t *zids = NULL;
609 uint_t nzents_saved;
610 int i, retv;
611 FILE *fp;
612 boolean_t inaltroot;
613 zone_entry_t *zentp;
614
615 if (nzents > 0)
616 return (Z_OK);
617
618 if (zone_list(NULL, &nzents) != 0) {
619 zperror(gettext("failed to get zoneid list"), B_FALSE);
620 return (Z_ERR);
621 }
622
623 again:
624 if (nzents == 0)
625 return (Z_OK);
626
627 zids = safe_calloc(nzents, sizeof (zoneid_t));
628 nzents_saved = nzents;
629
630 if (zone_list(zids, &nzents) != 0) {
631 zperror(gettext("failed to get zone list"), B_FALSE);
632 free(zids);
633 return (Z_ERR);
634 }
635 if (nzents != nzents_saved) {
636 /* list changed, try again */
637 free(zids);
638 goto again;
639 }
640
641 zents = safe_calloc(nzents, sizeof (zone_entry_t));
642
643 inaltroot = zonecfg_in_alt_root();
644 if (inaltroot)
645 fp = zonecfg_open_scratch("", B_FALSE);
646 else
647 fp = NULL;
648 zentp = zents;
649 retv = Z_OK;
650 for (i = 0; i < nzents; i++) {
651 char name[ZONENAME_MAX];
652 char altname[ZONENAME_MAX];
653
654 if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) {
655 zperror(gettext("failed to get zone name"), B_FALSE);
656 retv = Z_ERR;
657 continue;
658 }
659 if (zonecfg_is_scratch(name)) {
660 /* Ignore scratch zones by default */
661 if (!inaltroot)
662 continue;
663 if (fp == NULL ||
664 zonecfg_reverse_scratch(fp, name, altname,
665 sizeof (altname), NULL, 0) == -1) {
666 zerror(gettext("could not resolve scratch "
667 "zone %s"), name);
668 retv = Z_ERR;
669 continue;
670 }
671 (void) strcpy(name, altname);
672 } else {
673 /* Ignore non-scratch when in an alternate root */
674 if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0)
675 continue;
676 }
677 if (lookup_zone_info(name, zids[i], zentp) != Z_OK) {
678 zerror(gettext("failed to get zone data"));
679 retv = Z_ERR;
680 continue;
681 }
682 zentp++;
683 }
684 nzents = zentp - zents;
685 if (fp != NULL)
686 zonecfg_close_scratch(fp);
687
688 free(zids);
689 return (retv);
690 }
691
692 static int
693 zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
694 {
695 int i;
696 zone_entry_t zent;
697 FILE *cookie;
698 char *name;
699
700 /*
701 * First get the list of running zones from the kernel and print them.
702 * If that is all we need, then return.
703 */
704 if ((i = fetch_zents()) != Z_OK) {
705 /*
706 * No need for error messages; fetch_zents() has already taken
707 * care of this.
708 */
709 return (i);
710 }
711 for (i = 0; i < nzents; i++)
712 zone_print(&zents[i], verbose, parsable);
713 if (min_state >= ZONE_STATE_RUNNING)
714 return (Z_OK);
715 /*
716 * Next, get the full list of zones from the configuration, skipping
717 * any we have already printed.
718 */
719 cookie = setzoneent();
720 while ((name = getzoneent(cookie)) != NULL) {
721 for (i = 0; i < nzents; i++) {
722 if (strcmp(zents[i].zname, name) == 0)
723 break;
724 }
725 if (i < nzents) {
726 free(name);
727 continue;
728 }
729 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
730 free(name);
731 continue;
732 }
733 free(name);
734 if (zent.zstate_num >= min_state)
735 zone_print(&zent, verbose, parsable);
736 }
737 endzoneent(cookie);
738 return (Z_OK);
739 }
740
741 static zone_entry_t *
742 lookup_running_zone(char *str)
743 {
744 zoneid_t zoneid;
745 char *cp;
746 int i;
747
748 if (fetch_zents() != Z_OK)
749 return (NULL);
750
751 for (i = 0; i < nzents; i++) {
752 if (strcmp(str, zents[i].zname) == 0)
753 return (&zents[i]);
754 }
755 errno = 0;
756 zoneid = strtol(str, &cp, 0);
757 if (zoneid < MIN_ZONEID || zoneid > MAX_ZONEID ||
758 errno != 0 || *cp != '\0')
759 return (NULL);
760 for (i = 0; i < nzents; i++) {
761 if (zoneid == zents[i].zid)
762 return (&zents[i]);
763 }
764 return (NULL);
765 }
766
767 /*
768 * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if
769 * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect).
770 */
771 static boolean_t
772 bad_mode_bit(mode_t mode, mode_t bit, boolean_t on, char *file)
773 {
774 char *str;
775
776 assert(bit == S_IRUSR || bit == S_IWUSR || bit == S_IXUSR ||
777 bit == S_IRGRP || bit == S_IWGRP || bit == S_IXGRP ||
778 bit == S_IROTH || bit == S_IWOTH || bit == S_IXOTH);
779 /*
780 * TRANSLATION_NOTE
781 * The strings below will be used as part of a larger message,
782 * either:
783 * (file name) must be (owner|group|world) (read|writ|execut)able
784 * or
785 * (file name) must not be (owner|group|world) (read|writ|execut)able
786 */
787 switch (bit) {
788 case S_IRUSR:
789 str = gettext("owner readable");
790 break;
791 case S_IWUSR:
792 str = gettext("owner writable");
793 break;
794 case S_IXUSR:
795 str = gettext("owner executable");
796 break;
797 case S_IRGRP:
798 str = gettext("group readable");
799 break;
800 case S_IWGRP:
801 str = gettext("group writable");
802 break;
803 case S_IXGRP:
804 str = gettext("group executable");
805 break;
806 case S_IROTH:
807 str = gettext("world readable");
808 break;
809 case S_IWOTH:
810 str = gettext("world writable");
811 break;
812 case S_IXOTH:
813 str = gettext("world executable");
814 break;
815 }
816 if ((mode & bit) == (on ? 0 : bit)) {
817 /*
818 * TRANSLATION_NOTE
819 * The first parameter below is a file name; the second
820 * is one of the "(owner|group|world) (read|writ|execut)able"
821 * strings from above.
822 */
823 /*
824 * The code below could be simplified but not in a way
825 * that would easily translate to non-English locales.
826 */
827 if (on) {
828 (void) fprintf(stderr, gettext("%s must be %s.\n"),
829 file, str);
830 } else {
831 (void) fprintf(stderr, gettext("%s must not be %s.\n"),
832 file, str);
833 }
834 return (B_TRUE);
835 }
836 return (B_FALSE);
837 }
838
839 /*
840 * We want to make sure that no zone has its zone path as a child node
841 * (in the directory sense) of any other. We do that by comparing this
842 * zone's path to the path of all other (non-global) zones. The comparison
843 * in each case is simple: add '/' to the end of the path, then do a
844 * strncmp() of the two paths, using the length of the shorter one.
845 */
846
847 static int
848 crosscheck_zonepaths(char *path)
849 {
850 char rpath[MAXPATHLEN]; /* resolved path */
851 char path_copy[MAXPATHLEN]; /* copy of original path */
852 char rpath_copy[MAXPATHLEN]; /* copy of original rpath */
853 struct zoneent *ze;
854 int res, err;
855 FILE *cookie;
856
857 cookie = setzoneent();
858 while ((ze = getzoneent_private(cookie)) != NULL) {
859 /* Skip zones which are not installed. */
860 if (ze->zone_state < ZONE_STATE_INSTALLED) {
861 free(ze);
862 continue;
863 }
864 /* Skip the global zone and the current target zone. */
865 if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0 ||
866 strcmp(ze->zone_name, target_zone) == 0) {
867 free(ze);
868 continue;
869 }
870 if (strlen(ze->zone_path) == 0) {
871 /* old index file without path, fall back */
872 if ((err = zone_get_zonepath(ze->zone_name,
873 ze->zone_path, sizeof (ze->zone_path))) != Z_OK) {
874 errno = err;
875 zperror2(ze->zone_name,
876 gettext("could not get zone path"));
877 free(ze);
878 continue;
879 }
880 }
881 (void) snprintf(path_copy, sizeof (path_copy), "%s%s",
882 zonecfg_get_root(), ze->zone_path);
883 res = resolvepath(path_copy, rpath, sizeof (rpath));
884 if (res == -1) {
885 if (errno != ENOENT) {
886 zperror(path_copy, B_FALSE);
887 free(ze);
888 return (Z_ERR);
889 }
890 (void) printf(gettext("WARNING: zone %s is installed, "
891 "but its %s %s does not exist.\n"), ze->zone_name,
892 "zonepath", path_copy);
893 free(ze);
894 continue;
895 }
896 rpath[res] = '\0';
897 (void) snprintf(path_copy, sizeof (path_copy), "%s/", path);
898 (void) snprintf(rpath_copy, sizeof (rpath_copy), "%s/", rpath);
899 if (strncmp(path_copy, rpath_copy,
900 min(strlen(path_copy), strlen(rpath_copy))) == 0) {
901 /*
902 * TRANSLATION_NOTE
903 * zonepath is a literal that should not be translated.
904 */
905 (void) fprintf(stderr, gettext("%s zonepath (%s) and "
906 "%s zonepath (%s) overlap.\n"),
907 target_zone, path, ze->zone_name, rpath);
908 free(ze);
909 return (Z_ERR);
910 }
911 free(ze);
912 }
913 endzoneent(cookie);
914 return (Z_OK);
915 }
916
917 static int
918 validate_zonepath(char *path, int cmd_num)
919 {
920 int res; /* result of last library/system call */
921 boolean_t err = B_FALSE; /* have we run into an error? */
922 struct stat stbuf;
923 struct statvfs64 vfsbuf;
924 char rpath[MAXPATHLEN]; /* resolved path */
925 char ppath[MAXPATHLEN]; /* parent path */
926 char rppath[MAXPATHLEN]; /* resolved parent path */
927 char rootpath[MAXPATHLEN]; /* root path */
928 zone_state_t state;
929
930 if (path[0] != '/') {
931 (void) fprintf(stderr,
932 gettext("%s is not an absolute path.\n"), path);
933 return (Z_ERR);
934 }
935 if ((res = resolvepath(path, rpath, sizeof (rpath))) == -1) {
936 if ((errno != ENOENT) ||
937 (cmd_num != CMD_VERIFY && cmd_num != CMD_INSTALL &&
938 cmd_num != CMD_CLONE && cmd_num != CMD_MOVE)) {
939 zperror(path, B_FALSE);
940 return (Z_ERR);
941 }
942 if (cmd_num == CMD_VERIFY) {
943 /*
944 * TRANSLATION_NOTE
945 * zoneadm is a literal that should not be translated.
946 */
947 (void) fprintf(stderr, gettext("WARNING: %s does not "
948 "exist, so it could not be verified.\nWhen "
949 "'zoneadm %s' is run, '%s' will try to create\n%s, "
950 "and '%s' will be tried again,\nbut the '%s' may "
951 "fail if:\nthe parent directory of %s is group- or "
952 "other-writable\nor\n%s overlaps with any other "
953 "installed zones.\n"), path,
954 cmd_to_str(CMD_INSTALL), cmd_to_str(CMD_INSTALL),
955 path, cmd_to_str(CMD_VERIFY),
956 cmd_to_str(CMD_VERIFY), path, path);
957 return (Z_OK);
958 }
959 /*
960 * The zonepath is supposed to be mode 700 but its
961 * parent(s) 755. So use 755 on the mkdirp() then
962 * chmod() the zonepath itself to 700.
963 */
964 if (mkdirp(path, DEFAULT_DIR_MODE) < 0) {
965 zperror(path, B_FALSE);
966 return (Z_ERR);
967 }
968 /*
969 * If the chmod() fails, report the error, but might
970 * as well continue the verify procedure.
971 */
972 if (chmod(path, S_IRWXU) != 0)
973 zperror(path, B_FALSE);
974 /*
975 * Since the mkdir() succeeded, we should not have to
976 * worry about a subsequent ENOENT, thus this should
977 * only recurse once.
978 */
979 return (validate_zonepath(path, cmd_num));
980 }
981 rpath[res] = '\0';
982 if (strcmp(path, rpath) != 0) {
983 errno = Z_RESOLVED_PATH;
984 zperror(path, B_TRUE);
985 return (Z_ERR);
986 }
987 if ((res = stat(rpath, &stbuf)) != 0) {
988 zperror(rpath, B_FALSE);
989 return (Z_ERR);
990 }
991 if (!S_ISDIR(stbuf.st_mode)) {
992 (void) fprintf(stderr, gettext("%s is not a directory.\n"),
993 rpath);
994 return (Z_ERR);
995 }
996 if (strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) {
997 (void) printf(gettext("WARNING: %s is on a temporary "
998 "file system.\n"), rpath);
999 }
1000 if (crosscheck_zonepaths(rpath) != Z_OK)
1001 return (Z_ERR);
1002 /*
1003 * Try to collect and report as many minor errors as possible
1004 * before returning, so the user can learn everything that needs
1005 * to be fixed up front.
1006 */
1007 if (stbuf.st_uid != 0) {
1008 (void) fprintf(stderr, gettext("%s is not owned by root.\n"),
1009 rpath);
1010 err = B_TRUE;
1011 }
1012 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rpath);
1013 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rpath);
1014 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rpath);
1015 err |= bad_mode_bit(stbuf.st_mode, S_IRGRP, B_FALSE, rpath);
1016 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rpath);
1017 err |= bad_mode_bit(stbuf.st_mode, S_IXGRP, B_FALSE, rpath);
1018 err |= bad_mode_bit(stbuf.st_mode, S_IROTH, B_FALSE, rpath);
1019 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rpath);
1020 err |= bad_mode_bit(stbuf.st_mode, S_IXOTH, B_FALSE, rpath);
1021
1022 (void) snprintf(ppath, sizeof (ppath), "%s/..", path);
1023 if ((res = resolvepath(ppath, rppath, sizeof (rppath))) == -1) {
1024 zperror(ppath, B_FALSE);
1025 return (Z_ERR);
1026 }
1027 rppath[res] = '\0';
1028 if ((res = stat(rppath, &stbuf)) != 0) {
1029 zperror(rppath, B_FALSE);
1030 return (Z_ERR);
1031 }
1032 /* theoretically impossible */
1033 if (!S_ISDIR(stbuf.st_mode)) {
1034 (void) fprintf(stderr, gettext("%s is not a directory.\n"),
1035 rppath);
1036 return (Z_ERR);
1037 }
1038 if (stbuf.st_uid != 0) {
1039 (void) fprintf(stderr, gettext("%s is not owned by root.\n"),
1040 rppath);
1041 err = B_TRUE;
1042 }
1043 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rppath);
1044 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rppath);
1045 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rppath);
1046 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rppath);
1047 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rppath);
1048 if (strcmp(rpath, rppath) == 0) {
1049 (void) fprintf(stderr, gettext("%s is its own parent.\n"),
1050 rppath);
1051 err = B_TRUE;
1052 }
1053
1054 if (statvfs64(rpath, &vfsbuf) != 0) {
1055 zperror(rpath, B_FALSE);
1056 return (Z_ERR);
1057 }
1058 if (strcmp(vfsbuf.f_basetype, MNTTYPE_NFS) == 0) {
1059 /*
1060 * TRANSLATION_NOTE
1061 * Zonepath and NFS are literals that should not be translated.
1062 */
1063 (void) fprintf(stderr, gettext("Zonepath %s is on an NFS "
1064 "mounted file system.\n"
1065 "\tA local file system must be used.\n"), rpath);
1066 return (Z_ERR);
1067 }
1068 if (vfsbuf.f_flag & ST_NOSUID) {
1069 /*
1070 * TRANSLATION_NOTE
1071 * Zonepath and nosuid are literals that should not be
1072 * translated.
1073 */
1074 (void) fprintf(stderr, gettext("Zonepath %s is on a nosuid "
1075 "file system.\n"), rpath);
1076 return (Z_ERR);
1077 }
1078
1079 if ((res = zone_get_state(target_zone, &state)) != Z_OK) {
1080 errno = res;
1081 zperror2(target_zone, gettext("could not get state"));
1082 return (Z_ERR);
1083 }
1084 /*
1085 * The existence of the root path is only bad in the configured state,
1086 * as it is *supposed* to be there at the installed and later states.
1087 * However, the root path is expected to be there if the zone is
1088 * detached.
1089 * State/command mismatches are caught earlier in verify_details().
1090 */
1091 if (state == ZONE_STATE_CONFIGURED && cmd_num != CMD_ATTACH) {
1092 if (snprintf(rootpath, sizeof (rootpath), "%s/root", rpath) >=
1093 sizeof (rootpath)) {
1094 /*
1095 * TRANSLATION_NOTE
1096 * Zonepath is a literal that should not be translated.
1097 */
1098 (void) fprintf(stderr,
1099 gettext("Zonepath %s is too long.\n"), rpath);
1100 return (Z_ERR);
1101 }
1102 if ((res = stat(rootpath, &stbuf)) == 0) {
1103 if (zonecfg_detached(rpath))
1104 (void) fprintf(stderr,
1105 gettext("Cannot %s detached "
1106 "zone.\nUse attach or remove %s "
1107 "directory.\n"), cmd_to_str(cmd_num),
1108 rpath);
1109 else
1110 (void) fprintf(stderr,
1111 gettext("Rootpath %s exists; "
1112 "remove or move aside prior to %s.\n"),
1113 rootpath, cmd_to_str(cmd_num));
1114 return (Z_ERR);
1115 }
1116 }
1117
1118 return (err ? Z_ERR : Z_OK);
1119 }
1120
1121 /*
1122 * The following two routines implement a simple locking mechanism to
1123 * ensure that only one instance of zoneadm at a time is able to manipulate
1124 * a given zone. The lock is built on top of an fcntl(2) lock of
1125 * [<altroot>]/var/run/zones/<zonename>.zoneadm.lock. If a zoneadm instance
1126 * can grab that lock, it is allowed to manipulate the zone.
1127 *
1128 * Since zoneadm may call external applications which in turn invoke
1129 * zoneadm again, we introduce the notion of "lock inheritance". Any
1130 * instance of zoneadm that has another instance in its ancestry is assumed
1131 * to be acting on behalf of the original zoneadm, and is thus allowed to
1132 * manipulate its zone.
1133 *
1134 * This inheritance is implemented via the _ZONEADM_LOCK_HELD environment
1135 * variable. When zoneadm is granted a lock on its zone, this environment
1136 * variable is set to 1. When it releases the lock, the variable is set to
1137 * 0. Since a child process inherits its parent's environment, checking
1138 * the state of this variable indicates whether or not any ancestor owns
1139 * the lock.
1140 */
1141 static void
1142 release_lock_file(int lockfd)
1143 {
1144 /*
1145 * If we are cleaning up from a failed attempt to lock the zone for
1146 * the first time, we might have a zone_lock_cnt of 0. In that
1147 * error case, we don't want to do anything but close the lock
1148 * file.
1149 */
1150 assert(zone_lock_cnt >= 0);
1151 if (zone_lock_cnt > 0) {
1152 assert(getenv(LOCK_ENV_VAR) != NULL);
1153 assert(atoi(getenv(LOCK_ENV_VAR)) == 1);
1154 if (--zone_lock_cnt > 0) {
1155 assert(lockfd == -1);
1156 return;
1157 }
1158 if (putenv(zoneadm_lock_not_held) != 0) {
1159 zperror(target_zone, B_TRUE);
1160 exit(Z_ERR);
1161 }
1162 }
1163 assert(lockfd >= 0);
1164 (void) close(lockfd);
1165 }
1166
1167 static int
1168 grab_lock_file(const char *zone_name, int *lockfd)
1169 {
1170 char pathbuf[PATH_MAX];
1171 struct flock flock;
1172
1173 /*
1174 * If we already have the lock, we can skip this expensive song
1175 * and dance.
1176 */
1177 if (zone_lock_cnt > 0) {
1178 zone_lock_cnt++;
1179 *lockfd = -1;
1180 return (Z_OK);
1181 }
1182 assert(getenv(LOCK_ENV_VAR) != NULL);
1183 assert(atoi(getenv(LOCK_ENV_VAR)) == 0);
1184
1185 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s", zonecfg_get_root(),
1186 ZONES_TMPDIR) >= sizeof (pathbuf)) {
1187 zerror(gettext("alternate root path is too long"));
1188 return (Z_ERR);
1189 }
1190 if (mkdir(pathbuf, S_IRWXU) < 0 && errno != EEXIST) {
1191 zerror(gettext("could not mkdir %s: %s"), pathbuf,
1192 strerror(errno));
1193 return (Z_ERR);
1194 }
1195 (void) chmod(pathbuf, S_IRWXU);
1196
1197 /*
1198 * One of these lock files is created for each zone (when needed).
1199 * The lock files are not cleaned up (except on system reboot),
1200 * but since there is only one per zone, there is no resource
1201 * starvation issue.
1202 */
1203 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s/%s.zoneadm.lock",
1204 zonecfg_get_root(), ZONES_TMPDIR, zone_name) >= sizeof (pathbuf)) {
1205 zerror(gettext("alternate root path is too long"));
1206 return (Z_ERR);
1207 }
1208 if ((*lockfd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) {
1209 zerror(gettext("could not open %s: %s"), pathbuf,
1210 strerror(errno));
1211 return (Z_ERR);
1212 }
1213 /*
1214 * Lock the file to synchronize with other zoneadmds
1215 */
1216 flock.l_type = F_WRLCK;
1217 flock.l_whence = SEEK_SET;
1218 flock.l_start = (off_t)0;
1219 flock.l_len = (off_t)0;
1220 if ((fcntl(*lockfd, F_SETLKW, &flock) < 0) ||
1221 (putenv(zoneadm_lock_held) != 0)) {
1222 zerror(gettext("unable to lock %s: %s"), pathbuf,
1223 strerror(errno));
1224 release_lock_file(*lockfd);
1225 return (Z_ERR);
1226 }
1227 zone_lock_cnt = 1;
1228 return (Z_OK);
1229 }
1230
1231 static boolean_t
1232 get_doorname(const char *zone_name, char *buffer)
1233 {
1234 return (snprintf(buffer, PATH_MAX, "%s" ZONE_DOOR_PATH,
1235 zonecfg_get_root(), zone_name) < PATH_MAX);
1236 }
1237
1238 /*
1239 * system daemons are not audited. For the global zone, this occurs
1240 * "naturally" since init is started with the default audit
1241 * characteristics. Since zoneadmd is a system daemon and it starts
1242 * init for a zone, it is necessary to clear out the audit
1243 * characteristics inherited from whomever started zoneadmd. This is
1244 * indicated by the audit id, which is set from the ruid parameter of
1245 * adt_set_user(), below.
1246 */
1247
1248 static void
1249 prepare_audit_context()
1250 {
1251 adt_session_data_t *ah;
1252 char *failure = gettext("audit failure: %s");
1253
1254 if (adt_start_session(&ah, NULL, 0)) {
1255 zerror(failure, strerror(errno));
1256 return;
1257 }
1258 if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT,
1259 ADT_NO_AUDIT, ADT_NO_AUDIT, NULL, ADT_NEW)) {
1260 zerror(failure, strerror(errno));
1261 (void) adt_end_session(ah);
1262 return;
1263 }
1264 if (adt_set_proc(ah))
1265 zerror(failure, strerror(errno));
1266
1267 (void) adt_end_session(ah);
1268 }
1269
1270 static int
1271 start_zoneadmd(const char *zone_name)
1272 {
1273 char doorpath[PATH_MAX];
1274 pid_t child_pid;
1275 int error = Z_ERR;
1276 int doorfd, lockfd;
1277 struct door_info info;
1278
1279 if (!get_doorname(zone_name, doorpath))
1280 return (Z_ERR);
1281
1282 if (grab_lock_file(zone_name, &lockfd) != Z_OK)
1283 return (Z_ERR);
1284
1285 /*
1286 * Now that we have the lock, re-confirm that the daemon is
1287 * *not* up and working fine. If it is still down, we have a green
1288 * light to start it.
1289 */
1290 if ((doorfd = open(doorpath, O_RDONLY)) < 0) {
1291 if (errno != ENOENT) {
1292 zperror(doorpath, B_FALSE);
1293 goto out;
1294 }
1295 } else {
1296 if (door_info(doorfd, &info) == 0 &&
1297 ((info.di_attributes & DOOR_REVOKED) == 0)) {
1298 error = Z_OK;
1299 (void) close(doorfd);
1300 goto out;
1301 }
1302 (void) close(doorfd);
1303 }
1304
1305 if ((child_pid = fork()) == -1) {
1306 zperror(gettext("could not fork"), B_FALSE);
1307 goto out;
1308 } else if (child_pid == 0) {
1309 const char *argv[6], **ap;
1310
1311 /* child process */
1312 prepare_audit_context();
1313
1314 ap = argv;
1315 *ap++ = "zoneadmd";
1316 *ap++ = "-z";
1317 *ap++ = zone_name;
1318 if (zonecfg_in_alt_root()) {
1319 *ap++ = "-R";
1320 *ap++ = zonecfg_get_root();
1321 }
1322 *ap = NULL;
1323
1324 (void) execv("/usr/lib/zones/zoneadmd", (char * const *)argv);
1325 /*
1326 * TRANSLATION_NOTE
1327 * zoneadmd is a literal that should not be translated.
1328 */
1329 zperror(gettext("could not exec zoneadmd"), B_FALSE);
1330 _exit(Z_ERR);
1331 } else {
1332 /* parent process */
1333 pid_t retval;
1334 int pstatus = 0;
1335
1336 do {
1337 retval = waitpid(child_pid, &pstatus, 0);
1338 } while (retval != child_pid);
1339 if (WIFSIGNALED(pstatus) || (WIFEXITED(pstatus) &&
1340 WEXITSTATUS(pstatus) != 0)) {
1341 zerror(gettext("could not start %s"), "zoneadmd");
1342 goto out;
1343 }
1344 }
1345 error = Z_OK;
1346 out:
1347 release_lock_file(lockfd);
1348 return (error);
1349 }
1350
1351 static int
1352 ping_zoneadmd(const char *zone_name)
1353 {
1354 char doorpath[PATH_MAX];
1355 int doorfd;
1356 struct door_info info;
1357
1358 if (!get_doorname(zone_name, doorpath))
1359 return (Z_ERR);
1360
1361 if ((doorfd = open(doorpath, O_RDONLY)) < 0) {
1362 return (Z_ERR);
1363 }
1364 if (door_info(doorfd, &info) == 0 &&
1365 ((info.di_attributes & DOOR_REVOKED) == 0)) {
1366 (void) close(doorfd);
1367 return (Z_OK);
1368 }
1369 (void) close(doorfd);
1370 return (Z_ERR);
1371 }
1372
1373 static int
1374 call_zoneadmd(const char *zone_name, zone_cmd_arg_t *arg)
1375 {
1376 char doorpath[PATH_MAX];
1377 int doorfd, result;
1378 door_arg_t darg;
1379
1380 zoneid_t zoneid;
1381 uint64_t uniqid = 0;
1382
1383 zone_cmd_rval_t *rvalp;
1384 size_t rlen;
1385 char *cp, *errbuf;
1386
1387 rlen = getpagesize();
1388 if ((rvalp = malloc(rlen)) == NULL) {
1389 zerror(gettext("failed to allocate %lu bytes: %s"), rlen,
1390 strerror(errno));
1391 return (-1);
1392 }
1393
1394 if ((zoneid = getzoneidbyname(zone_name)) != ZONE_ID_UNDEFINED) {
1395 (void) zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid,
1396 sizeof (uniqid));
1397 }
1398 arg->uniqid = uniqid;
1399 (void) strlcpy(arg->locale, locale, sizeof (arg->locale));
1400 if (!get_doorname(zone_name, doorpath)) {
1401 zerror(gettext("alternate root path is too long"));
1402 free(rvalp);
1403 return (-1);
1404 }
1405
1406 /*
1407 * Loop trying to start zoneadmd; if something goes seriously
1408 * wrong we break out and fail.
1409 */
1410 for (;;) {
1411 if (start_zoneadmd(zone_name) != Z_OK)
1412 break;
1413
1414 if ((doorfd = open(doorpath, O_RDONLY)) < 0) {
1415 zperror(gettext("failed to open zone door"), B_FALSE);
1416 break;
1417 }
1418
1419 darg.data_ptr = (char *)arg;
1420 darg.data_size = sizeof (*arg);
1421 darg.desc_ptr = NULL;
1422 darg.desc_num = 0;
1423 darg.rbuf = (char *)rvalp;
1424 darg.rsize = rlen;
1425 if (door_call(doorfd, &darg) != 0) {
1426 (void) close(doorfd);
1427 /*
1428 * We'll get EBADF if the door has been revoked.
1429 */
1430 if (errno != EBADF) {
1431 zperror(gettext("door_call failed"), B_FALSE);
1432 break;
1433 }
1434 continue; /* take another lap */
1435 }
1436 (void) close(doorfd);
1437
1438 if (darg.data_size == 0) {
1439 /* Door server is going away; kick it again. */
1440 continue;
1441 }
1442
1443 errbuf = rvalp->errbuf;
1444 while (*errbuf != '\0') {
1445 /*
1446 * Remove any newlines since zerror()
1447 * will append one automatically.
1448 */
1449 cp = strchr(errbuf, '\n');
1450 if (cp != NULL)
1451 *cp = '\0';
1452 zerror("%s", errbuf);
1453 if (cp == NULL)
1454 break;
1455 errbuf = cp + 1;
1456 }
1457 result = rvalp->rval == 0 ? 0 : -1;
1458 free(rvalp);
1459 return (result);
1460 }
1461
1462 free(rvalp);
1463 return (-1);
1464 }
1465
1466 static int
1467 invoke_brand_handler(int cmd_num, char *argv[])
1468 {
1469 zone_dochandle_t handle;
1470 int err;
1471
1472 if ((handle = zonecfg_init_handle()) == NULL) {
1473 zperror(cmd_to_str(cmd_num), B_TRUE);
1474 return (Z_ERR);
1475 }
1476 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
1477 errno = err;
1478 zperror(cmd_to_str(cmd_num), B_TRUE);
1479 zonecfg_fini_handle(handle);
1480 return (Z_ERR);
1481 }
1482 if (verify_brand(handle, cmd_num, argv) != Z_OK) {
1483 zonecfg_fini_handle(handle);
1484 return (Z_ERR);
1485 }
1486 zonecfg_fini_handle(handle);
1487 return (Z_OK);
1488 }
1489
1490 static int
1491 ready_func(int argc, char *argv[])
1492 {
1493 zone_cmd_arg_t zarg;
1494 int arg;
1495
1496 if (zonecfg_in_alt_root()) {
1497 zerror(gettext("cannot ready zone in alternate root"));
1498 return (Z_ERR);
1499 }
1500
1501 optind = 0;
1502 if ((arg = getopt(argc, argv, "?")) != EOF) {
1503 switch (arg) {
1504 case '?':
1505 sub_usage(SHELP_READY, CMD_READY);
1506 return (optopt == '?' ? Z_OK : Z_USAGE);
1507 default:
1508 sub_usage(SHELP_READY, CMD_READY);
1509 return (Z_USAGE);
1510 }
1511 }
1512 if (argc > optind) {
1513 sub_usage(SHELP_READY, CMD_READY);
1514 return (Z_USAGE);
1515 }
1516 if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE, B_FALSE)
1517 != Z_OK)
1518 return (Z_ERR);
1519 if (verify_details(CMD_READY, argv) != Z_OK)
1520 return (Z_ERR);
1521
1522 zarg.cmd = Z_READY;
1523 if (call_zoneadmd(target_zone, &zarg) != 0) {
1524 zerror(gettext("call to %s failed"), "zoneadmd");
1525 return (Z_ERR);
1526 }
1527 return (Z_OK);
1528 }
1529
1530 static int
1531 boot_func(int argc, char *argv[])
1532 {
1533 zone_cmd_arg_t zarg;
1534 boolean_t force = B_FALSE;
1535 int arg;
1536
1537 if (zonecfg_in_alt_root()) {
1538 zerror(gettext("cannot boot zone in alternate root"));
1539 return (Z_ERR);
1540 }
1541
1542 zarg.bootbuf[0] = '\0';
1543
1544 /*
1545 * The following getopt processes arguments to zone boot; that
1546 * is to say, the [here] portion of the argument string:
1547 *
1548 * zoneadm -z myzone boot [here] -- -v -m verbose
1549 *
1550 * Where [here] can either be nothing, -? (in which case we bail
1551 * and print usage), -f (a private option to indicate that the
1552 * boot operation should be 'forced'), or -s. Support for -s is
1553 * vestigal and obsolete, but is retained because it was a
1554 * documented interface and there are known consumers including
1555 * admin/install; the proper way to specify boot arguments like -s
1556 * is:
1557 *
1558 * zoneadm -z myzone boot -- -s -v -m verbose.
1559 */
1560 optind = 0;
1561 while ((arg = getopt(argc, argv, "?fs")) != EOF) {
1562 switch (arg) {
1563 case '?':
1564 sub_usage(SHELP_BOOT, CMD_BOOT);
1565 return (optopt == '?' ? Z_OK : Z_USAGE);
1566 case 's':
1567 (void) strlcpy(zarg.bootbuf, "-s",
1568 sizeof (zarg.bootbuf));
1569 break;
1570 case 'f':
1571 force = B_TRUE;
1572 break;
1573 default:
1574 sub_usage(SHELP_BOOT, CMD_BOOT);
1575 return (Z_USAGE);
1576 }
1577 }
1578
1579 for (; optind < argc; optind++) {
1580 if (strlcat(zarg.bootbuf, argv[optind],
1581 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1582 zerror(gettext("Boot argument list too long"));
1583 return (Z_ERR);
1584 }
1585 if (optind < argc - 1)
1586 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
1587 sizeof (zarg.bootbuf)) {
1588 zerror(gettext("Boot argument list too long"));
1589 return (Z_ERR);
1590 }
1591 }
1592 if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE, force)
1593 != Z_OK)
1594 return (Z_ERR);
1595 if (verify_details(CMD_BOOT, argv) != Z_OK)
1596 return (Z_ERR);
1597 zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT;
1598 if (call_zoneadmd(target_zone, &zarg) != 0) {
1599 zerror(gettext("call to %s failed"), "zoneadmd");
1600 return (Z_ERR);
1601 }
1602
1603 return (Z_OK);
1604 }
1605
1606 static void
1607 fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr)
1608 {
1609 ssize_t result;
1610 uuid_t uuid;
1611 FILE *fp;
1612 ushort_t flags;
1613
1614 (void) memset(zeptr, 0, sizeof (*zeptr));
1615
1616 zeptr->zid = zid;
1617
1618 /*
1619 * Since we're looking up our own (non-global) zone name,
1620 * we can be assured that it will succeed.
1621 */
1622 result = getzonenamebyid(zid, zeptr->zname, sizeof (zeptr->zname));
1623 assert(result >= 0);
1624 if (zonecfg_is_scratch(zeptr->zname) &&
1625 (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
1626 (void) zonecfg_reverse_scratch(fp, zeptr->zname, zeptr->zname,
1627 sizeof (zeptr->zname), NULL, 0);
1628 zonecfg_close_scratch(fp);
1629 }
1630
1631 if (is_system_labeled()) {
1632 (void) zone_getattr(zid, ZONE_ATTR_ROOT, zeptr->zroot,
1633 sizeof (zeptr->zroot));
1634 (void) strlcpy(zeptr->zbrand, NATIVE_BRAND_NAME,
1635 sizeof (zeptr->zbrand));
1636 } else {
1637 (void) strlcpy(zeptr->zroot, "/", sizeof (zeptr->zroot));
1638 (void) zone_getattr(zid, ZONE_ATTR_BRAND, zeptr->zbrand,
1639 sizeof (zeptr->zbrand));
1640 }
1641
1642 zeptr->zstate_str = "running";
1643 if (zonecfg_get_uuid(zeptr->zname, uuid) == Z_OK &&
1644 !uuid_is_null(uuid))
1645 uuid_unparse(uuid, zeptr->zuuid);
1646
1647 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags, sizeof (flags)) < 0) {
1648 zperror2(zeptr->zname, gettext("could not get zone flags"));
1649 exit(Z_ERR);
1650 }
1651 if (flags & ZF_NET_EXCL)
1652 zeptr->ziptype = ZS_EXCLUSIVE;
1653 else
1654 zeptr->ziptype = ZS_SHARED;
1655 }
1656
1657 static int
1658 list_func(int argc, char *argv[])
1659 {
1660 zone_entry_t *zentp, zent;
1661 int arg, retv;
1662 boolean_t output = B_FALSE, verbose = B_FALSE, parsable = B_FALSE;
1663 zone_state_t min_state = ZONE_STATE_RUNNING;
1664 zoneid_t zone_id = getzoneid();
1665
1666 if (target_zone == NULL) {
1667 /* all zones: default view to running but allow override */
1668 optind = 0;
1669 while ((arg = getopt(argc, argv, "?cipv")) != EOF) {
1670 switch (arg) {
1671 case '?':
1672 sub_usage(SHELP_LIST, CMD_LIST);
1673 return (optopt == '?' ? Z_OK : Z_USAGE);
1674 /*
1675 * The 'i' and 'c' options are not mutually
1676 * exclusive so if 'c' is given, then min_state
1677 * is set to 0 (ZONE_STATE_CONFIGURED) which is
1678 * the lowest possible state. If 'i' is given,
1679 * then min_state is set to be the lowest state
1680 * so far.
1681 */
1682 case 'c':
1683 min_state = ZONE_STATE_CONFIGURED;
1684 break;
1685 case 'i':
1686 min_state = min(ZONE_STATE_INSTALLED,
1687 min_state);
1688
1689 break;
1690 case 'p':
1691 parsable = B_TRUE;
1692 break;
1693 case 'v':
1694 verbose = B_TRUE;
1695 break;
1696 default:
1697 sub_usage(SHELP_LIST, CMD_LIST);
1698 return (Z_USAGE);
1699 }
1700 }
1701 if (parsable && verbose) {
1702 zerror(gettext("%s -p and -v are mutually exclusive."),
1703 cmd_to_str(CMD_LIST));
1704 return (Z_ERR);
1705 }
1706 if (zone_id == GLOBAL_ZONEID || is_system_labeled()) {
1707 retv = zone_print_list(min_state, verbose, parsable);
1708 } else {
1709 fake_up_local_zone(zone_id, &zent);
1710 retv = Z_OK;
1711 zone_print(&zent, verbose, parsable);
1712 }
1713 return (retv);
1714 }
1715
1716 /*
1717 * Specific target zone: disallow -i/-c suboptions.
1718 */
1719 optind = 0;
1720 while ((arg = getopt(argc, argv, "?pv")) != EOF) {
1721 switch (arg) {
1722 case '?':
1723 sub_usage(SHELP_LIST, CMD_LIST);
1724 return (optopt == '?' ? Z_OK : Z_USAGE);
1725 case 'p':
1726 parsable = B_TRUE;
1727 break;
1728 case 'v':
1729 verbose = B_TRUE;
1730 break;
1731 default:
1732 sub_usage(SHELP_LIST, CMD_LIST);
1733 return (Z_USAGE);
1734 }
1735 }
1736 if (parsable && verbose) {
1737 zerror(gettext("%s -p and -v are mutually exclusive."),
1738 cmd_to_str(CMD_LIST));
1739 return (Z_ERR);
1740 }
1741 if (argc > optind) {
1742 sub_usage(SHELP_LIST, CMD_LIST);
1743 return (Z_USAGE);
1744 }
1745 if (zone_id != GLOBAL_ZONEID && !is_system_labeled()) {
1746 fake_up_local_zone(zone_id, &zent);
1747 /*
1748 * main() will issue a Z_NO_ZONE error if it cannot get an
1749 * id for target_zone, which in a non-global zone should
1750 * happen for any zone name except `zonename`. Thus we
1751 * assert() that here but don't otherwise check.
1752 */
1753 assert(strcmp(zent.zname, target_zone) == 0);
1754 zone_print(&zent, verbose, parsable);
1755 output = B_TRUE;
1756 } else if ((zentp = lookup_running_zone(target_zone)) != NULL) {
1757 zone_print(zentp, verbose, parsable);
1758 output = B_TRUE;
1759 } else if (lookup_zone_info(target_zone, ZONE_ID_UNDEFINED,
1760 &zent) == Z_OK) {
1761 zone_print(&zent, verbose, parsable);
1762 output = B_TRUE;
1763 }
1764
1765 /*
1766 * Invoke brand-specific handler. Note that we do this
1767 * only if we're in the global zone, and target_zone is specified
1768 * and it is not the global zone.
1769 */
1770 if (zone_id == GLOBAL_ZONEID && target_zone != NULL &&
1771 strcmp(target_zone, GLOBAL_ZONENAME) != 0)
1772 if (invoke_brand_handler(CMD_LIST, argv) != Z_OK)
1773 return (Z_ERR);
1774
1775 return (output ? Z_OK : Z_ERR);
1776 }
1777
1778 static void
1779 sigterm(int sig)
1780 {
1781 /*
1782 * Ignore SIG{INT,TERM}, so we don't end up in an infinite loop,
1783 * then propagate the signal to our process group.
1784 */
1785 assert(sig == SIGINT || sig == SIGTERM);
1786 (void) sigset(SIGINT, SIG_IGN);
1787 (void) sigset(SIGTERM, SIG_IGN);
1788 (void) kill(0, sig);
1789 child_killed = B_TRUE;
1790 }
1791
1792 static int
1793 do_subproc(char *cmdbuf)
1794 {
1795 char inbuf[1024]; /* arbitrary large amount */
1796 FILE *file;
1797
1798 do_subproc_cnt++;
1799 child_killed = B_FALSE;
1800 /*
1801 * We use popen(3c) to launch child processes for [un]install;
1802 * this library call does not return a PID, so we have to kill
1803 * the whole process group. To avoid killing our parent, we
1804 * become a process group leader here. But doing so can wreak
1805 * havoc with reading from stdin when launched by a non-job-control
1806 * shell, so we close stdin and reopen it as /dev/null first.
1807 */
1808 (void) close(STDIN_FILENO);
1809 (void) openat(STDIN_FILENO, "/dev/null", O_RDONLY);
1810 if (!zoneadm_is_nested)
1811 (void) setpgid(0, 0);
1812 (void) sigset(SIGINT, sigterm);
1813 (void) sigset(SIGTERM, sigterm);
1814 file = popen(cmdbuf, "r");
1815 for (;;) {
1816 if (child_killed || fgets(inbuf, sizeof (inbuf), file) == NULL)
1817 break;
1818 (void) fputs(inbuf, stdout);
1819 }
1820 (void) sigset(SIGINT, SIG_DFL);
1821 (void) sigset(SIGTERM, SIG_DFL);
1822 return (pclose(file));
1823 }
1824
1825 static int
1826 do_subproc_interactive(char *cmdbuf)
1827 {
1828 void (*saveint)(int);
1829 void (*saveterm)(int);
1830 void (*savequit)(int);
1831 void (*savehup)(int);
1832 int pid, child, status;
1833
1834 /*
1835 * do_subproc() links stdin to /dev/null, which would break any
1836 * interactive subprocess we try to launch here. Similarly, we
1837 * can't have been launched as a subprocess ourselves.
1838 */
1839 assert(do_subproc_cnt == 0 && !zoneadm_is_nested);
1840
1841 if ((child = vfork()) == 0) {
1842 (void) execl("/bin/sh", "sh", "-c", cmdbuf, (char *)NULL);
1843 }
1844
1845 if (child == -1)
1846 return (-1);
1847
1848 saveint = sigset(SIGINT, SIG_IGN);
1849 saveterm = sigset(SIGTERM, SIG_IGN);
1850 savequit = sigset(SIGQUIT, SIG_IGN);
1851 savehup = sigset(SIGHUP, SIG_IGN);
1852
1853 while ((pid = waitpid(child, &status, 0)) != child && pid != -1)
1854 ;
1855
1856 (void) sigset(SIGINT, saveint);
1857 (void) sigset(SIGTERM, saveterm);
1858 (void) sigset(SIGQUIT, savequit);
1859 (void) sigset(SIGHUP, savehup);
1860
1861 return (pid == -1 ? -1 : status);
1862 }
1863
1864 static int
1865 subproc_status(const char *cmd, int status, boolean_t verbose_failure)
1866 {
1867 if (WIFEXITED(status)) {
1868 int exit_code = WEXITSTATUS(status);
1869
1870 if ((verbose_failure) && (exit_code != ZONE_SUBPROC_OK))
1871 zerror(gettext("'%s' failed with exit code %d."), cmd,
1872 exit_code);
1873
1874 return (exit_code);
1875 } else if (WIFSIGNALED(status)) {
1876 int signal = WTERMSIG(status);
1877 char sigstr[SIG2STR_MAX];
1878
1879 if (sig2str(signal, sigstr) == 0) {
1880 zerror(gettext("'%s' terminated by signal SIG%s."), cmd,
1881 sigstr);
1882 } else {
1883 zerror(gettext("'%s' terminated by an unknown signal."),
1884 cmd);
1885 }
1886 } else {
1887 zerror(gettext("'%s' failed for unknown reasons."), cmd);
1888 }
1889
1890 /*
1891 * Assume a subprocess that died due to a signal or an unknown error
1892 * should be considered an exit code of ZONE_SUBPROC_FATAL, as the
1893 * user will likely need to do some manual cleanup.
1894 */
1895 return (ZONE_SUBPROC_FATAL);
1896 }
1897
1898 /*
1899 * Various sanity checks; make sure:
1900 * 1. We're in the global zone.
1901 * 2. The calling user has sufficient privilege.
1902 * 3. The target zone is neither the global zone nor anything starting with
1903 * "SUNW".
1904 * 4a. If we're looking for a 'not running' (i.e., configured or installed)
1905 * zone, the name service knows about it.
1906 * 4b. For some operations which expect a zone not to be running, that it is
1907 * not already running (or ready).
1908 */
1909 static int
1910 sanity_check(char *zone, int cmd_num, boolean_t running,
1911 boolean_t unsafe_when_running, boolean_t force)
1912 {
1913 zone_entry_t *zent;
1914 priv_set_t *privset;
1915 zone_state_t state, min_state;
1916 char kernzone[ZONENAME_MAX];
1917 FILE *fp;
1918
1919 if (getzoneid() != GLOBAL_ZONEID) {
1920 switch (cmd_num) {
1921 case CMD_HALT:
1922 zerror(gettext("use %s to %s this zone."), "halt(1M)",
1923 cmd_to_str(cmd_num));
1924 break;
1925 case CMD_REBOOT:
1926 zerror(gettext("use %s to %s this zone."),
1927 "reboot(1M)", cmd_to_str(cmd_num));
1928 break;
1929 default:
1930 zerror(gettext("must be in the global zone to %s a "
1931 "zone."), cmd_to_str(cmd_num));
1932 break;
1933 }
1934 return (Z_ERR);
1935 }
1936
1937 if ((privset = priv_allocset()) == NULL) {
1938 zerror(gettext("%s failed"), "priv_allocset");
1939 return (Z_ERR);
1940 }
1941
1942 if (getppriv(PRIV_EFFECTIVE, privset) != 0) {
1943 zerror(gettext("%s failed"), "getppriv");
1944 priv_freeset(privset);
1945 return (Z_ERR);
1946 }
1947
1948 if (priv_isfullset(privset) == B_FALSE) {
1949 zerror(gettext("only a privileged user may %s a zone."),
1950 cmd_to_str(cmd_num));
1951 priv_freeset(privset);
1952 return (Z_ERR);
1953 }
1954 priv_freeset(privset);
1955
1956 if (zone == NULL) {
1957 zerror(gettext("no zone specified"));
1958 return (Z_ERR);
1959 }
1960
1961 if (strcmp(zone, GLOBAL_ZONENAME) == 0) {
1962 zerror(gettext("%s operation is invalid for the global zone."),
1963 cmd_to_str(cmd_num));
1964 return (Z_ERR);
1965 }
1966
1967 if (strncmp(zone, "SUNW", 4) == 0) {
1968 zerror(gettext("%s operation is invalid for zones starting "
1969 "with SUNW."), cmd_to_str(cmd_num));
1970 return (Z_ERR);
1971 }
1972
1973 if (!is_native_zone && !is_cluster_zone && cmd_num == CMD_MOUNT) {
1974 zerror(gettext("%s operation is invalid for branded zones."),
1975 cmd_to_str(cmd_num));
1976 return (Z_ERR);
1977 }
1978
1979 if (!zonecfg_in_alt_root()) {
1980 zent = lookup_running_zone(zone);
1981 } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
1982 zent = NULL;
1983 } else {
1984 if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(),
1985 kernzone, sizeof (kernzone)) == 0)
1986 zent = lookup_running_zone(kernzone);
1987 else
1988 zent = NULL;
1989 zonecfg_close_scratch(fp);
1990 }
1991
1992 /*
1993 * Look up from the kernel for 'running' zones.
1994 */
1995 if (running && !force) {
1996 if (zent == NULL) {
1997 zerror(gettext("not running"));
1998 return (Z_ERR);
1999 }
2000 } else {
2001 int err;
2002
2003 if (unsafe_when_running && zent != NULL) {
2004 /* check whether the zone is ready or running */
2005 if ((err = zone_get_state(zent->zname,
2006 &zent->zstate_num)) != Z_OK) {
2007 errno = err;
2008 zperror2(zent->zname,
2009 gettext("could not get state"));
2010 /* can't tell, so hedge */
2011 zent->zstate_str = "ready/running";
2012 } else {
2013 zent->zstate_str =
2014 zone_state_str(zent->zstate_num);
2015 }
2016 zerror(gettext("%s operation is invalid for %s zones."),
2017 cmd_to_str(cmd_num), zent->zstate_str);
2018 return (Z_ERR);
2019 }
2020 if ((err = zone_get_state(zone, &state)) != Z_OK) {
2021 errno = err;
2022 zperror2(zone, gettext("could not get state"));
2023 return (Z_ERR);
2024 }
2025 switch (cmd_num) {
2026 case CMD_UNINSTALL:
2027 if (state == ZONE_STATE_CONFIGURED) {
2028 zerror(gettext("is already in state '%s'."),
2029 zone_state_str(ZONE_STATE_CONFIGURED));
2030 return (Z_ERR);
2031 }
2032 break;
2033 case CMD_ATTACH:
2034 case CMD_CLONE:
2035 case CMD_INSTALL:
2036 if (state == ZONE_STATE_INSTALLED) {
2037 zerror(gettext("is already %s."),
2038 zone_state_str(ZONE_STATE_INSTALLED));
2039 return (Z_ERR);
2040 } else if (state == ZONE_STATE_INCOMPLETE) {
2041 zerror(gettext("zone is %s; %s required."),
2042 zone_state_str(ZONE_STATE_INCOMPLETE),
2043 cmd_to_str(CMD_UNINSTALL));
2044 return (Z_ERR);
2045 }
2046 break;
2047 case CMD_DETACH:
2048 case CMD_MOVE:
2049 case CMD_READY:
2050 case CMD_BOOT:
2051 case CMD_MOUNT:
2052 case CMD_MARK:
2053 if ((cmd_num == CMD_BOOT || cmd_num == CMD_MOUNT) &&
2054 force)
2055 min_state = ZONE_STATE_INCOMPLETE;
2056 else
2057 min_state = ZONE_STATE_INSTALLED;
2058
2059 if (force && cmd_num == CMD_BOOT && is_native_zone) {
2060 zerror(gettext("Only branded zones may be "
2061 "force-booted."));
2062 return (Z_ERR);
2063 }
2064
2065 if (state < min_state) {
2066 zerror(gettext("must be %s before %s."),
2067 zone_state_str(min_state),
2068 cmd_to_str(cmd_num));
2069 return (Z_ERR);
2070 }
2071 break;
2072 case CMD_VERIFY:
2073 if (state == ZONE_STATE_INCOMPLETE) {
2074 zerror(gettext("zone is %s; %s required."),
2075 zone_state_str(ZONE_STATE_INCOMPLETE),
2076 cmd_to_str(CMD_UNINSTALL));
2077 return (Z_ERR);
2078 }
2079 break;
2080 case CMD_UNMOUNT:
2081 if (state != ZONE_STATE_MOUNTED) {
2082 zerror(gettext("must be %s before %s."),
2083 zone_state_str(ZONE_STATE_MOUNTED),
2084 cmd_to_str(cmd_num));
2085 return (Z_ERR);
2086 }
2087 break;
2088 }
2089 }
2090 return (Z_OK);
2091 }
2092
2093 static int
2094 halt_func(int argc, char *argv[])
2095 {
2096 zone_cmd_arg_t zarg;
2097 int arg;
2098
2099 if (zonecfg_in_alt_root()) {
2100 zerror(gettext("cannot halt zone in alternate root"));
2101 return (Z_ERR);
2102 }
2103
2104 optind = 0;
2105 if ((arg = getopt(argc, argv, "?")) != EOF) {
2106 switch (arg) {
2107 case '?':
2108 sub_usage(SHELP_HALT, CMD_HALT);
2109 return (optopt == '?' ? Z_OK : Z_USAGE);
2110 default:
2111 sub_usage(SHELP_HALT, CMD_HALT);
2112 return (Z_USAGE);
2113 }
2114 }
2115 if (argc > optind) {
2116 sub_usage(SHELP_HALT, CMD_HALT);
2117 return (Z_USAGE);
2118 }
2119 /*
2120 * zoneadmd should be the one to decide whether or not to proceed,
2121 * so even though it seems that the fourth parameter below should
2122 * perhaps be B_TRUE, it really shouldn't be.
2123 */
2124 if (sanity_check(target_zone, CMD_HALT, B_FALSE, B_FALSE, B_FALSE)
2125 != Z_OK)
2126 return (Z_ERR);
2127
2128 /*
2129 * Invoke brand-specific handler.
2130 */
2131 if (invoke_brand_handler(CMD_HALT, argv) != Z_OK)
2132 return (Z_ERR);
2133
2134 zarg.cmd = Z_HALT;
2135 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR);
2136 }
2137
2138 static int
2139 reboot_func(int argc, char *argv[])
2140 {
2141 zone_cmd_arg_t zarg;
2142 int arg;
2143
2144 if (zonecfg_in_alt_root()) {
2145 zerror(gettext("cannot reboot zone in alternate root"));
2146 return (Z_ERR);
2147 }
2148
2149 optind = 0;
2150 if ((arg = getopt(argc, argv, "?")) != EOF) {
2151 switch (arg) {
2152 case '?':
2153 sub_usage(SHELP_REBOOT, CMD_REBOOT);
2154 return (optopt == '?' ? Z_OK : Z_USAGE);
2155 default:
2156 sub_usage(SHELP_REBOOT, CMD_REBOOT);
2157 return (Z_USAGE);
2158 }
2159 }
2160
2161 zarg.bootbuf[0] = '\0';
2162 for (; optind < argc; optind++) {
2163 if (strlcat(zarg.bootbuf, argv[optind],
2164 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
2165 zerror(gettext("Boot argument list too long"));
2166 return (Z_ERR);
2167 }
2168 if (optind < argc - 1)
2169 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
2170 sizeof (zarg.bootbuf)) {
2171 zerror(gettext("Boot argument list too long"));
2172 return (Z_ERR);
2173 }
2174 }
2175
2176
2177 /*
2178 * zoneadmd should be the one to decide whether or not to proceed,
2179 * so even though it seems that the fourth parameter below should
2180 * perhaps be B_TRUE, it really shouldn't be.
2181 */
2182 if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE, B_FALSE)
2183 != Z_OK)
2184 return (Z_ERR);
2185 if (verify_details(CMD_REBOOT, argv) != Z_OK)
2186 return (Z_ERR);
2187
2188 zarg.cmd = Z_REBOOT;
2189 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR);
2190 }
2191
2192 static int
2193 verify_brand(zone_dochandle_t handle, int cmd_num, char *argv[])
2194 {
2195 char cmdbuf[MAXPATHLEN];
2196 int err;
2197 char zonepath[MAXPATHLEN];
2198 brand_handle_t bh = NULL;
2199 int status, i;
2200
2201 /*
2202 * Fetch the verify command from the brand configuration.
2203 * "exec" the command so that the returned status is that of
2204 * the command and not the shell.
2205 */
2206 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) !=
2207 Z_OK) {
2208 errno = err;
2209 zperror(cmd_to_str(cmd_num), B_TRUE);
2210 return (Z_ERR);
2211 }
2212 if ((bh = brand_open(target_brand)) == NULL) {
2213 zerror(gettext("missing or invalid brand"));
2214 return (Z_ERR);
2215 }
2216
2217 /*
2218 * If the brand has its own verification routine, execute it now.
2219 * The verification routine validates the intended zoneadm
2220 * operation for the specific brand. The zoneadm subcommand and
2221 * all its arguments are passed to the routine.
2222 */
2223 (void) strcpy(cmdbuf, EXEC_PREFIX);
2224 err = brand_get_verify_adm(bh, target_zone, zonepath,
2225 cmdbuf + EXEC_LEN, sizeof (cmdbuf) - EXEC_LEN, 0, NULL);
2226 brand_close(bh);
2227 if (err != 0)
2228 return (Z_BRAND_ERROR);
2229 if (strlen(cmdbuf) <= EXEC_LEN)
2230 return (Z_OK);
2231
2232 if (strlcat(cmdbuf, cmd_to_str(cmd_num),
2233 sizeof (cmdbuf)) >= sizeof (cmdbuf))
2234 return (Z_ERR);
2235
2236 /* Build the argv string */
2237 i = 0;
2238 while (argv[i] != NULL) {
2239 if ((strlcat(cmdbuf, " ",
2240 sizeof (cmdbuf)) >= sizeof (cmdbuf)) ||
2241 (strlcat(cmdbuf, argv[i++],
2242 sizeof (cmdbuf)) >= sizeof (cmdbuf)))
2243 return (Z_ERR);
2244 }
2245
2246 if (zoneadm_is_nested)
2247 status = do_subproc(cmdbuf);
2248 else
2249 status = do_subproc_interactive(cmdbuf);
2250 err = subproc_status(gettext("brand-specific verification"),
2251 status, B_FALSE);
2252
2253 return ((err == ZONE_SUBPROC_OK) ? Z_OK : Z_BRAND_ERROR);
2254 }
2255
2256 static int
2257 verify_rctls(zone_dochandle_t handle)
2258 {
2259 struct zone_rctltab rctltab;
2260 size_t rbs = rctlblk_size();
2261 rctlblk_t *rctlblk;
2262 int error = Z_INVAL;
2263
2264 if ((rctlblk = malloc(rbs)) == NULL) {
2265 zerror(gettext("failed to allocate %lu bytes: %s"), rbs,
2266 strerror(errno));
2267 return (Z_NOMEM);
2268 }
2269
2270 if (zonecfg_setrctlent(handle) != Z_OK) {
2271 zerror(gettext("zonecfg_setrctlent failed"));
2272 free(rctlblk);
2273 return (error);
2274 }
2275
2276 rctltab.zone_rctl_valptr = NULL;
2277 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
2278 struct zone_rctlvaltab *rctlval;
2279 const char *name = rctltab.zone_rctl_name;
2280
2281 if (!zonecfg_is_rctl(name)) {
2282 zerror(gettext("WARNING: Ignoring unrecognized rctl "
2283 "'%s'."), name);
2284 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
2285 rctltab.zone_rctl_valptr = NULL;
2286 continue;
2287 }
2288
2289 for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL;
2290 rctlval = rctlval->zone_rctlval_next) {
2291 if (zonecfg_construct_rctlblk(rctlval, rctlblk)
2292 != Z_OK) {
2293 zerror(gettext("invalid rctl value: "
2294 "(priv=%s,limit=%s,action%s)"),
2295 rctlval->zone_rctlval_priv,
2296 rctlval->zone_rctlval_limit,
2297 rctlval->zone_rctlval_action);
2298 goto out;
2299 }
2300 if (!zonecfg_valid_rctl(name, rctlblk)) {
2301 zerror(gettext("(priv=%s,limit=%s,action=%s) "
2302 "is not a valid value for rctl '%s'"),
2303 rctlval->zone_rctlval_priv,
2304 rctlval->zone_rctlval_limit,
2305 rctlval->zone_rctlval_action,
2306 name);
2307 goto out;
2308 }
2309 }
2310 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
2311 }
2312 rctltab.zone_rctl_valptr = NULL;
2313 error = Z_OK;
2314 out:
2315 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
2316 (void) zonecfg_endrctlent(handle);
2317 free(rctlblk);
2318 return (error);
2319 }
2320
2321 static int
2322 verify_pool(zone_dochandle_t handle)
2323 {
2324 char poolname[MAXPATHLEN];
2325 pool_conf_t *poolconf;
2326 pool_t *pool;
2327 int status;
2328 int error;
2329
2330 /*
2331 * This ends up being very similar to the check done in zoneadmd.
2332 */
2333 error = zonecfg_get_pool(handle, poolname, sizeof (poolname));
2334 if (error == Z_NO_ENTRY || (error == Z_OK && strlen(poolname) == 0)) {
2335 /*
2336 * No pool specified.
2337 */
2338 return (0);
2339 }
2340 if (error != Z_OK) {
2341 zperror(gettext("Unable to retrieve pool name from "
2342 "configuration"), B_TRUE);
2343 return (error);
2344 }
2345 /*
2346 * Don't do anything if pools aren't enabled.
2347 */
2348 if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED) {
2349 zerror(gettext("WARNING: pools facility not active; "
2350 "zone will not be bound to pool '%s'."), poolname);
2351 return (Z_OK);
2352 }
2353 /*
2354 * Try to provide a sane error message if the requested pool doesn't
2355 * exist. It isn't clear that pools-related failures should
2356 * necessarily translate to a failure to verify the zone configuration,
2357 * hence they are not considered errors.
2358 */
2359 if ((poolconf = pool_conf_alloc()) == NULL) {
2360 zerror(gettext("WARNING: pool_conf_alloc failed; "
2361 "using default pool"));
2362 return (Z_OK);
2363 }
2364 if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) !=
2365 PO_SUCCESS) {
2366 zerror(gettext("WARNING: pool_conf_open failed; "
2367 "using default pool"));
2368 pool_conf_free(poolconf);
2369 return (Z_OK);
2370 }
2371 pool = pool_get_pool(poolconf, poolname);
2372 (void) pool_conf_close(poolconf);
2373 pool_conf_free(poolconf);
2374 if (pool == NULL) {
2375 zerror(gettext("WARNING: pool '%s' not found. "
2376 "using default pool"), poolname);
2377 }
2378
2379 return (Z_OK);
2380 }
2381
2382 static int
2383 verify_ipd(zone_dochandle_t handle)
2384 {
2385 int return_code = Z_OK;
2386 struct zone_fstab fstab;
2387 struct stat st;
2388 char specdir[MAXPATHLEN];
2389
2390 if (zonecfg_setipdent(handle) != Z_OK) {
2391 /*
2392 * TRANSLATION_NOTE
2393 * inherit-pkg-dirs is a literal that should not be translated.
2394 */
2395 (void) fprintf(stderr, gettext("could not verify "
2396 "inherit-pkg-dirs: unable to enumerate mounts\n"));
2397 return (Z_ERR);
2398 }
2399 while (zonecfg_getipdent(handle, &fstab) == Z_OK) {
2400 /*
2401 * Verify fs_dir exists.
2402 */
2403 (void) snprintf(specdir, sizeof (specdir), "%s%s",
2404 zonecfg_get_root(), fstab.zone_fs_dir);
2405 if (stat(specdir, &st) != 0) {
2406 /*
2407 * TRANSLATION_NOTE
2408 * inherit-pkg-dir is a literal that should not be
2409 * translated.
2410 */
2411 (void) fprintf(stderr, gettext("could not verify "
2412 "inherit-pkg-dir %s: %s\n"),
2413 fstab.zone_fs_dir, strerror(errno));
2414 return_code = Z_ERR;
2415 }
2416 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2417 /*
2418 * TRANSLATION_NOTE
2419 * inherit-pkg-dir and NFS are literals that should
2420 * not be translated.
2421 */
2422 (void) fprintf(stderr, gettext("cannot verify "
2423 "inherit-pkg-dir %s: NFS mounted file system.\n"
2424 "\tA local file system must be used.\n"),
2425 fstab.zone_fs_dir);
2426 return_code = Z_ERR;
2427 }
2428 }
2429 (void) zonecfg_endipdent(handle);
2430
2431 return (return_code);
2432 }
2433
2434 /*
2435 * Verify that the special device/file system exists and is valid.
2436 */
2437 static int
2438 verify_fs_special(struct zone_fstab *fstab)
2439 {
2440 struct stat64 st;
2441
2442 /*
2443 * This validation is really intended for standard zone administration.
2444 * If we are in a mini-root or some other upgrade situation where
2445 * we are using the scratch zone, just by-pass this.
2446 */
2447 if (zonecfg_in_alt_root())
2448 return (Z_OK);
2449
2450 if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2451 return (verify_fs_zfs(fstab));
2452
2453 if (stat64(fstab->zone_fs_special, &st) != 0) {
2454 (void) fprintf(stderr, gettext("could not verify fs "
2455 "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2456 fstab->zone_fs_special, strerror(errno));
2457 return (Z_ERR);
2458 }
2459
2460 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2461 /*
2462 * TRANSLATION_NOTE
2463 * fs and NFS are literals that should
2464 * not be translated.
2465 */
2466 (void) fprintf(stderr, gettext("cannot verify "
2467 "fs %s: NFS mounted file system.\n"
2468 "\tA local file system must be used.\n"),
2469 fstab->zone_fs_special);
2470 return (Z_ERR);
2471 }
2472
2473 return (Z_OK);
2474 }
2475
2476 static int
2477 isregfile(const char *path)
2478 {
2479 struct stat64 st;
2480
2481 if (stat64(path, &st) == -1)
2482 return (-1);
2483
2484 return (S_ISREG(st.st_mode));
2485 }
2486
2487 static int
2488 verify_filesystems(zone_dochandle_t handle)
2489 {
2490 int return_code = Z_OK;
2491 struct zone_fstab fstab;
2492 char cmdbuf[MAXPATHLEN];
2493 struct stat st;
2494
2495 /*
2496 * No need to verify inherit-pkg-dir fs types, as their type is
2497 * implicitly lofs, which is known. Therefore, the types are only
2498 * verified for regular file systems below.
2499 *
2500 * Since the actual mount point is not known until the dependent mounts
2501 * are performed, we don't attempt any path validation here: that will
2502 * happen later when zoneadmd actually does the mounts.
2503 */
2504 if (zonecfg_setfsent(handle) != Z_OK) {
2505 (void) fprintf(stderr, gettext("could not verify file systems: "
2506 "unable to enumerate mounts\n"));
2507 return (Z_ERR);
2508 }
2509 while (zonecfg_getfsent(handle, &fstab) == Z_OK) {
2510 if (!zonecfg_valid_fs_type(fstab.zone_fs_type)) {
2511 (void) fprintf(stderr, gettext("cannot verify fs %s: "
2512 "type %s is not allowed.\n"), fstab.zone_fs_dir,
2513 fstab.zone_fs_type);
2514 return_code = Z_ERR;
2515 goto next_fs;
2516 }
2517 /*
2518 * Verify /usr/lib/fs/<fstype>/mount exists.
2519 */
2520 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/mount",
2521 fstab.zone_fs_type) > sizeof (cmdbuf)) {
2522 (void) fprintf(stderr, gettext("cannot verify fs %s: "
2523 "type %s is too long.\n"), fstab.zone_fs_dir,
2524 fstab.zone_fs_type);
2525 return_code = Z_ERR;
2526 goto next_fs;
2527 }
2528 if (stat(cmdbuf, &st) != 0) {
2529 (void) fprintf(stderr, gettext("could not verify fs "
2530 "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2531 cmdbuf, strerror(errno));
2532 return_code = Z_ERR;
2533 goto next_fs;
2534 }
2535 if (!S_ISREG(st.st_mode)) {
2536 (void) fprintf(stderr, gettext("could not verify fs "
2537 "%s: %s is not a regular file\n"),
2538 fstab.zone_fs_dir, cmdbuf);
2539 return_code = Z_ERR;
2540 goto next_fs;
2541 }
2542 /*
2543 * If zone_fs_raw is set, verify that there's an fsck
2544 * binary for it. If zone_fs_raw is not set, and it's
2545 * not a regular file (lofi mount), and there's an fsck
2546 * binary for it, complain.
2547 */
2548 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck",
2549 fstab.zone_fs_type) > sizeof (cmdbuf)) {
2550 (void) fprintf(stderr, gettext("cannot verify fs %s: "
2551 "type %s is too long.\n"), fstab.zone_fs_dir,
2552 fstab.zone_fs_type);
2553 return_code = Z_ERR;
2554 goto next_fs;
2555 }
2556 if (fstab.zone_fs_raw[0] != '\0' &&
2557 (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) {
2558 (void) fprintf(stderr, gettext("cannot verify fs %s: "
2559 "'raw' device specified but "
2560 "no fsck executable exists for %s\n"),
2561 fstab.zone_fs_dir, fstab.zone_fs_type);
2562 return_code = Z_ERR;
2563 goto next_fs;
2564 } else if (fstab.zone_fs_raw[0] == '\0' &&
2565 stat(cmdbuf, &st) == 0 &&
2566 isregfile(fstab.zone_fs_special) != 1) {
2567 (void) fprintf(stderr, gettext("could not verify fs "
2568 "%s: must specify 'raw' device for %s "
2569 "file systems\n"),
2570 fstab.zone_fs_dir, fstab.zone_fs_type);
2571 return_code = Z_ERR;
2572 goto next_fs;
2573 }
2574
2575 /* Verify fs_special. */
2576 if ((return_code = verify_fs_special(&fstab)) != Z_OK)
2577 goto next_fs;
2578
2579 /* Verify fs_raw. */
2580 if (fstab.zone_fs_raw[0] != '\0' &&
2581 stat(fstab.zone_fs_raw, &st) != 0) {
2582 /*
2583 * TRANSLATION_NOTE
2584 * fs is a literal that should not be translated.
2585 */
2586 (void) fprintf(stderr, gettext("could not verify fs "
2587 "%s: could not access %s: %s\n"), fstab.zone_fs_dir,
2588 fstab.zone_fs_raw, strerror(errno));
2589 return_code = Z_ERR;
2590 goto next_fs;
2591 }
2592 next_fs:
2593 zonecfg_free_fs_option_list(fstab.zone_fs_options);
2594 }
2595 (void) zonecfg_endfsent(handle);
2596
2597 return (return_code);
2598 }
2599
2600 static int
2601 verify_limitpriv(zone_dochandle_t handle)
2602 {
2603 char *privname = NULL;
2604 int err;
2605 priv_set_t *privs;
2606
2607 if ((privs = priv_allocset()) == NULL) {
2608 zperror(gettext("failed to allocate privilege set"), B_FALSE);
2609 return (Z_NOMEM);
2610 }
2611 err = zonecfg_get_privset(handle, privs, &privname);
2612 switch (err) {
2613 case Z_OK:
2614 break;
2615 case Z_PRIV_PROHIBITED:
2616 (void) fprintf(stderr, gettext("privilege \"%s\" is not "
2617 "permitted within the zone's privilege set\n"), privname);
2618 break;
2619 case Z_PRIV_REQUIRED:
2620 (void) fprintf(stderr, gettext("required privilege \"%s\" is "
2621 "missing from the zone's privilege set\n"), privname);
2622 break;
2623 case Z_PRIV_UNKNOWN:
2624 (void) fprintf(stderr, gettext("unknown privilege \"%s\" "
2625 "specified in the zone's privilege set\n"), privname);
2626 break;
2627 default:
2628 zperror(
2629 gettext("failed to determine the zone's privilege set"),
2630 B_TRUE);
2631 break;
2632 }
2633 free(privname);
2634 priv_freeset(privs);
2635 return (err);
2636 }
2637
2638 static void
2639 free_local_netifs(int if_cnt, struct net_if **if_list)
2640 {
2641 int i;
2642
2643 for (i = 0; i < if_cnt; i++) {
2644 free(if_list[i]->name);
2645 free(if_list[i]);
2646 }
2647 free(if_list);
2648 }
2649
2650 /*
2651 * Get a list of the network interfaces, along with their address families,
2652 * that are plumbed in the global zone. See if_tcp(7p) for a description
2653 * of the ioctls used here.
2654 */
2655 static int
2656 get_local_netifs(int *if_cnt, struct net_if ***if_list)
2657 {
2658 int s;
2659 int i;
2660 int res = Z_OK;
2661 int space_needed;
2662 int cnt = 0;
2663 struct lifnum if_num;
2664 struct lifconf if_conf;
2665 struct lifreq *if_reqp;
2666 char *if_buf;
2667 struct net_if **local_ifs = NULL;
2668
2669 *if_cnt = 0;
2670 *if_list = NULL;
2671
2672 if ((s = socket(SOCKET_AF(AF_INET), SOCK_DGRAM, 0)) < 0)
2673 return (Z_ERR);
2674
2675 /*
2676 * Come back here in the unlikely event that the number of interfaces
2677 * increases between the time we get the count and the time we do the
2678 * SIOCGLIFCONF ioctl.
2679 */
2680 retry:
2681 /* Get the number of interfaces. */
2682 if_num.lifn_family = AF_UNSPEC;
2683 if_num.lifn_flags = LIFC_NOXMIT;
2684 if (ioctl(s, SIOCGLIFNUM, &if_num) < 0) {
2685 (void) close(s);
2686 return (Z_ERR);
2687 }
2688
2689 /* Get the interface configuration list. */
2690 space_needed = if_num.lifn_count * sizeof (struct lifreq);
2691 if ((if_buf = malloc(space_needed)) == NULL) {
2692 (void) close(s);
2693 return (Z_ERR);
2694 }
2695 if_conf.lifc_family = AF_UNSPEC;
2696 if_conf.lifc_flags = LIFC_NOXMIT;
2697 if_conf.lifc_len = space_needed;
2698 if_conf.lifc_buf = if_buf;
2699 if (ioctl(s, SIOCGLIFCONF, &if_conf) < 0) {
2700 free(if_buf);
2701 /*
2702 * SIOCGLIFCONF returns EINVAL if the buffer we passed in is
2703 * too small. In this case go back and get the new if cnt.
2704 */
2705 if (errno == EINVAL)
2706 goto retry;
2707
2708 (void) close(s);
2709 return (Z_ERR);
2710 }
2711 (void) close(s);
2712
2713 /* Get the name and address family for each interface. */
2714 if_reqp = if_conf.lifc_req;
2715 for (i = 0; i < (if_conf.lifc_len / sizeof (struct lifreq)); i++) {
2716 struct net_if **p;
2717 struct lifreq req;
2718
2719 if (strcmp(LOOPBACK_IF, if_reqp->lifr_name) == 0) {
2720 if_reqp++;
2721 continue;
2722 }
2723
2724 if ((s = socket(SOCKET_AF(if_reqp->lifr_addr.ss_family),
2725 SOCK_DGRAM, 0)) == -1) {
2726 res = Z_ERR;
2727 break;
2728 }
2729
2730 (void) strncpy(req.lifr_name, if_reqp->lifr_name,
2731 sizeof (req.lifr_name));
2732 if (ioctl(s, SIOCGLIFADDR, &req) < 0) {
2733 (void) close(s);
2734 if_reqp++;
2735 continue;
2736 }
2737
2738 if ((p = (struct net_if **)realloc(local_ifs,
2739 sizeof (struct net_if *) * (cnt + 1))) == NULL) {
2740 res = Z_ERR;
2741 break;
2742 }
2743 local_ifs = p;
2744
2745 if ((local_ifs[cnt] = malloc(sizeof (struct net_if))) == NULL) {
2746 res = Z_ERR;
2747 break;
2748 }
2749
2750 if ((local_ifs[cnt]->name = strdup(if_reqp->lifr_name))
2751 == NULL) {
2752 free(local_ifs[cnt]);
2753 res = Z_ERR;
2754 break;
2755 }
2756 local_ifs[cnt]->af = req.lifr_addr.ss_family;
2757 cnt++;
2758
2759 (void) close(s);
2760 if_reqp++;
2761 }
2762
2763 free(if_buf);
2764
2765 if (res != Z_OK) {
2766 free_local_netifs(cnt, local_ifs);
2767 } else {
2768 *if_cnt = cnt;
2769 *if_list = local_ifs;
2770 }
2771
2772 return (res);
2773 }
2774
2775 static char *
2776 af2str(int af)
2777 {
2778 switch (af) {
2779 case AF_INET:
2780 return ("IPv4");
2781 case AF_INET6:
2782 return ("IPv6");
2783 default:
2784 return ("Unknown");
2785 }
2786 }
2787
2788 /*
2789 * Cross check the network interface name and address family with the
2790 * interfaces that are set up in the global zone so that we can print the
2791 * appropriate error message.
2792 */
2793 static void
2794 print_net_err(char *phys, char *addr, int af, char *msg)
2795 {
2796 int i;
2797 int local_if_cnt = 0;
2798 struct net_if **local_ifs = NULL;
2799 boolean_t found_if = B_FALSE;
2800 boolean_t found_af = B_FALSE;
2801
2802 if (get_local_netifs(&local_if_cnt, &local_ifs) != Z_OK) {
2803 (void) fprintf(stderr,
2804 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"),
2805 "net", "address", addr, "physical", phys, msg);
2806 return;
2807 }
2808
2809 for (i = 0; i < local_if_cnt; i++) {
2810 if (strcmp(phys, local_ifs[i]->name) == 0) {
2811 found_if = B_TRUE;
2812 if (af == local_ifs[i]->af) {
2813 found_af = B_TRUE;
2814 break;
2815 }
2816 }
2817 }
2818
2819 free_local_netifs(local_if_cnt, local_ifs);
2820
2821 if (!found_if) {
2822 (void) fprintf(stderr,
2823 gettext("could not verify %s %s=%s\n\t"
2824 "network interface %s is not plumbed in the global zone\n"),
2825 "net", "physical", phys, phys);
2826 return;
2827 }
2828
2829 /*
2830 * Print this error if we were unable to find the address family
2831 * for this interface. If the af variable is not initialized to
2832 * to something meaningful by the caller (not AF_UNSPEC) then we
2833 * also skip this message since it wouldn't be informative.
2834 */
2835 if (!found_af && af != AF_UNSPEC) {
2836 (void) fprintf(stderr,
2837 gettext("could not verify %s %s=%s %s=%s\n\tthe %s address "
2838 "family is not configured on this network interface in "
2839 "the\n\tglobal zone\n"),
2840 "net", "address", addr, "physical", phys, af2str(af));
2841 return;
2842 }
2843
2844 (void) fprintf(stderr,
2845 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"),
2846 "net", "address", addr, "physical", phys, msg);
2847 }
2848
2849 static int
2850 verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[])
2851 {
2852 struct zone_nwiftab nwiftab;
2853 int return_code = Z_OK;
2854 int err;
2855 boolean_t in_alt_root;
2856 zone_iptype_t iptype;
2857 dlpi_handle_t dh;
2858
2859 in_alt_root = zonecfg_in_alt_root();
2860 if (in_alt_root)
2861 goto no_net;
2862
2863 if ((err = zonecfg_get_iptype(handle, &iptype)) != Z_OK) {
2864 errno = err;
2865 zperror(cmd_to_str(cmd_num), B_TRUE);
2866 zonecfg_fini_handle(handle);
2867 return (Z_ERR);
2868 }
2869 if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
2870 errno = err;
2871 zperror(cmd_to_str(cmd_num), B_TRUE);
2872 zonecfg_fini_handle(handle);
2873 return (Z_ERR);
2874 }
2875 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
2876 struct lifreq lifr;
2877 sa_family_t af = AF_UNSPEC;
2878 char dl_owner_zname[ZONENAME_MAX];
2879 zoneid_t dl_owner_zid;
2880 zoneid_t target_zid;
2881 int res;
2882
2883 /* skip any loopback interfaces */
2884 if (strcmp(nwiftab.zone_nwif_physical, "lo0") == 0)
2885 continue;
2886 switch (iptype) {
2887 case ZS_SHARED:
2888 if ((res = zonecfg_valid_net_address(
2889 nwiftab.zone_nwif_address, &lifr)) != Z_OK) {
2890 print_net_err(nwiftab.zone_nwif_physical,
2891 nwiftab.zone_nwif_address, af,
2892 zonecfg_strerror(res));
2893 return_code = Z_ERR;
2894 continue;
2895 }
2896 af = lifr.lifr_addr.ss_family;
2897 if (!zonecfg_ifname_exists(af,
2898 nwiftab.zone_nwif_physical)) {
2899 /*
2900 * The interface failed to come up. We continue
2901 * on anyway for the sake of consistency: a
2902 * zone is not shut down if the interface fails
2903 * any time after boot, nor does the global zone
2904 * fail to boot if an interface fails.
2905 */
2906 (void) fprintf(stderr,
2907 gettext("WARNING: skipping network "
2908 "interface '%s' which may not be "
2909 "present/plumbed in the global "
2910 "zone.\n"),
2911 nwiftab.zone_nwif_physical);
2912 }
2913 break;
2914 case ZS_EXCLUSIVE:
2915 /* Warning if it exists for either IPv4 or IPv6 */
2916
2917 if (zonecfg_ifname_exists(AF_INET,
2918 nwiftab.zone_nwif_physical) ||
2919 zonecfg_ifname_exists(AF_INET6,
2920 nwiftab.zone_nwif_physical)) {
2921 (void) fprintf(stderr,
2922 gettext("WARNING: skipping network "
2923 "interface '%s' which is used in the "
2924 "global zone.\n"),
2925 nwiftab.zone_nwif_physical);
2926 break;
2927 }
2928
2929 /*
2930 * Verify that the physical interface can be opened.
2931 */
2932 err = dlpi_open(nwiftab.zone_nwif_physical, &dh, 0);
2933 if (err != DLPI_SUCCESS) {
2934 (void) fprintf(stderr,
2935 gettext("WARNING: skipping network "
2936 "interface '%s' which cannot be opened: "
2937 "dlpi error (%s).\n"),
2938 nwiftab.zone_nwif_physical,
2939 dlpi_strerror(err));
2940 break;
2941 } else {
2942 dlpi_close(dh);
2943 }
2944 /*
2945 * Verify whether the physical interface is already
2946 * used by a zone.
2947 */
2948 dl_owner_zid = ALL_ZONES;
2949 if (zone_check_datalink(&dl_owner_zid,
2950 nwiftab.zone_nwif_physical) != 0)
2951 break;
2952
2953 /*
2954 * If the zone being verified is
2955 * running and owns the interface
2956 */
2957 target_zid = getzoneidbyname(target_zone);
2958 if (target_zid == dl_owner_zid)
2959 break;
2960
2961 /* Zone id match failed, use name to check */
2962 if (getzonenamebyid(dl_owner_zid, dl_owner_zname,
2963 ZONENAME_MAX) < 0) {
2964 /* No name, show ID instead */
2965 (void) snprintf(dl_owner_zname, ZONENAME_MAX,
2966 "<%d>", dl_owner_zid);
2967 } else if (strcmp(dl_owner_zname, target_zone) == 0)
2968 break;
2969
2970 /*
2971 * Note here we only report a warning that
2972 * the interface is already in use by another
2973 * running zone, and the verify process just
2974