Print this page




   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
  25  * Copyright 2015, Joyent Inc. All rights reserved.
  26  * Copyright (c) 2015 by Delphix. All rights reserved.

  27  */
  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>


  90 #include "zoneadm.h"
  91 
  92 #define MAXARGS 8
  93 #define SOURCE_ZONE (CMD_MAX + 1)
  94 
  95 /* Reflects kernel zone entries */
  96 typedef struct zone_entry {
  97         zoneid_t        zid;
  98         char            zname[ZONENAME_MAX];
  99         char            *zstate_str;
 100         zone_state_t    zstate_num;
 101         char            zbrand[MAXNAMELEN];
 102         char            zroot[MAXPATHLEN];
 103         char            zuuid[UUID_PRINTABLE_STRING_LENGTH];
 104         zone_iptype_t   ziptype;
 105         zoneid_t        zdid;
 106 } zone_entry_t;
 107 
 108 #define CLUSTER_BRAND_NAME      "cluster"
 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 


 388 {
 389         (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str,
 390             zonecfg_strerror(errno));
 391 }
 392 
 393 /* PRINTFLIKE1 */
 394 void
 395 zerror(const char *fmt, ...)
 396 {
 397         va_list alist;
 398 
 399         va_start(alist, fmt);
 400         (void) fprintf(stderr, "%s: ", execname);
 401         if (target_zone != NULL)
 402                 (void) fprintf(stderr, "zone '%s': ", target_zone);
 403         (void) vfprintf(stderr, fmt, alist);
 404         (void) fprintf(stderr, "\n");
 405         va_end(alist);
 406 }
 407 













 408 static void
 409 zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable)
 410 {
 411         static boolean_t firsttime = B_TRUE;
 412         char *ip_type_str;
 413 
 414         /* Skip a zone that shutdown while we were collecting data. */
 415         if (zent->zname[0] == '\0')
 416                 return;
 417 
 418         if (zent->ziptype == ZS_EXCLUSIVE)
 419                 ip_type_str = "excl";
 420         else
 421                 ip_type_str = "shared";
 422 
 423         assert(!(verbose && parsable));
 424         if (firsttime && verbose) {
 425                 firsttime = B_FALSE;
 426                 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
 427                     ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",


 459                 else
 460                         (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
 461                 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
 462                     zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
 463         }
 464 }
 465 
 466 static int
 467 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
 468 {
 469         char root[MAXPATHLEN], *cp;
 470         int err;
 471         uuid_t uuid;
 472         zone_dochandle_t handle;
 473 
 474         (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname));
 475         (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot));
 476         (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand));
 477         zent->zstate_str = "???";
 478 
 479         if (strcmp(zone_name, GLOBAL_ZONENAME) == 0)
 480                 zid = zent->zdid = GLOBAL_ZONEID;
 481 
 482         zent->zid = zid;
 483 
 484         if (zonecfg_get_uuid(zone_name, uuid) == Z_OK &&
 485             !uuid_is_null(uuid))
 486                 uuid_unparse(uuid, zent->zuuid);
 487         else
 488                 zent->zuuid[0] = '\0';
 489 
 490         /*
 491          * For labeled zones which query the zone path of lower-level
 492          * zones, the path needs to be adjusted to drop the final
 493          * "/root" component. This adjusted path is then useful
 494          * for reading down any exported directories from the
 495          * lower-level zone.
 496          */
 497         if (is_system_labeled() && zent->zid != ZONE_ID_UNDEFINED) {
 498                 if (zone_getattr(zent->zid, ZONE_ATTR_ROOT, zent->zroot,
 499                     sizeof (zent->zroot)) == -1) {
 500                         zperror2(zent->zname,
 501                             gettext("could not get zone path."));


 506                         *cp = 0;
 507         } else {
 508                 if ((err = zone_get_zonepath(zent->zname, root,
 509                     sizeof (root))) != Z_OK) {
 510                         errno = err;
 511                         zperror2(zent->zname,
 512                             gettext("could not get zone path."));
 513                         return (Z_ERR);
 514                 }
 515                 (void) strlcpy(zent->zroot, root, sizeof (zent->zroot));
 516         }
 517 
 518         if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) {
 519                 errno = err;
 520                 zperror2(zent->zname, gettext("could not get state"));
 521                 return (Z_ERR);
 522         }
 523         zent->zstate_str = zone_state_str(zent->zstate_num);
 524 
 525         /*
 526          * A zone's brand might only be available in the .xml file describing
 527          * it, which is only visible to the global zone.  This causes
 528          * zone_get_brand() to fail when called from within a non-global
 529          * zone.  Fortunately we only do this on labeled systems, where we
 530          * know all zones are native.
 531          */
 532         if (getzoneid() != GLOBAL_ZONEID) {
 533                 assert(is_system_labeled() != 0);
 534                 (void) strlcpy(zent->zbrand, default_brand,
 535                     sizeof (zent->zbrand));
 536         } else if (zone_get_brand(zent->zname, zent->zbrand,
 537             sizeof (zent->zbrand)) != Z_OK) {
 538                 zperror2(zent->zname, gettext("could not get brand name"));
 539                 return (Z_ERR);
 540         }
 541 
 542         /*
 543          * Get ip type of the zone.
 544          * Note for global zone, ZS_SHARED is set always.
 545          */
 546         if (zid == GLOBAL_ZONEID) {
 547                 zent->ziptype = ZS_SHARED;


 577         if (zent->zstate_num == ZONE_STATE_RUNNING &&
 578             zid != ZONE_ID_UNDEFINED) {
 579                 ushort_t flags;
 580 
 581                 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
 582                     sizeof (flags)) >= 0) {
 583                         if (flags & ZF_NET_EXCL)
 584                                 zent->ziptype = ZS_EXCLUSIVE;
 585                         else
 586                                 zent->ziptype = ZS_SHARED;
 587                 }
 588         }
 589 
 590         zent->zdid = zonecfg_get_did(handle);
 591 
 592         zonecfg_fini_handle(handle);
 593 
 594         return (Z_OK);
 595 }
 596 












 597 static int
 598 zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
 599 {
 600         zone_entry_t zent;
 601         FILE *cookie;
 602         struct zoneent *ze;




 603 
 604         /*
 605          * Get the full list of zones from the configuration.
 606          */
 607         cookie = setzoneent();
 608         while ((ze = getzoneent_private(cookie)) != NULL) {
 609                 char *name = ze->zone_name;
 610                 zoneid_t zid;
 611 
 612                 zid = getzoneidbyname(name);



 613 
 614                 if (ze->zone_brand[0] == '\0') {
 615                         /* old, incomplete index entry */
 616                         if (lookup_zone_info(name, zid, &zent) != Z_OK) {
 617                                 free(ze);
 618                                 continue;






 619                         }
 620                 } else {
 621                         /* new, full index entry */
 622                         (void) strlcpy(zent.zname, name, sizeof (zent.zname));
 623                         (void) strlcpy(zent.zroot, ze->zone_path,
 624                             sizeof (zent.zroot));
 625                         uuid_unparse(ze->zone_uuid, zent.zuuid);
 626                         (void) strlcpy(zent.zbrand, ze->zone_brand,
 627                             sizeof (zent.zbrand));
 628                         zent.ziptype = ze->zone_iptype;
 629                         zent.zdid = ze->zone_did;
 630                         zent.zid = zid;
 631 
 632                         if (zid != -1) {
 633                                 int err;
 634 
 635                                 err = zone_get_state(name,
 636                                     (zone_state_t *)&ze->zone_state);
 637                                 if (err != Z_OK) {
 638                                         errno = err;
 639                                         zperror2(name, gettext("could not get "
 640                                             "state"));
 641                                         free(ze);














 642                                         continue;
 643                                 }












 644                         }
 645 
 646                         zent.zstate_num = ze->zone_state;
 647                         zent.zstate_str = zone_state_str(zent.zstate_num);





 648                 }














 649 














































 650                 if (zent.zstate_num >= min_state)
 651                         zone_print(&zent, verbose, parsable);
 652 
 653                 free(ze);
 654         }
 655         endzoneent(cookie);
 656         return (Z_OK);
 657 }
 658 
 659 /*
 660  * Retrieve a zone entry by name.  Returns NULL if no such zone exists.
 661  */
 662 static zone_entry_t *
 663 lookup_running_zone(const char *name)
 664 {
 665         zoneid_t zid;
 666         zone_entry_t *zent;
 667 
 668         if ((zid = getzoneidbyname(name)) == -1)
 669                 return (NULL);
 670 
 671         if ((zent = malloc(sizeof (zone_entry_t))) == NULL)
 672                 return (NULL);
 673 


 894         }
 895         rpath[res] = '\0';
 896         if (strcmp(path, rpath) != 0) {
 897                 errno = Z_RESOLVED_PATH;
 898                 zperror(path, B_TRUE);
 899                 return (Z_ERR);
 900         }
 901         if ((res = stat(rpath, &stbuf)) != 0) {
 902                 zperror(rpath, B_FALSE);
 903                 return (Z_ERR);
 904         }
 905         if (!S_ISDIR(stbuf.st_mode)) {
 906                 (void) fprintf(stderr, gettext("%s is not a directory.\n"),
 907                     rpath);
 908                 return (Z_ERR);
 909         }
 910         if (strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) {
 911                 (void) printf(gettext("WARNING: %s is on a temporary "
 912                     "file system.\n"), rpath);
 913         }
 914         if (cmd_num != CMD_BOOT && cmd_num != CMD_REBOOT &&
 915             cmd_num != CMD_READY) {
 916                 /* we checked when we installed, no need to check each boot */
 917                 if (crosscheck_zonepaths(rpath) != Z_OK)
 918                         return (Z_ERR);
 919         }
 920         /*
 921          * Try to collect and report as many minor errors as possible
 922          * before returning, so the user can learn everything that needs
 923          * to be fixed up front.
 924          */
 925         if (stbuf.st_uid != 0) {
 926                 (void) fprintf(stderr, gettext("%s is not owned by root.\n"),
 927                     rpath);
 928                 err = B_TRUE;
 929 
 930                 /* Try to change owner */
 931                 if (cmd_num != CMD_VERIFY) {
 932                         (void) fprintf(stderr, gettext("%s: changing owner "
 933                             "to root.\n"), rpath);
 934                         if (chown(rpath, 0, -1) != 0) {
 935                                 zperror(rpath, B_FALSE);
 936                                 return (Z_ERR);
 937                         } else {
 938                                 err = B_FALSE;
 939                         }


1086                 return (Z_ERR);
1087         }
1088         if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
1089                 errno = err;
1090                 zperror(cmd_to_str(cmd_num), B_TRUE);
1091                 zonecfg_fini_handle(handle);
1092                 return (Z_ERR);
1093         }
1094         if (verify_brand(handle, cmd_num, argv) != Z_OK) {
1095                 zonecfg_fini_handle(handle);
1096                 return (Z_ERR);
1097         }
1098         zonecfg_fini_handle(handle);
1099         return (Z_OK);
1100 }
1101 
1102 static int
1103 ready_func(int argc, char *argv[])
1104 {
1105         zone_cmd_arg_t zarg;
1106         boolean_t debug = B_FALSE;
1107         int arg;
1108 
1109         if (zonecfg_in_alt_root()) {
1110                 zerror(gettext("cannot ready zone in alternate root"));
1111                 return (Z_ERR);
1112         }
1113 
1114         optind = 0;
1115         if ((arg = getopt(argc, argv, "?X")) != EOF) {
1116                 switch (arg) {
1117                 case '?':
1118                         sub_usage(SHELP_READY, CMD_READY);
1119                         return (optopt == '?' ? Z_OK : Z_USAGE);
1120                 case 'X':
1121                         debug = B_TRUE;
1122                         break;
1123                 default:
1124                         sub_usage(SHELP_READY, CMD_READY);
1125                         return (Z_USAGE);
1126                 }
1127         }
1128         if (argc > optind) {
1129                 sub_usage(SHELP_READY, CMD_READY);
1130                 return (Z_USAGE);
1131         }
1132         if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE, B_FALSE)
1133             != Z_OK)
1134                 return (Z_ERR);
1135         if (verify_details(CMD_READY, argv) != Z_OK)
1136                 return (Z_ERR);
1137 
1138         zarg.cmd = Z_READY;
1139         zarg.debug = debug;
1140         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1141                 zerror(gettext("call to %s failed"), "zoneadmd");
1142                 return (Z_ERR);
1143         }
1144         return (Z_OK);
1145 }
1146 
1147 static int
1148 boot_func(int argc, char *argv[])
1149 {
1150         zone_cmd_arg_t zarg;
1151         boolean_t force = B_FALSE;
1152         boolean_t debug = B_FALSE;
1153         int arg;
1154 
1155         if (zonecfg_in_alt_root()) {
1156                 zerror(gettext("cannot boot zone in alternate root"));
1157                 return (Z_ERR);
1158         }
1159 
1160         zarg.bootbuf[0] = '\0';
1161 
1162         /*
1163          * The following getopt processes arguments to zone boot; that
1164          * is to say, the [here] portion of the argument string:
1165          *
1166          *      zoneadm -z myzone boot [here] -- -v -m verbose
1167          *
1168          * Where [here] can either be nothing, -? (in which case we bail
1169          * and print usage), -f (a private option to indicate that the
1170          * boot operation should be 'forced'), or -s.  Support for -s is
1171          * vestigal and obsolete, but is retained because it was a
1172          * documented interface and there are known consumers including
1173          * admin/install; the proper way to specify boot arguments like -s
1174          * is:
1175          *
1176          *      zoneadm -z myzone boot -- -s -v -m verbose.
1177          */
1178         optind = 0;
1179         while ((arg = getopt(argc, argv, "?fsX")) != EOF) {
1180                 switch (arg) {
1181                 case '?':
1182                         sub_usage(SHELP_BOOT, CMD_BOOT);
1183                         return (optopt == '?' ? Z_OK : Z_USAGE);
1184                 case 's':
1185                         (void) strlcpy(zarg.bootbuf, "-s",
1186                             sizeof (zarg.bootbuf));
1187                         break;
1188                 case 'f':
1189                         force = B_TRUE;
1190                         break;
1191                 case 'X':
1192                         debug = B_TRUE;
1193                         break;
1194                 default:
1195                         sub_usage(SHELP_BOOT, CMD_BOOT);
1196                         return (Z_USAGE);
1197                 }
1198         }
1199 
1200         for (; optind < argc; optind++) {
1201                 if (strlcat(zarg.bootbuf, argv[optind],
1202                     sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1203                         zerror(gettext("Boot argument list too long"));
1204                         return (Z_ERR);
1205                 }
1206                 if (optind < argc - 1)
1207                         if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
1208                             sizeof (zarg.bootbuf)) {
1209                                 zerror(gettext("Boot argument list too long"));
1210                                 return (Z_ERR);
1211                         }
1212         }
1213         if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE, force)
1214             != Z_OK)
1215                 return (Z_ERR);
1216         if (verify_details(CMD_BOOT, argv) != Z_OK)
1217                 return (Z_ERR);
1218         zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT;
1219         zarg.debug = debug;
1220         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1221                 zerror(gettext("call to %s failed"), "zoneadmd");
1222                 return (Z_ERR);
1223         }
1224 
1225         return (Z_OK);
1226 }
1227 
1228 static void
1229 fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr)
1230 {
1231         ssize_t result;
1232         uuid_t uuid;
1233         FILE *fp;
1234         ushort_t flags;
1235 
1236         (void) memset(zeptr, 0, sizeof (*zeptr));
1237 
1238         zeptr->zid = zid;
1239 


1509                 if (setuid(0) == -1) {
1510                         zperror(gettext("insufficient privilege"), B_TRUE);
1511                         return (Z_ERR);
1512                 }
1513                 return (Z_OK);
1514         }
1515 }
1516 
1517 /*
1518  * Various sanity checks; make sure:
1519  * 1. We're in the global zone.
1520  * 2. The calling user has sufficient privilege.
1521  * 3. The target zone is neither the global zone nor anything starting with
1522  *    "SUNW".
1523  * 4a. If we're looking for a 'not running' (i.e., configured or installed)
1524  *     zone, the name service knows about it.
1525  * 4b. For some operations which expect a zone not to be running, that it is
1526  *     not already running (or ready).
1527  */
1528 static int
1529 sanity_check(char *zone, int cmd_num, boolean_t need_running,
1530     boolean_t unsafe_when_running, boolean_t force)
1531 {
1532         boolean_t is_running = B_FALSE;
1533         priv_set_t *privset;
1534         zone_state_t state, min_state;
1535         char kernzone[ZONENAME_MAX];
1536         FILE *fp;
1537 
1538         if (getzoneid() != GLOBAL_ZONEID) {
1539                 switch (cmd_num) {
1540                 case CMD_HALT:
1541                         zerror(gettext("use %s to %s this zone."), "halt(1M)",
1542                             cmd_to_str(cmd_num));
1543                         break;
1544                 case CMD_SHUTDOWN:
1545                         zerror(gettext("use %s to %s this zone."),
1546                             "shutdown(1M)", cmd_to_str(cmd_num));
1547                         break;
1548                 case CMD_REBOOT:
1549                         zerror(gettext("use %s to %s this zone."),
1550                             "reboot(1M)", cmd_to_str(cmd_num));
1551                         break;
1552                 default:


1583 
1584         if (auth_check(username, zone, cmd_num) == Z_ERR) {
1585                 zerror(gettext("User %s is not authorized to %s this zone."),
1586                     username, cmd_to_str(cmd_num));
1587                 return (Z_ERR);
1588         }
1589 
1590         if (strcmp(zone, GLOBAL_ZONENAME) == 0) {
1591                 zerror(gettext("%s operation is invalid for the global zone."),
1592                     cmd_to_str(cmd_num));
1593                 return (Z_ERR);
1594         }
1595 
1596         if (strncmp(zone, "SUNW", 4) == 0) {
1597                 zerror(gettext("%s operation is invalid for zones starting "
1598                     "with SUNW."), cmd_to_str(cmd_num));
1599                 return (Z_ERR);
1600         }
1601 
1602         if (!zonecfg_in_alt_root()) {
1603                 /* Avoid the xml read overhead of lookup_running_zone */
1604                 if (getzoneidbyname(zone) != -1)
1605                         is_running = B_TRUE;
1606 
1607         } else if ((fp = zonecfg_open_scratch("", B_FALSE)) != NULL) {
1608                 if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), kernzone,
1609                     sizeof (kernzone)) == 0 && getzoneidbyname(kernzone) != -1)
1610                         is_running = B_TRUE;
1611 
1612                 zonecfg_close_scratch(fp);
1613         }
1614 
1615         /*
1616          * Look up from the kernel for 'running' zones.
1617          */
1618         if (need_running && !force) {
1619                 if (!is_running) {
1620                         zerror(gettext("not running"));
1621                         return (Z_ERR);
1622                 }
1623         } else {
1624                 int err;
1625 
1626                 err = zone_get_state(zone, &state);
1627 
1628                 if (unsafe_when_running && is_running) {
1629                         /* check whether the zone is ready or running */
1630                         char *zstate_str;
1631 
1632                         if (err != Z_OK) {
1633                                 errno = err;
1634                                 zperror2(zone, gettext("could not get state"));

1635                                 /* can't tell, so hedge */
1636                                 zstate_str = "ready/running";
1637                         } else {
1638                                 zstate_str = zone_state_str(state);

1639                         }
1640                         zerror(gettext("%s operation is invalid for %s zones."),
1641                             cmd_to_str(cmd_num), zstate_str);
1642                         return (Z_ERR);
1643                 }
1644 
1645                 if (err != Z_OK) {
1646                         errno = err;
1647                         zperror2(zone, gettext("could not get state"));
1648                         return (Z_ERR);
1649                 }
1650 
1651                 switch (cmd_num) {
1652                 case CMD_UNINSTALL:
1653                         if (state == ZONE_STATE_CONFIGURED) {
1654                                 zerror(gettext("is already in state '%s'."),
1655                                     zone_state_str(ZONE_STATE_CONFIGURED));
1656                                 return (Z_ERR);
1657                         }
1658                         break;
1659                 case CMD_ATTACH:
1660                         if (state == ZONE_STATE_INSTALLED) {
1661                                 zerror(gettext("is already %s."),
1662                                     zone_state_str(ZONE_STATE_INSTALLED));
1663                                 return (Z_ERR);
1664                         } else if (state == ZONE_STATE_INCOMPLETE && !force) {
1665                                 zerror(gettext("zone is %s; %s required."),
1666                                     zone_state_str(ZONE_STATE_INCOMPLETE),
1667                                     cmd_to_str(CMD_UNINSTALL));
1668                                 return (Z_ERR);
1669                         }
1670                         break;


1718                                 return (Z_ERR);
1719                         }
1720                         break;
1721                 case CMD_SYSBOOT:
1722                         if (state != ZONE_STATE_INSTALLED) {
1723                                 zerror(gettext("%s operation is invalid for %s "
1724                                     "zones."), cmd_to_str(cmd_num),
1725                                     zone_state_str(state));
1726                                 return (Z_ERR);
1727                         }
1728                         break;
1729                 }
1730         }
1731         return (Z_OK);
1732 }
1733 
1734 static int
1735 halt_func(int argc, char *argv[])
1736 {
1737         zone_cmd_arg_t zarg;
1738         boolean_t debug = B_FALSE;
1739         int arg;
1740 
1741         if (zonecfg_in_alt_root()) {
1742                 zerror(gettext("cannot halt zone in alternate root"));
1743                 return (Z_ERR);
1744         }
1745 
1746         optind = 0;
1747         if ((arg = getopt(argc, argv, "?X")) != EOF) {
1748                 switch (arg) {
1749                 case '?':
1750                         sub_usage(SHELP_HALT, CMD_HALT);
1751                         return (optopt == '?' ? Z_OK : Z_USAGE);
1752                 case 'X':
1753                         debug = B_TRUE;
1754                         break;
1755                 default:
1756                         sub_usage(SHELP_HALT, CMD_HALT);
1757                         return (Z_USAGE);
1758                 }
1759         }
1760         if (argc > optind) {
1761                 sub_usage(SHELP_HALT, CMD_HALT);
1762                 return (Z_USAGE);
1763         }
1764         /*
1765          * zoneadmd should be the one to decide whether or not to proceed,
1766          * so even though it seems that the fourth parameter below should
1767          * perhaps be B_TRUE, it really shouldn't be.
1768          */
1769         if (sanity_check(target_zone, CMD_HALT, B_FALSE, B_FALSE, B_FALSE)
1770             != Z_OK)
1771                 return (Z_ERR);
1772 
1773         /*
1774          * Invoke brand-specific handler.
1775          */
1776         if (invoke_brand_handler(CMD_HALT, argv) != Z_OK)
1777                 return (Z_ERR);
1778 
1779         zarg.cmd = Z_HALT;
1780         zarg.debug = debug;
1781         return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale,
1782             B_TRUE) == 0) ?  Z_OK : Z_ERR);
1783 }
1784 
1785 static int
1786 shutdown_func(int argc, char *argv[])
1787 {
1788         zone_cmd_arg_t zarg;
1789         int arg;
1790         boolean_t reboot = B_FALSE;
1791 
1792         zarg.cmd = Z_SHUTDOWN;
1793 
1794         if (zonecfg_in_alt_root()) {
1795                 zerror(gettext("cannot shut down zone in alternate root"));
1796                 return (Z_ERR);
1797         }
1798 
1799         optind = 0;
1800         while ((arg = getopt(argc, argv, "?r")) != EOF) {


1838         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != Z_OK)
1839                 return (Z_ERR);
1840 
1841         if (reboot) {
1842                 if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE,
1843                     B_FALSE) != Z_OK)
1844                         return (Z_ERR);
1845 
1846                 zarg.cmd = Z_BOOT;
1847                 if (zonecfg_call_zoneadmd(target_zone, &zarg, locale,
1848                     B_TRUE) != Z_OK)
1849                         return (Z_ERR);
1850         }
1851         return (Z_OK);
1852 }
1853 
1854 static int
1855 reboot_func(int argc, char *argv[])
1856 {
1857         zone_cmd_arg_t zarg;
1858         boolean_t debug = B_FALSE;
1859         int arg;
1860 
1861         if (zonecfg_in_alt_root()) {
1862                 zerror(gettext("cannot reboot zone in alternate root"));
1863                 return (Z_ERR);
1864         }
1865 
1866         optind = 0;
1867         if ((arg = getopt(argc, argv, "?X")) != EOF) {
1868                 switch (arg) {
1869                 case '?':
1870                         sub_usage(SHELP_REBOOT, CMD_REBOOT);
1871                         return (optopt == '?' ? Z_OK : Z_USAGE);
1872                 case 'X':
1873                         debug = B_TRUE;
1874                         break;
1875                 default:
1876                         sub_usage(SHELP_REBOOT, CMD_REBOOT);
1877                         return (Z_USAGE);
1878                 }
1879         }
1880 
1881         zarg.bootbuf[0] = '\0';
1882         for (; optind < argc; optind++) {
1883                 if (strlcat(zarg.bootbuf, argv[optind],
1884                     sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1885                         zerror(gettext("Boot argument list too long"));
1886                         return (Z_ERR);
1887                 }
1888                 if (optind < argc - 1)
1889                         if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
1890                             sizeof (zarg.bootbuf)) {
1891                                 zerror(gettext("Boot argument list too long"));
1892                                 return (Z_ERR);
1893                         }
1894         }
1895 
1896 
1897         /*
1898          * zoneadmd should be the one to decide whether or not to proceed,
1899          * so even though it seems that the fourth parameter below should
1900          * perhaps be B_TRUE, it really shouldn't be.
1901          */
1902         if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE, B_FALSE)
1903             != Z_OK)
1904                 return (Z_ERR);
1905         if (verify_details(CMD_REBOOT, argv) != Z_OK)
1906                 return (Z_ERR);
1907 
1908         zarg.cmd = Z_REBOOT;
1909         zarg.debug = debug;
1910         return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0)
1911             ? Z_OK : Z_ERR);
1912 }
1913 
1914 static int
1915 get_hook(brand_handle_t bh, char *cmd, size_t len, int (*bp)(brand_handle_t,
1916     const char *, const char *, char *, size_t), char *zonename, char *zonepath)
1917 {
1918         if (strlcpy(cmd, EXEC_PREFIX, len) >= len)
1919                 return (Z_ERR);
1920 
1921         if (bp(bh, zonename, zonepath, cmd + EXEC_LEN, len - EXEC_LEN) != 0)
1922                 return (Z_ERR);
1923 
1924         if (strlen(cmd) <= EXEC_LEN)
1925                 cmd[0] = '\0';
1926 
1927         return (Z_OK);
1928 }
1929 


2117 
2118 /*
2119  * Verify that the special device/file system exists and is valid.
2120  */
2121 static int
2122 verify_fs_special(struct zone_fstab *fstab)
2123 {
2124         struct stat64 st;
2125 
2126         /*
2127          * This validation is really intended for standard zone administration.
2128          * If we are in a mini-root or some other upgrade situation where
2129          * we are using the scratch zone, just by-pass this.
2130          */
2131         if (zonecfg_in_alt_root())
2132                 return (Z_OK);
2133 
2134         if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2135                 return (verify_fs_zfs(fstab));
2136 
2137         if (strcmp(fstab->zone_fs_type, MNTTYPE_HYPRLOFS) == 0 &&
2138             strcmp(fstab->zone_fs_special, "swap") == 0)
2139                         return (Z_OK);
2140 
2141         if (stat64(fstab->zone_fs_special, &st) != 0) {
2142                 (void) fprintf(stderr, gettext("could not verify fs "
2143                     "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2144                     fstab->zone_fs_special, strerror(errno));
2145                 return (Z_ERR);
2146         }
2147 
2148         if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2149                 /*
2150                  * TRANSLATION_NOTE
2151                  * fs and NFS are literals that should
2152                  * not be translated.
2153                  */
2154                 (void) fprintf(stderr, gettext("cannot verify "
2155                     "fs %s: NFS mounted file system.\n"
2156                     "\tA local file system must be used.\n"),
2157                     fstab->zone_fs_special);
2158                 return (Z_ERR);
2159         }
2160 


2524                     "net", "address", addr, "physical", phys, af2str(af));
2525                 return;
2526         }
2527 
2528         (void) fprintf(stderr,
2529             gettext("could not verify %s %s=%s %s=%s\n\t%s\n"),
2530             "net", "address", addr, "physical", phys, msg);
2531 }
2532 
2533 static int
2534 verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[])
2535 {
2536         struct zone_nwiftab nwiftab;
2537         int return_code = Z_OK;
2538         int err;
2539         boolean_t in_alt_root;
2540         zone_iptype_t iptype;
2541         dladm_handle_t dh;
2542         dladm_status_t status;
2543         datalink_id_t linkid;

2544 
2545         in_alt_root = zonecfg_in_alt_root();
2546         if (in_alt_root)
2547                 goto no_net;
2548 
2549         if ((err = zonecfg_get_iptype(handle, &iptype)) != Z_OK) {
2550                 errno = err;
2551                 zperror(cmd_to_str(cmd_num), B_TRUE);
2552                 zonecfg_fini_handle(handle);
2553                 return (Z_ERR);
2554         }
2555         if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
2556                 errno = err;
2557                 zperror(cmd_to_str(cmd_num), B_TRUE);
2558                 zonecfg_fini_handle(handle);
2559                 return (Z_ERR);
2560         }
2561         while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
2562                 struct lifreq lifr;
2563                 sa_family_t af = AF_UNSPEC;


2606                             nwiftab.zone_nwif_physical)) {
2607                                 (void) fprintf(stderr,
2608                                     gettext("WARNING: skipping network "
2609                                     "interface '%s' which is used in the "
2610                                     "global zone.\n"),
2611                                     nwiftab.zone_nwif_physical);
2612                                 break;
2613                         }
2614 
2615                         /*
2616                          * Verify that the datalink exists and that it isn't
2617                          * already assigned to a zone.
2618                          */
2619                         if ((status = dladm_open(&dh)) == DLADM_STATUS_OK) {
2620                                 status = dladm_name2info(dh,
2621                                     nwiftab.zone_nwif_physical, &linkid, NULL,
2622                                     NULL, NULL);
2623                                 dladm_close(dh);
2624                         }
2625                         if (status != DLADM_STATUS_OK) {





2626                                 break;
2627                         }
2628                         dl_owner_zid = ALL_ZONES;
2629                         if (zone_check_datalink(&dl_owner_zid, linkid) != 0)
2630                                 break;
2631 
2632                         /*
2633                          * If the zone being verified is
2634                          * running and owns the interface
2635                          */
2636                         target_zid = getzoneidbyname(target_zone);
2637                         if (target_zid == dl_owner_zid)
2638                                 break;
2639 
2640                         /* Zone id match failed, use name to check */
2641                         if (getzonenamebyid(dl_owner_zid, dl_owner_zname,
2642                             ZONENAME_MAX) < 0) {
2643                                 /* No name, show ID instead */
2644                                 (void) snprintf(dl_owner_zname, ZONENAME_MAX,
2645                                     "<%d>", dl_owner_zid);


2703             verify_limitpriv(handle) != Z_OK)
2704                 return_code = Z_ERR;
2705 
2706         return (return_code);
2707 }
2708 
2709 /*
2710  * Called when readying or booting a zone.  We double check that the zone's
2711  * debug ID is set and is unique.  This covers the case of pre-existing zones
2712  * with no ID.  Also, its possible that a zone was migrated to this host
2713  * and as a result it has a duplicate ID.  In this case we preserve the ID
2714  * of the first zone we match on in the index file (since it was there before
2715  * the current zone) and we assign a new unique ID to the current zone.
2716  * Return true if we assigned a new ID, indicating that the zone configuration
2717  * needs to be saved.
2718  */
2719 static boolean_t
2720 verify_fix_did(zone_dochandle_t handle)
2721 {
2722         zoneid_t mydid;
2723         struct zoneent *ze;
2724         FILE *cookie;

2725         boolean_t fix = B_FALSE;
2726 
2727         mydid = zonecfg_get_did(handle);
2728         if (mydid == -1) {
2729                 zonecfg_set_did(handle);
2730                 return (B_TRUE);
2731         }
2732 
2733         /* Get the full list of zones from the configuration. */
2734         cookie = setzoneent();
2735         while ((ze = getzoneent_private(cookie)) != NULL) {
2736                 char *name;
2737                 zoneid_t did;
2738 
2739                 name = ze->zone_name;
2740                 if (strcmp(name, GLOBAL_ZONENAME) == 0 ||
2741                     strcmp(name, target_zone) == 0) {
2742                         free(ze);
2743                         continue;
2744                 }
2745 
2746                 if (ze->zone_brand[0] == '\0') {
2747                         /* old, incomplete index entry */
2748                         zone_entry_t zent;
2749 
2750                         if (lookup_zone_info(name, ZONE_ID_UNDEFINED,
2751                             &zent) != Z_OK) {
2752                                 free(ze);
2753                                 continue;
2754                         }
2755                         did = zent.zdid;
2756                 } else {
2757                         /* new, full index entry */
2758                         did = ze->zone_did;
2759                 }
2760                 free(ze);
2761 
2762                 if (did == mydid) {

2763                         fix = B_TRUE;
2764                         break;
2765                 }
2766         }
2767         endzoneent(cookie);
2768 
2769         if (fix) {
2770                 zonecfg_set_did(handle);
2771                 return (B_TRUE);
2772         }
2773 
2774         return (B_FALSE);
2775 }
2776 
2777 static int
2778 verify_details(int cmd_num, char *argv[])
2779 {
2780         zone_dochandle_t handle;
2781         char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2782         int return_code = Z_OK;


2913 
2914         if ((optarg != NULL) && (strlcat(buf, optarg, bufsize) > bufsize))
2915                 return (Z_ERR);
2916 
2917         return (Z_OK);
2918 }
2919 
2920 /* ARGSUSED */
2921 static int
2922 install_func(int argc, char *argv[])
2923 {
2924         char cmdbuf[MAXPATHLEN];
2925         char postcmdbuf[MAXPATHLEN];
2926         int lockfd;
2927         int arg, err, subproc_err;
2928         char zonepath[MAXPATHLEN];
2929         brand_handle_t bh = NULL;
2930         int status;
2931         boolean_t do_postinstall = B_FALSE;
2932         boolean_t brand_help = B_FALSE;
2933         boolean_t do_dataset = B_TRUE;
2934         char opts[128];
2935 
2936         if (target_zone == NULL) {
2937                 sub_usage(SHELP_INSTALL, CMD_INSTALL);
2938                 return (Z_USAGE);
2939         }
2940 
2941         if (zonecfg_in_alt_root()) {
2942                 zerror(gettext("cannot install zone in alternate root"));
2943                 return (Z_ERR);
2944         }
2945 
2946         if ((err = zone_get_zonepath(target_zone, zonepath,
2947             sizeof (zonepath))) != Z_OK) {
2948                 errno = err;
2949                 zperror2(target_zone, gettext("could not get zone path"));
2950                 return (Z_ERR);
2951         }
2952 
2953         /* Fetch the install command from the brand configuration.  */


2989 
2990         brand_close(bh);
2991 
2992         if (cmdbuf[0] == '\0') {
2993                 zerror("Missing brand install command");
2994                 return (Z_ERR);
2995         }
2996 
2997         /* Check the argv string for args we handle internally */
2998         optind = 0;
2999         opterr = 0;
3000         while ((arg = getopt(argc, argv, opts)) != EOF) {
3001                 switch (arg) {
3002                 case '?':
3003                         if (optopt == '?') {
3004                                 sub_usage(SHELP_INSTALL, CMD_INSTALL);
3005                                 brand_help = B_TRUE;
3006                         }
3007                         /* Ignore unknown options - may be brand specific. */
3008                         break;
3009                 case 'x':
3010                         if (strcmp(optarg, "nodataset") == 0) {
3011                                 do_dataset = B_FALSE;
3012                                 continue; /* internal arg, don't pass thru */
3013                         }
3014                         break;
3015                 default:
3016                         /* Ignore unknown options - may be brand specific. */
3017                         break;
3018                 }
3019 
3020                 /*
3021                  * Append the option to the command line passed to the
3022                  * brand-specific install and postinstall routines.
3023                  */
3024                 if (addopt(cmdbuf, optopt, optarg, sizeof (cmdbuf)) != Z_OK) {
3025                         zerror("Install command line too long");
3026                         return (Z_ERR);
3027                 }
3028                 if (addopt(postcmdbuf, optopt, optarg, sizeof (postcmdbuf))
3029                     != Z_OK) {
3030                         zerror("Post-Install command line too long");
3031                         return (Z_ERR);
3032                 }
3033         }
3034 


3047 
3048         if (!brand_help) {
3049                 if (sanity_check(target_zone, CMD_INSTALL, B_FALSE, B_TRUE,
3050                     B_FALSE) != Z_OK)
3051                         return (Z_ERR);
3052                 if (verify_details(CMD_INSTALL, argv) != Z_OK)
3053                         return (Z_ERR);
3054 
3055                 if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
3056                         zerror(gettext("another %s may have an operation in "
3057                             "progress."), "zoneadm");
3058                         return (Z_ERR);
3059                 }
3060                 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE);
3061                 if (err != Z_OK) {
3062                         errno = err;
3063                         zperror2(target_zone, gettext("could not set state"));
3064                         goto done;
3065                 }
3066 
3067                 if (do_dataset)
3068                         create_zfs_zonepath(zonepath);
3069         }
3070 
3071         status = do_subproc(cmdbuf);
3072         if ((subproc_err =
3073             subproc_status(gettext("brand-specific installation"), status,
3074             B_FALSE)) != ZONE_SUBPROC_OK) {
3075                 if (subproc_err == ZONE_SUBPROC_USAGE && !brand_help) {
3076                         sub_usage(SHELP_INSTALL, CMD_INSTALL);
3077                         zonecfg_release_lock_file(target_zone, lockfd);
3078                         return (Z_ERR);
3079                 }
3080                 errno = subproc_err;
3081                 err = Z_ERR;
3082                 goto done;
3083         }
3084 
3085         if (brand_help)
3086                 return (Z_OK);
3087 


5012         if (addoptions(cmdbuf, argv, sizeof (cmdbuf)) != Z_OK)
5013                 return (Z_ERR);
5014 
5015         if (!brand_help) {
5016                 if ((err = zone_get_rootpath(target_zone, rootpath,
5017                     sizeof (rootpath))) != Z_OK) {
5018                         errno = err;
5019                         zperror2(target_zone, gettext("could not get root "
5020                             "path"));
5021                         return (Z_ERR);
5022                 }
5023 
5024                 /*
5025                  * If there seems to be a zoneadmd running for this zone, call
5026                  * it to tell it that an uninstall is happening; if all goes
5027                  * well it will then shut itself down.
5028                  */
5029                 if (zonecfg_ping_zoneadmd(target_zone) == Z_OK) {
5030                         zone_cmd_arg_t zarg;
5031                         zarg.cmd = Z_NOTE_UNINSTALLING;
5032                         zarg.debug = B_FALSE;
5033                         /* we don't care too much if this fails, just plow on */
5034                         (void) zonecfg_call_zoneadmd(target_zone, &zarg, locale,
5035                             B_TRUE);
5036                 }
5037 
5038                 if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
5039                         zerror(gettext("another %s may have an operation in "
5040                             "progress."), "zoneadm");
5041                         return (Z_ERR);
5042                 }
5043 
5044                 /* Don't uninstall the zone if anything is mounted there */
5045                 err = zonecfg_find_mounts(rootpath, NULL, NULL);
5046                 if (err) {
5047                         zerror(gettext("These file systems are mounted on "
5048                             "subdirectories of %s.\n"), rootpath);
5049                         (void) zonecfg_find_mounts(rootpath, zfm_print, NULL);
5050                         zonecfg_release_lock_file(target_zone, lockfd);
5051                         return (Z_ERR);
5052                 }


5128         optind = 0;
5129         if ((arg = getopt(argc, argv, "f")) != EOF) {
5130                 switch (arg) {
5131                 case 'f':
5132                         force = B_TRUE;
5133                         break;
5134                 default:
5135                         return (Z_USAGE);
5136                 }
5137         }
5138         if (argc > optind)
5139                 return (Z_USAGE);
5140 
5141         if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force)
5142             != Z_OK)
5143                 return (Z_ERR);
5144         if (verify_details(CMD_MOUNT, argv) != Z_OK)
5145                 return (Z_ERR);
5146 
5147         zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT;
5148         zarg.debug = B_FALSE;
5149         zarg.bootbuf[0] = '\0';
5150         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5151                 zerror(gettext("call to %s failed"), "zoneadmd");
5152                 return (Z_ERR);
5153         }
5154         return (Z_OK);
5155 }
5156 
5157 /* ARGSUSED */
5158 static int
5159 unmount_func(int argc, char *argv[])
5160 {
5161         zone_cmd_arg_t zarg;
5162 
5163         if (argc > 0)
5164                 return (Z_USAGE);
5165         if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE, B_FALSE)
5166             != Z_OK)
5167                 return (Z_ERR);
5168 
5169         zarg.cmd = Z_UNMOUNT;
5170         zarg.debug = B_FALSE;
5171         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5172                 zerror(gettext("call to %s failed"), "zoneadmd");
5173                 return (Z_ERR);
5174         }
5175         return (Z_OK);
5176 }
5177 
5178 static int
5179 mark_func(int argc, char *argv[])
5180 {
5181         int err, lockfd;
5182         int arg;
5183         boolean_t force = B_FALSE;
5184         int state;
5185 
5186         optind = 0;
5187         opterr = 0;
5188         while ((arg = getopt(argc, argv, "F")) != EOF) {
5189                 switch (arg) {
5190                 case 'F':




   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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2014 Nexenta Systems, Inc. All rights reserved.

  25  * Copyright (c) 2015 by Delphix. All rights reserved.
  26  * Copyright 2015, Joyent Inc. All rights reserved.
  27  */
  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>


  90 #include "zoneadm.h"
  91 
  92 #define MAXARGS 8
  93 #define SOURCE_ZONE (CMD_MAX + 1)
  94 
  95 /* Reflects kernel zone entries */
  96 typedef struct zone_entry {
  97         zoneid_t        zid;
  98         char            zname[ZONENAME_MAX];
  99         char            *zstate_str;
 100         zone_state_t    zstate_num;
 101         char            zbrand[MAXNAMELEN];
 102         char            zroot[MAXPATHLEN];
 103         char            zuuid[UUID_PRINTABLE_STRING_LENGTH];
 104         zone_iptype_t   ziptype;
 105         zoneid_t        zdid;
 106 } zone_entry_t;
 107 
 108 #define CLUSTER_BRAND_NAME      "cluster"
 109 
 110 static zone_entry_t *zents;
 111 static size_t nzents;
 112 
 113 #define LOOPBACK_IF     "lo0"
 114 #define SOCKET_AF(af)   (((af) == AF_UNSPEC) ? AF_INET : (af))
 115 
 116 struct net_if {
 117         char    *name;
 118         int     af;
 119 };
 120 
 121 /* 0755 is the default directory mode. */
 122 #define DEFAULT_DIR_MODE \
 123         (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
 124 
 125 struct cmd {
 126         uint_t  cmd_num;                                /* command number */
 127         char    *cmd_name;                              /* command name */
 128         char    *short_usage;                           /* short form help */
 129         int     (*handler)(int argc, char *argv[]);     /* function to call */
 130 
 131 };
 132 


 391 {
 392         (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str,
 393             zonecfg_strerror(errno));
 394 }
 395 
 396 /* PRINTFLIKE1 */
 397 void
 398 zerror(const char *fmt, ...)
 399 {
 400         va_list alist;
 401 
 402         va_start(alist, fmt);
 403         (void) fprintf(stderr, "%s: ", execname);
 404         if (target_zone != NULL)
 405                 (void) fprintf(stderr, "zone '%s': ", target_zone);
 406         (void) vfprintf(stderr, fmt, alist);
 407         (void) fprintf(stderr, "\n");
 408         va_end(alist);
 409 }
 410 
 411 static void *
 412 safe_calloc(size_t nelem, size_t elsize)
 413 {
 414         void *r = calloc(nelem, elsize);
 415 
 416         if (r == NULL) {
 417                 zerror(gettext("failed to allocate %lu bytes: %s"),
 418                     (ulong_t)nelem * elsize, strerror(errno));
 419                 exit(Z_ERR);
 420         }
 421         return (r);
 422 }
 423 
 424 static void
 425 zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable)
 426 {
 427         static boolean_t firsttime = B_TRUE;
 428         char *ip_type_str;
 429 
 430         /* Skip a zone that shutdown while we were collecting data. */
 431         if (zent->zname[0] == '\0')
 432                 return;
 433 
 434         if (zent->ziptype == ZS_EXCLUSIVE)
 435                 ip_type_str = "excl";
 436         else
 437                 ip_type_str = "shared";
 438 
 439         assert(!(verbose && parsable));
 440         if (firsttime && verbose) {
 441                 firsttime = B_FALSE;
 442                 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
 443                     ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",


 475                 else
 476                         (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
 477                 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
 478                     zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
 479         }
 480 }
 481 
 482 static int
 483 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
 484 {
 485         char root[MAXPATHLEN], *cp;
 486         int err;
 487         uuid_t uuid;
 488         zone_dochandle_t handle;
 489 
 490         (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname));
 491         (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot));
 492         (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand));
 493         zent->zstate_str = "???";
 494 



 495         zent->zid = zid;
 496 
 497         if (zonecfg_get_uuid(zone_name, uuid) == Z_OK &&
 498             !uuid_is_null(uuid))
 499                 uuid_unparse(uuid, zent->zuuid);
 500         else
 501                 zent->zuuid[0] = '\0';
 502 
 503         /*
 504          * For labeled zones which query the zone path of lower-level
 505          * zones, the path needs to be adjusted to drop the final
 506          * "/root" component. This adjusted path is then useful
 507          * for reading down any exported directories from the
 508          * lower-level zone.
 509          */
 510         if (is_system_labeled() && zent->zid != ZONE_ID_UNDEFINED) {
 511                 if (zone_getattr(zent->zid, ZONE_ATTR_ROOT, zent->zroot,
 512                     sizeof (zent->zroot)) == -1) {
 513                         zperror2(zent->zname,
 514                             gettext("could not get zone path."));


 519                         *cp = 0;
 520         } else {
 521                 if ((err = zone_get_zonepath(zent->zname, root,
 522                     sizeof (root))) != Z_OK) {
 523                         errno = err;
 524                         zperror2(zent->zname,
 525                             gettext("could not get zone path."));
 526                         return (Z_ERR);
 527                 }
 528                 (void) strlcpy(zent->zroot, root, sizeof (zent->zroot));
 529         }
 530 
 531         if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) {
 532                 errno = err;
 533                 zperror2(zent->zname, gettext("could not get state"));
 534                 return (Z_ERR);
 535         }
 536         zent->zstate_str = zone_state_str(zent->zstate_num);
 537 
 538         /*
 539          * A zone's brand is only available in the .xml file describing it,
 540          * which is only visible to the global zone.  This causes
 541          * zone_get_brand() to fail when called from within a non-global
 542          * zone.  Fortunately we only do this on labeled systems, where we
 543          * know all zones are native.
 544          */
 545         if (getzoneid() != GLOBAL_ZONEID) {
 546                 assert(is_system_labeled() != 0);
 547                 (void) strlcpy(zent->zbrand, default_brand,
 548                     sizeof (zent->zbrand));
 549         } else if (zone_get_brand(zent->zname, zent->zbrand,
 550             sizeof (zent->zbrand)) != Z_OK) {
 551                 zperror2(zent->zname, gettext("could not get brand name"));
 552                 return (Z_ERR);
 553         }
 554 
 555         /*
 556          * Get ip type of the zone.
 557          * Note for global zone, ZS_SHARED is set always.
 558          */
 559         if (zid == GLOBAL_ZONEID) {
 560                 zent->ziptype = ZS_SHARED;


 590         if (zent->zstate_num == ZONE_STATE_RUNNING &&
 591             zid != ZONE_ID_UNDEFINED) {
 592                 ushort_t flags;
 593 
 594                 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
 595                     sizeof (flags)) >= 0) {
 596                         if (flags & ZF_NET_EXCL)
 597                                 zent->ziptype = ZS_EXCLUSIVE;
 598                         else
 599                                 zent->ziptype = ZS_SHARED;
 600                 }
 601         }
 602 
 603         zent->zdid = zonecfg_get_did(handle);
 604 
 605         zonecfg_fini_handle(handle);
 606 
 607         return (Z_OK);
 608 }
 609 
 610 /*
 611  * fetch_zents() calls zone_list(2) to find out how many zones are running
 612  * (which is stored in the global nzents), then calls zone_list(2) again
 613  * to fetch the list of running zones (stored in the global zents).  This
 614  * function may be called multiple times, so if zents is already set, we
 615  * return immediately to save work.
 616  *
 617  * Note that the data about running zones can change while this function
 618  * is running, so its possible that the list of zones will have empty slots
 619  * at the end.
 620  */
 621 
 622 static int
 623 fetch_zents(void)
 624 {
 625         zoneid_t *zids = NULL;
 626         uint_t nzents_saved;
 627         int i, retv;
 628         FILE *fp;
 629         boolean_t inaltroot;
 630         zone_entry_t *zentp;
 631         const char *altroot;
 632 
 633         if (nzents > 0)
 634                 return (Z_OK);





 635 
 636         if (zone_list(NULL, &nzents) != 0) {
 637                 zperror(gettext("failed to get zoneid list"), B_FALSE);
 638                 return (Z_ERR);
 639         }
 640 
 641 again:
 642         if (nzents == 0)
 643                 return (Z_OK);
 644 
 645         zids = safe_calloc(nzents, sizeof (zoneid_t));
 646         nzents_saved = nzents;
 647 
 648         if (zone_list(zids, &nzents) != 0) {
 649                 zperror(gettext("failed to get zone list"), B_FALSE);
 650                 free(zids);
 651                 return (Z_ERR);
 652         }
 653         if (nzents != nzents_saved) {
 654                 /* list changed, try again */
 655                 free(zids);
 656                 goto again;
 657         }






 658 
 659         zents = safe_calloc(nzents, sizeof (zone_entry_t));

 660 
 661         inaltroot = zonecfg_in_alt_root();
 662         if (inaltroot) {
 663                 fp = zonecfg_open_scratch("", B_FALSE);
 664                 altroot = zonecfg_get_root();
 665         } else {
 666                 fp = NULL;
 667         }
 668         zentp = zents;
 669         retv = Z_OK;
 670         for (i = 0; i < nzents; i++) {
 671                 char name[ZONENAME_MAX];
 672                 char altname[ZONENAME_MAX];
 673                 char rev_altroot[MAXPATHLEN];
 674 
 675                 if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) {
 676                         /*
 677                          * There is a race condition where the zone may have
 678                          * shutdown since we retrieved the number of running
 679                          * zones above.  This is not an error, there will be
 680                          * an empty slot at the end of the list.
 681                          */
 682                         continue;
 683                 }
 684                 if (zonecfg_is_scratch(name)) {
 685                         /* Ignore scratch zones by default */
 686                         if (!inaltroot)
 687                                 continue;
 688                         if (fp == NULL ||
 689                             zonecfg_reverse_scratch(fp, name, altname,
 690                             sizeof (altname), rev_altroot,
 691                             sizeof (rev_altroot)) == -1) {
 692                                 zerror(gettext("could not resolve scratch "
 693                                     "zone %s"), name);
 694                                 retv = Z_ERR;
 695                                 continue;
 696                         }
 697                         /* Ignore zones in other alternate roots */
 698                         if (strcmp(rev_altroot, altroot) != 0)
 699                                 continue;
 700                         (void) strcpy(name, altname);
 701                 } else {
 702                         /* Ignore non-scratch when in an alternate root */
 703                         if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0)
 704                                 continue;
 705                 }
 706                 if (lookup_zone_info(name, zids[i], zentp) != Z_OK) {
 707                         /*
 708                          * There is a race condition where the zone may have
 709                          * shutdown since we retrieved the number of running
 710                          * zones above.  This is not an error, there will be
 711                          * an empty slot at the end of the list.
 712                          */
 713                         continue;
 714                 }
 715                 zentp++;
 716         }
 717         nzents = zentp - zents;
 718         if (fp != NULL)
 719                 zonecfg_close_scratch(fp);
 720 
 721         free(zids);
 722         return (retv);
 723 }
 724 
 725 static int
 726 zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable)
 727 {
 728         int i;
 729         zone_entry_t zent;
 730         FILE *cookie;
 731         char *name;
 732 
 733         /*
 734          * First get the list of running zones from the kernel and print them.
 735          * If that is all we need, then return.
 736          */
 737         if ((i = fetch_zents()) != Z_OK) {
 738                 /*
 739                  * No need for error messages; fetch_zents() has already taken
 740                  * care of this.
 741                  */
 742                 return (i);
 743         }
 744         for (i = 0; i < nzents; i++)
 745                 zone_print(&zents[i], verbose, parsable);
 746         if (min_state >= ZONE_STATE_RUNNING)
 747                 return (Z_OK);
 748         /*
 749          * Next, get the full list of zones from the configuration, skipping
 750          * any we have already printed.
 751          */
 752         cookie = setzoneent();
 753         while ((name = getzoneent(cookie)) != NULL) {
 754                 for (i = 0; i < nzents; i++) {
 755                         if (strcmp(zents[i].zname, name) == 0)
 756                                 break;
 757                 }
 758                 if (i < nzents) {
 759                         free(name);
 760                         continue;
 761                 }
 762                 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
 763                         free(name);
 764                         continue;
 765                 }
 766                 free(name);
 767                 if (zent.zstate_num >= min_state)
 768                         zone_print(&zent, verbose, parsable);


 769         }
 770         endzoneent(cookie);
 771         return (Z_OK);
 772 }
 773 
 774 /*
 775  * Retrieve a zone entry by name.  Returns NULL if no such zone exists.
 776  */
 777 static zone_entry_t *
 778 lookup_running_zone(const char *name)
 779 {
 780         zoneid_t zid;
 781         zone_entry_t *zent;
 782 
 783         if ((zid = getzoneidbyname(name)) == -1)
 784                 return (NULL);
 785 
 786         if ((zent = malloc(sizeof (zone_entry_t))) == NULL)
 787                 return (NULL);
 788 


1009         }
1010         rpath[res] = '\0';
1011         if (strcmp(path, rpath) != 0) {
1012                 errno = Z_RESOLVED_PATH;
1013                 zperror(path, B_TRUE);
1014                 return (Z_ERR);
1015         }
1016         if ((res = stat(rpath, &stbuf)) != 0) {
1017                 zperror(rpath, B_FALSE);
1018                 return (Z_ERR);
1019         }
1020         if (!S_ISDIR(stbuf.st_mode)) {
1021                 (void) fprintf(stderr, gettext("%s is not a directory.\n"),
1022                     rpath);
1023                 return (Z_ERR);
1024         }
1025         if (strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) {
1026                 (void) printf(gettext("WARNING: %s is on a temporary "
1027                     "file system.\n"), rpath);
1028         }



1029         if (crosscheck_zonepaths(rpath) != Z_OK)
1030                 return (Z_ERR);

1031         /*
1032          * Try to collect and report as many minor errors as possible
1033          * before returning, so the user can learn everything that needs
1034          * to be fixed up front.
1035          */
1036         if (stbuf.st_uid != 0) {
1037                 (void) fprintf(stderr, gettext("%s is not owned by root.\n"),
1038                     rpath);
1039                 err = B_TRUE;
1040 
1041                 /* Try to change owner */
1042                 if (cmd_num != CMD_VERIFY) {
1043                         (void) fprintf(stderr, gettext("%s: changing owner "
1044                             "to root.\n"), rpath);
1045                         if (chown(rpath, 0, -1) != 0) {
1046                                 zperror(rpath, B_FALSE);
1047                                 return (Z_ERR);
1048                         } else {
1049                                 err = B_FALSE;
1050                         }


1197                 return (Z_ERR);
1198         }
1199         if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
1200                 errno = err;
1201                 zperror(cmd_to_str(cmd_num), B_TRUE);
1202                 zonecfg_fini_handle(handle);
1203                 return (Z_ERR);
1204         }
1205         if (verify_brand(handle, cmd_num, argv) != Z_OK) {
1206                 zonecfg_fini_handle(handle);
1207                 return (Z_ERR);
1208         }
1209         zonecfg_fini_handle(handle);
1210         return (Z_OK);
1211 }
1212 
1213 static int
1214 ready_func(int argc, char *argv[])
1215 {
1216         zone_cmd_arg_t zarg;

1217         int arg;
1218 
1219         if (zonecfg_in_alt_root()) {
1220                 zerror(gettext("cannot ready zone in alternate root"));
1221                 return (Z_ERR);
1222         }
1223 
1224         optind = 0;
1225         if ((arg = getopt(argc, argv, "?")) != EOF) {
1226                 switch (arg) {
1227                 case '?':
1228                         sub_usage(SHELP_READY, CMD_READY);
1229                         return (optopt == '?' ? Z_OK : Z_USAGE);



1230                 default:
1231                         sub_usage(SHELP_READY, CMD_READY);
1232                         return (Z_USAGE);
1233                 }
1234         }
1235         if (argc > optind) {
1236                 sub_usage(SHELP_READY, CMD_READY);
1237                 return (Z_USAGE);
1238         }
1239         if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE, B_FALSE)
1240             != Z_OK)
1241                 return (Z_ERR);
1242         if (verify_details(CMD_READY, argv) != Z_OK)
1243                 return (Z_ERR);
1244 
1245         zarg.cmd = Z_READY;

1246         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1247                 zerror(gettext("call to %s failed"), "zoneadmd");
1248                 return (Z_ERR);
1249         }
1250         return (Z_OK);
1251 }
1252 
1253 static int
1254 boot_func(int argc, char *argv[])
1255 {
1256         zone_cmd_arg_t zarg;
1257         boolean_t force = B_FALSE;

1258         int arg;
1259 
1260         if (zonecfg_in_alt_root()) {
1261                 zerror(gettext("cannot boot zone in alternate root"));
1262                 return (Z_ERR);
1263         }
1264 
1265         zarg.bootbuf[0] = '\0';
1266 
1267         /*
1268          * The following getopt processes arguments to zone boot; that
1269          * is to say, the [here] portion of the argument string:
1270          *
1271          *      zoneadm -z myzone boot [here] -- -v -m verbose
1272          *
1273          * Where [here] can either be nothing, -? (in which case we bail
1274          * and print usage), -f (a private option to indicate that the
1275          * boot operation should be 'forced'), or -s.  Support for -s is
1276          * vestigal and obsolete, but is retained because it was a
1277          * documented interface and there are known consumers including
1278          * admin/install; the proper way to specify boot arguments like -s
1279          * is:
1280          *
1281          *      zoneadm -z myzone boot -- -s -v -m verbose.
1282          */
1283         optind = 0;
1284         while ((arg = getopt(argc, argv, "?fs")) != EOF) {
1285                 switch (arg) {
1286                 case '?':
1287                         sub_usage(SHELP_BOOT, CMD_BOOT);
1288                         return (optopt == '?' ? Z_OK : Z_USAGE);
1289                 case 's':
1290                         (void) strlcpy(zarg.bootbuf, "-s",
1291                             sizeof (zarg.bootbuf));
1292                         break;
1293                 case 'f':
1294                         force = B_TRUE;
1295                         break;



1296                 default:
1297                         sub_usage(SHELP_BOOT, CMD_BOOT);
1298                         return (Z_USAGE);
1299                 }
1300         }
1301 
1302         for (; optind < argc; optind++) {
1303                 if (strlcat(zarg.bootbuf, argv[optind],
1304                     sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1305                         zerror(gettext("Boot argument list too long"));
1306                         return (Z_ERR);
1307                 }
1308                 if (optind < argc - 1)
1309                         if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
1310                             sizeof (zarg.bootbuf)) {
1311                                 zerror(gettext("Boot argument list too long"));
1312                                 return (Z_ERR);
1313                         }
1314         }
1315         if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE, force)
1316             != Z_OK)
1317                 return (Z_ERR);
1318         if (verify_details(CMD_BOOT, argv) != Z_OK)
1319                 return (Z_ERR);
1320         zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT;

1321         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
1322                 zerror(gettext("call to %s failed"), "zoneadmd");
1323                 return (Z_ERR);
1324         }
1325 
1326         return (Z_OK);
1327 }
1328 
1329 static void
1330 fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr)
1331 {
1332         ssize_t result;
1333         uuid_t uuid;
1334         FILE *fp;
1335         ushort_t flags;
1336 
1337         (void) memset(zeptr, 0, sizeof (*zeptr));
1338 
1339         zeptr->zid = zid;
1340 


1610                 if (setuid(0) == -1) {
1611                         zperror(gettext("insufficient privilege"), B_TRUE);
1612                         return (Z_ERR);
1613                 }
1614                 return (Z_OK);
1615         }
1616 }
1617 
1618 /*
1619  * Various sanity checks; make sure:
1620  * 1. We're in the global zone.
1621  * 2. The calling user has sufficient privilege.
1622  * 3. The target zone is neither the global zone nor anything starting with
1623  *    "SUNW".
1624  * 4a. If we're looking for a 'not running' (i.e., configured or installed)
1625  *     zone, the name service knows about it.
1626  * 4b. For some operations which expect a zone not to be running, that it is
1627  *     not already running (or ready).
1628  */
1629 static int
1630 sanity_check(char *zone, int cmd_num, boolean_t running,
1631     boolean_t unsafe_when_running, boolean_t force)
1632 {
1633         zone_entry_t *zent;
1634         priv_set_t *privset;
1635         zone_state_t state, min_state;
1636         char kernzone[ZONENAME_MAX];
1637         FILE *fp;
1638 
1639         if (getzoneid() != GLOBAL_ZONEID) {
1640                 switch (cmd_num) {
1641                 case CMD_HALT:
1642                         zerror(gettext("use %s to %s this zone."), "halt(1M)",
1643                             cmd_to_str(cmd_num));
1644                         break;
1645                 case CMD_SHUTDOWN:
1646                         zerror(gettext("use %s to %s this zone."),
1647                             "shutdown(1M)", cmd_to_str(cmd_num));
1648                         break;
1649                 case CMD_REBOOT:
1650                         zerror(gettext("use %s to %s this zone."),
1651                             "reboot(1M)", cmd_to_str(cmd_num));
1652                         break;
1653                 default:


1684 
1685         if (auth_check(username, zone, cmd_num) == Z_ERR) {
1686                 zerror(gettext("User %s is not authorized to %s this zone."),
1687                     username, cmd_to_str(cmd_num));
1688                 return (Z_ERR);
1689         }
1690 
1691         if (strcmp(zone, GLOBAL_ZONENAME) == 0) {
1692                 zerror(gettext("%s operation is invalid for the global zone."),
1693                     cmd_to_str(cmd_num));
1694                 return (Z_ERR);
1695         }
1696 
1697         if (strncmp(zone, "SUNW", 4) == 0) {
1698                 zerror(gettext("%s operation is invalid for zones starting "
1699                     "with SUNW."), cmd_to_str(cmd_num));
1700                 return (Z_ERR);
1701         }
1702 
1703         if (!zonecfg_in_alt_root()) {
1704                 zent = lookup_running_zone(zone);
1705         } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) {
1706                 zent = NULL;
1707         } else {
1708                 if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(),
1709                     kernzone, sizeof (kernzone)) == 0)
1710                         zent = lookup_running_zone(kernzone);
1711                 else
1712                         zent = NULL;
1713                 zonecfg_close_scratch(fp);
1714         }
1715 
1716         /*
1717          * Look up from the kernel for 'running' zones.
1718          */
1719         if (running && !force) {
1720                 if (zent == NULL) {
1721                         zerror(gettext("not running"));
1722                         return (Z_ERR);
1723                 }
1724         } else {
1725                 int err;
1726 
1727                 if (unsafe_when_running && zent != NULL) {


1728                         /* check whether the zone is ready or running */
1729                         if ((err = zone_get_state(zent->zname,
1730                             &zent->zstate_num)) != Z_OK) {

1731                                 errno = err;
1732                                 zperror2(zent->zname,
1733                                     gettext("could not get state"));
1734                                 /* can't tell, so hedge */
1735                                 zent->zstate_str = "ready/running";
1736                         } else {
1737                                 zent->zstate_str =
1738                                     zone_state_str(zent->zstate_num);
1739                         }
1740                         zerror(gettext("%s operation is invalid for %s zones."),
1741                             cmd_to_str(cmd_num), zent->zstate_str);
1742                         return (Z_ERR);
1743                 }
1744                 if ((err = zone_get_state(zone, &state)) != Z_OK) {

1745                         errno = err;
1746                         zperror2(zone, gettext("could not get state"));
1747                         return (Z_ERR);
1748                 }

1749                 switch (cmd_num) {
1750                 case CMD_UNINSTALL:
1751                         if (state == ZONE_STATE_CONFIGURED) {
1752                                 zerror(gettext("is already in state '%s'."),
1753                                     zone_state_str(ZONE_STATE_CONFIGURED));
1754                                 return (Z_ERR);
1755                         }
1756                         break;
1757                 case CMD_ATTACH:
1758                         if (state == ZONE_STATE_INSTALLED) {
1759                                 zerror(gettext("is already %s."),
1760                                     zone_state_str(ZONE_STATE_INSTALLED));
1761                                 return (Z_ERR);
1762                         } else if (state == ZONE_STATE_INCOMPLETE && !force) {
1763                                 zerror(gettext("zone is %s; %s required."),
1764                                     zone_state_str(ZONE_STATE_INCOMPLETE),
1765                                     cmd_to_str(CMD_UNINSTALL));
1766                                 return (Z_ERR);
1767                         }
1768                         break;


1816                                 return (Z_ERR);
1817                         }
1818                         break;
1819                 case CMD_SYSBOOT:
1820                         if (state != ZONE_STATE_INSTALLED) {
1821                                 zerror(gettext("%s operation is invalid for %s "
1822                                     "zones."), cmd_to_str(cmd_num),
1823                                     zone_state_str(state));
1824                                 return (Z_ERR);
1825                         }
1826                         break;
1827                 }
1828         }
1829         return (Z_OK);
1830 }
1831 
1832 static int
1833 halt_func(int argc, char *argv[])
1834 {
1835         zone_cmd_arg_t zarg;

1836         int arg;
1837 
1838         if (zonecfg_in_alt_root()) {
1839                 zerror(gettext("cannot halt zone in alternate root"));
1840                 return (Z_ERR);
1841         }
1842 
1843         optind = 0;
1844         if ((arg = getopt(argc, argv, "?")) != EOF) {
1845                 switch (arg) {
1846                 case '?':
1847                         sub_usage(SHELP_HALT, CMD_HALT);
1848                         return (optopt == '?' ? Z_OK : Z_USAGE);



1849                 default:
1850                         sub_usage(SHELP_HALT, CMD_HALT);
1851                         return (Z_USAGE);
1852                 }
1853         }
1854         if (argc > optind) {
1855                 sub_usage(SHELP_HALT, CMD_HALT);
1856                 return (Z_USAGE);
1857         }
1858         /*
1859          * zoneadmd should be the one to decide whether or not to proceed,
1860          * so even though it seems that the fourth parameter below should
1861          * perhaps be B_TRUE, it really shouldn't be.
1862          */
1863         if (sanity_check(target_zone, CMD_HALT, B_FALSE, B_FALSE, B_FALSE)
1864             != Z_OK)
1865                 return (Z_ERR);
1866 
1867         /*
1868          * Invoke brand-specific handler.
1869          */
1870         if (invoke_brand_handler(CMD_HALT, argv) != Z_OK)
1871                 return (Z_ERR);
1872 
1873         zarg.cmd = Z_HALT;

1874         return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale,
1875             B_TRUE) == 0) ?  Z_OK : Z_ERR);
1876 }
1877 
1878 static int
1879 shutdown_func(int argc, char *argv[])
1880 {
1881         zone_cmd_arg_t zarg;
1882         int arg;
1883         boolean_t reboot = B_FALSE;
1884 
1885         zarg.cmd = Z_SHUTDOWN;
1886 
1887         if (zonecfg_in_alt_root()) {
1888                 zerror(gettext("cannot shut down zone in alternate root"));
1889                 return (Z_ERR);
1890         }
1891 
1892         optind = 0;
1893         while ((arg = getopt(argc, argv, "?r")) != EOF) {


1931         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != Z_OK)
1932                 return (Z_ERR);
1933 
1934         if (reboot) {
1935                 if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE,
1936                     B_FALSE) != Z_OK)
1937                         return (Z_ERR);
1938 
1939                 zarg.cmd = Z_BOOT;
1940                 if (zonecfg_call_zoneadmd(target_zone, &zarg, locale,
1941                     B_TRUE) != Z_OK)
1942                         return (Z_ERR);
1943         }
1944         return (Z_OK);
1945 }
1946 
1947 static int
1948 reboot_func(int argc, char *argv[])
1949 {
1950         zone_cmd_arg_t zarg;

1951         int arg;
1952 
1953         if (zonecfg_in_alt_root()) {
1954                 zerror(gettext("cannot reboot zone in alternate root"));
1955                 return (Z_ERR);
1956         }
1957 
1958         optind = 0;
1959         if ((arg = getopt(argc, argv, "?")) != EOF) {
1960                 switch (arg) {
1961                 case '?':
1962                         sub_usage(SHELP_REBOOT, CMD_REBOOT);
1963                         return (optopt == '?' ? Z_OK : Z_USAGE);



1964                 default:
1965                         sub_usage(SHELP_REBOOT, CMD_REBOOT);
1966                         return (Z_USAGE);
1967                 }
1968         }
1969 
1970         zarg.bootbuf[0] = '\0';
1971         for (; optind < argc; optind++) {
1972                 if (strlcat(zarg.bootbuf, argv[optind],
1973                     sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) {
1974                         zerror(gettext("Boot argument list too long"));
1975                         return (Z_ERR);
1976                 }
1977                 if (optind < argc - 1)
1978                         if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >=
1979                             sizeof (zarg.bootbuf)) {
1980                                 zerror(gettext("Boot argument list too long"));
1981                                 return (Z_ERR);
1982                         }
1983         }
1984 
1985 
1986         /*
1987          * zoneadmd should be the one to decide whether or not to proceed,
1988          * so even though it seems that the fourth parameter below should
1989          * perhaps be B_TRUE, it really shouldn't be.
1990          */
1991         if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE, B_FALSE)
1992             != Z_OK)
1993                 return (Z_ERR);
1994         if (verify_details(CMD_REBOOT, argv) != Z_OK)
1995                 return (Z_ERR);
1996 
1997         zarg.cmd = Z_REBOOT;

1998         return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0)
1999             ? Z_OK : Z_ERR);
2000 }
2001 
2002 static int
2003 get_hook(brand_handle_t bh, char *cmd, size_t len, int (*bp)(brand_handle_t,
2004     const char *, const char *, char *, size_t), char *zonename, char *zonepath)
2005 {
2006         if (strlcpy(cmd, EXEC_PREFIX, len) >= len)
2007                 return (Z_ERR);
2008 
2009         if (bp(bh, zonename, zonepath, cmd + EXEC_LEN, len - EXEC_LEN) != 0)
2010                 return (Z_ERR);
2011 
2012         if (strlen(cmd) <= EXEC_LEN)
2013                 cmd[0] = '\0';
2014 
2015         return (Z_OK);
2016 }
2017 


2205 
2206 /*
2207  * Verify that the special device/file system exists and is valid.
2208  */
2209 static int
2210 verify_fs_special(struct zone_fstab *fstab)
2211 {
2212         struct stat64 st;
2213 
2214         /*
2215          * This validation is really intended for standard zone administration.
2216          * If we are in a mini-root or some other upgrade situation where
2217          * we are using the scratch zone, just by-pass this.
2218          */
2219         if (zonecfg_in_alt_root())
2220                 return (Z_OK);
2221 
2222         if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0)
2223                 return (verify_fs_zfs(fstab));
2224 




2225         if (stat64(fstab->zone_fs_special, &st) != 0) {
2226                 (void) fprintf(stderr, gettext("could not verify fs "
2227                     "%s: could not access %s: %s\n"), fstab->zone_fs_dir,
2228                     fstab->zone_fs_special, strerror(errno));
2229                 return (Z_ERR);
2230         }
2231 
2232         if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) {
2233                 /*
2234                  * TRANSLATION_NOTE
2235                  * fs and NFS are literals that should
2236                  * not be translated.
2237                  */
2238                 (void) fprintf(stderr, gettext("cannot verify "
2239                     "fs %s: NFS mounted file system.\n"
2240                     "\tA local file system must be used.\n"),
2241                     fstab->zone_fs_special);
2242                 return (Z_ERR);
2243         }
2244 


2608                     "net", "address", addr, "physical", phys, af2str(af));
2609                 return;
2610         }
2611 
2612         (void) fprintf(stderr,
2613             gettext("could not verify %s %s=%s %s=%s\n\t%s\n"),
2614             "net", "address", addr, "physical", phys, msg);
2615 }
2616 
2617 static int
2618 verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[])
2619 {
2620         struct zone_nwiftab nwiftab;
2621         int return_code = Z_OK;
2622         int err;
2623         boolean_t in_alt_root;
2624         zone_iptype_t iptype;
2625         dladm_handle_t dh;
2626         dladm_status_t status;
2627         datalink_id_t linkid;
2628         char errmsg[DLADM_STRSIZE];
2629 
2630         in_alt_root = zonecfg_in_alt_root();
2631         if (in_alt_root)
2632                 goto no_net;
2633 
2634         if ((err = zonecfg_get_iptype(handle, &iptype)) != Z_OK) {
2635                 errno = err;
2636                 zperror(cmd_to_str(cmd_num), B_TRUE);
2637                 zonecfg_fini_handle(handle);
2638                 return (Z_ERR);
2639         }
2640         if ((err = zonecfg_setnwifent(handle)) != Z_OK) {
2641                 errno = err;
2642                 zperror(cmd_to_str(cmd_num), B_TRUE);
2643                 zonecfg_fini_handle(handle);
2644                 return (Z_ERR);
2645         }
2646         while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) {
2647                 struct lifreq lifr;
2648                 sa_family_t af = AF_UNSPEC;


2691                             nwiftab.zone_nwif_physical)) {
2692                                 (void) fprintf(stderr,
2693                                     gettext("WARNING: skipping network "
2694                                     "interface '%s' which is used in the "
2695                                     "global zone.\n"),
2696                                     nwiftab.zone_nwif_physical);
2697                                 break;
2698                         }
2699 
2700                         /*
2701                          * Verify that the datalink exists and that it isn't
2702                          * already assigned to a zone.
2703                          */
2704                         if ((status = dladm_open(&dh)) == DLADM_STATUS_OK) {
2705                                 status = dladm_name2info(dh,
2706                                     nwiftab.zone_nwif_physical, &linkid, NULL,
2707                                     NULL, NULL);
2708                                 dladm_close(dh);
2709                         }
2710                         if (status != DLADM_STATUS_OK) {
2711                                 (void) fprintf(stderr,
2712                                     gettext("WARNING: skipping network "
2713                                     "interface '%s': %s\n"),
2714                                     nwiftab.zone_nwif_physical,
2715                                     dladm_status2str(status, errmsg));
2716                                 break;
2717                         }
2718                         dl_owner_zid = ALL_ZONES;
2719                         if (zone_check_datalink(&dl_owner_zid, linkid) != 0)
2720                                 break;
2721 
2722                         /*
2723                          * If the zone being verified is
2724                          * running and owns the interface
2725                          */
2726                         target_zid = getzoneidbyname(target_zone);
2727                         if (target_zid == dl_owner_zid)
2728                                 break;
2729 
2730                         /* Zone id match failed, use name to check */
2731                         if (getzonenamebyid(dl_owner_zid, dl_owner_zname,
2732                             ZONENAME_MAX) < 0) {
2733                                 /* No name, show ID instead */
2734                                 (void) snprintf(dl_owner_zname, ZONENAME_MAX,
2735                                     "<%d>", dl_owner_zid);


2793             verify_limitpriv(handle) != Z_OK)
2794                 return_code = Z_ERR;
2795 
2796         return (return_code);
2797 }
2798 
2799 /*
2800  * Called when readying or booting a zone.  We double check that the zone's
2801  * debug ID is set and is unique.  This covers the case of pre-existing zones
2802  * with no ID.  Also, its possible that a zone was migrated to this host
2803  * and as a result it has a duplicate ID.  In this case we preserve the ID
2804  * of the first zone we match on in the index file (since it was there before
2805  * the current zone) and we assign a new unique ID to the current zone.
2806  * Return true if we assigned a new ID, indicating that the zone configuration
2807  * needs to be saved.
2808  */
2809 static boolean_t
2810 verify_fix_did(zone_dochandle_t handle)
2811 {
2812         zoneid_t mydid;
2813         zone_entry_t zent;
2814         FILE *cookie;
2815         char *name;
2816         boolean_t fix = B_FALSE;
2817 
2818         mydid = zonecfg_get_did(handle);
2819         if (mydid == -1) {
2820                 zonecfg_set_did(handle);
2821                 return (B_TRUE);
2822         }
2823 
2824         /* Get the full list of zones from the configuration. */
2825         cookie = setzoneent();
2826         while ((name = getzoneent(cookie)) != NULL) {
2827                 if (strcmp(target_zone, name) == 0) {
2828                         free(name);
2829                         break;  /* Once we find our entry, stop. */





2830                 }
2831 
2832                 if (strcmp(name, "global") == 0 ||
2833                     lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) {
2834                         free(name);




2835                         continue;
2836                 }






2837 
2838                 free(name);
2839                 if (zent.zdid == mydid) {
2840                         fix = B_TRUE;
2841                         break;
2842                 }
2843         }
2844         endzoneent(cookie);
2845 
2846         if (fix) {
2847                 zonecfg_set_did(handle);
2848                 return (B_TRUE);
2849         }
2850 
2851         return (B_FALSE);
2852 }
2853 
2854 static int
2855 verify_details(int cmd_num, char *argv[])
2856 {
2857         zone_dochandle_t handle;
2858         char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2859         int return_code = Z_OK;


2990 
2991         if ((optarg != NULL) && (strlcat(buf, optarg, bufsize) > bufsize))
2992                 return (Z_ERR);
2993 
2994         return (Z_OK);
2995 }
2996 
2997 /* ARGSUSED */
2998 static int
2999 install_func(int argc, char *argv[])
3000 {
3001         char cmdbuf[MAXPATHLEN];
3002         char postcmdbuf[MAXPATHLEN];
3003         int lockfd;
3004         int arg, err, subproc_err;
3005         char zonepath[MAXPATHLEN];
3006         brand_handle_t bh = NULL;
3007         int status;
3008         boolean_t do_postinstall = B_FALSE;
3009         boolean_t brand_help = B_FALSE;

3010         char opts[128];
3011 
3012         if (target_zone == NULL) {
3013                 sub_usage(SHELP_INSTALL, CMD_INSTALL);
3014                 return (Z_USAGE);
3015         }
3016 
3017         if (zonecfg_in_alt_root()) {
3018                 zerror(gettext("cannot install zone in alternate root"));
3019                 return (Z_ERR);
3020         }
3021 
3022         if ((err = zone_get_zonepath(target_zone, zonepath,
3023             sizeof (zonepath))) != Z_OK) {
3024                 errno = err;
3025                 zperror2(target_zone, gettext("could not get zone path"));
3026                 return (Z_ERR);
3027         }
3028 
3029         /* Fetch the install command from the brand configuration.  */


3065 
3066         brand_close(bh);
3067 
3068         if (cmdbuf[0] == '\0') {
3069                 zerror("Missing brand install command");
3070                 return (Z_ERR);
3071         }
3072 
3073         /* Check the argv string for args we handle internally */
3074         optind = 0;
3075         opterr = 0;
3076         while ((arg = getopt(argc, argv, opts)) != EOF) {
3077                 switch (arg) {
3078                 case '?':
3079                         if (optopt == '?') {
3080                                 sub_usage(SHELP_INSTALL, CMD_INSTALL);
3081                                 brand_help = B_TRUE;
3082                         }
3083                         /* Ignore unknown options - may be brand specific. */
3084                         break;






3085                 default:
3086                         /* Ignore unknown options - may be brand specific. */
3087                         break;
3088                 }
3089 
3090                 /*
3091                  * Append the option to the command line passed to the
3092                  * brand-specific install and postinstall routines.
3093                  */
3094                 if (addopt(cmdbuf, optopt, optarg, sizeof (cmdbuf)) != Z_OK) {
3095                         zerror("Install command line too long");
3096                         return (Z_ERR);
3097                 }
3098                 if (addopt(postcmdbuf, optopt, optarg, sizeof (postcmdbuf))
3099                     != Z_OK) {
3100                         zerror("Post-Install command line too long");
3101                         return (Z_ERR);
3102                 }
3103         }
3104 


3117 
3118         if (!brand_help) {
3119                 if (sanity_check(target_zone, CMD_INSTALL, B_FALSE, B_TRUE,
3120                     B_FALSE) != Z_OK)
3121                         return (Z_ERR);
3122                 if (verify_details(CMD_INSTALL, argv) != Z_OK)
3123                         return (Z_ERR);
3124 
3125                 if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
3126                         zerror(gettext("another %s may have an operation in "
3127                             "progress."), "zoneadm");
3128                         return (Z_ERR);
3129                 }
3130                 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE);
3131                 if (err != Z_OK) {
3132                         errno = err;
3133                         zperror2(target_zone, gettext("could not set state"));
3134                         goto done;
3135                 }
3136 

3137                 create_zfs_zonepath(zonepath);
3138         }
3139 
3140         status = do_subproc(cmdbuf);
3141         if ((subproc_err =
3142             subproc_status(gettext("brand-specific installation"), status,
3143             B_FALSE)) != ZONE_SUBPROC_OK) {
3144                 if (subproc_err == ZONE_SUBPROC_USAGE && !brand_help) {
3145                         sub_usage(SHELP_INSTALL, CMD_INSTALL);
3146                         zonecfg_release_lock_file(target_zone, lockfd);
3147                         return (Z_ERR);
3148                 }
3149                 errno = subproc_err;
3150                 err = Z_ERR;
3151                 goto done;
3152         }
3153 
3154         if (brand_help)
3155                 return (Z_OK);
3156 


5081         if (addoptions(cmdbuf, argv, sizeof (cmdbuf)) != Z_OK)
5082                 return (Z_ERR);
5083 
5084         if (!brand_help) {
5085                 if ((err = zone_get_rootpath(target_zone, rootpath,
5086                     sizeof (rootpath))) != Z_OK) {
5087                         errno = err;
5088                         zperror2(target_zone, gettext("could not get root "
5089                             "path"));
5090                         return (Z_ERR);
5091                 }
5092 
5093                 /*
5094                  * If there seems to be a zoneadmd running for this zone, call
5095                  * it to tell it that an uninstall is happening; if all goes
5096                  * well it will then shut itself down.
5097                  */
5098                 if (zonecfg_ping_zoneadmd(target_zone) == Z_OK) {
5099                         zone_cmd_arg_t zarg;
5100                         zarg.cmd = Z_NOTE_UNINSTALLING;

5101                         /* we don't care too much if this fails, just plow on */
5102                         (void) zonecfg_call_zoneadmd(target_zone, &zarg, locale,
5103                             B_TRUE);
5104                 }
5105 
5106                 if (zonecfg_grab_lock_file(target_zone, &lockfd) != Z_OK) {
5107                         zerror(gettext("another %s may have an operation in "
5108                             "progress."), "zoneadm");
5109                         return (Z_ERR);
5110                 }
5111 
5112                 /* Don't uninstall the zone if anything is mounted there */
5113                 err = zonecfg_find_mounts(rootpath, NULL, NULL);
5114                 if (err) {
5115                         zerror(gettext("These file systems are mounted on "
5116                             "subdirectories of %s.\n"), rootpath);
5117                         (void) zonecfg_find_mounts(rootpath, zfm_print, NULL);
5118                         zonecfg_release_lock_file(target_zone, lockfd);
5119                         return (Z_ERR);
5120                 }


5196         optind = 0;
5197         if ((arg = getopt(argc, argv, "f")) != EOF) {
5198                 switch (arg) {
5199                 case 'f':
5200                         force = B_TRUE;
5201                         break;
5202                 default:
5203                         return (Z_USAGE);
5204                 }
5205         }
5206         if (argc > optind)
5207                 return (Z_USAGE);
5208 
5209         if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force)
5210             != Z_OK)
5211                 return (Z_ERR);
5212         if (verify_details(CMD_MOUNT, argv) != Z_OK)
5213                 return (Z_ERR);
5214 
5215         zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT;

5216         zarg.bootbuf[0] = '\0';
5217         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5218                 zerror(gettext("call to %s failed"), "zoneadmd");
5219                 return (Z_ERR);
5220         }
5221         return (Z_OK);
5222 }
5223 
5224 /* ARGSUSED */
5225 static int
5226 unmount_func(int argc, char *argv[])
5227 {
5228         zone_cmd_arg_t zarg;
5229 
5230         if (argc > 0)
5231                 return (Z_USAGE);
5232         if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE, B_FALSE)
5233             != Z_OK)
5234                 return (Z_ERR);
5235 
5236         zarg.cmd = Z_UNMOUNT;

5237         if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) {
5238                 zerror(gettext("call to %s failed"), "zoneadmd");
5239                 return (Z_ERR);
5240         }
5241         return (Z_OK);
5242 }
5243 
5244 static int
5245 mark_func(int argc, char *argv[])
5246 {
5247         int err, lockfd;
5248         int arg;
5249         boolean_t force = B_FALSE;
5250         int state;
5251 
5252         optind = 0;
5253         opterr = 0;
5254         while ((arg = getopt(argc, argv, "F")) != EOF) {
5255                 switch (arg) {
5256                 case 'F':