85 #include <pwd.h>
86 #include <auth_list.h>
87 #include <auth_attr.h>
88 #include <secdb.h>
89
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 } zone_entry_t;
106
107 #define CLUSTER_BRAND_NAME "cluster"
108
109 static zone_entry_t *zents;
110 static size_t nzents;
111
112 #define LOOPBACK_IF "lo0"
113 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af))
114
115 struct net_if {
116 char *name;
117 int af;
118 };
119
120 /* 0755 is the default directory mode. */
121 #define DEFAULT_DIR_MODE \
122 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
123
124 struct cmd {
427 char *ip_type_str;
428
429 /* Skip a zone that shutdown while we were collecting data. */
430 if (zent->zname[0] == '\0')
431 return;
432
433 if (zent->ziptype == ZS_EXCLUSIVE)
434 ip_type_str = "excl";
435 else
436 ip_type_str = "shared";
437
438 assert(!(verbose && parsable));
439 if (firsttime && verbose) {
440 firsttime = B_FALSE;
441 (void) printf("%*s %-16s %-10s %-30s %-8s %-6s\n",
442 ZONEID_WIDTH, "ID", "NAME", "STATUS", "PATH", "BRAND",
443 "IP");
444 }
445 if (!verbose) {
446 char *cp, *clim;
447
448 if (!parsable) {
449 (void) printf("%s\n", zent->zname);
450 return;
451 }
452 if (zent->zid == ZONE_ID_UNDEFINED)
453 (void) printf("-");
454 else
455 (void) printf("%lu", zent->zid);
456 (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
457 cp = zent->zroot;
458 while ((clim = strchr(cp, ':')) != NULL) {
459 (void) printf("%.*s\\:", clim - cp, cp);
460 cp = clim + 1;
461 }
462 (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
463 ip_type_str);
464 return;
465 }
466 if (zent->zstate_str != NULL) {
467 if (zent->zid == ZONE_ID_UNDEFINED)
468 (void) printf("%*s", ZONEID_WIDTH, "-");
469 else
470 (void) printf("%*lu", ZONEID_WIDTH, zent->zid);
471 (void) printf(" %-16s %-10s %-30s %-8s %-6s\n", zent->zname,
472 zent->zstate_str, zent->zroot, zent->zbrand, ip_type_str);
473 }
474 }
475
476 static int
477 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent)
478 {
479 char root[MAXPATHLEN], *cp;
480 int err;
481 uuid_t uuid;
482 zone_dochandle_t handle;
483
538 */
539 if (getzoneid() != GLOBAL_ZONEID) {
540 assert(is_system_labeled() != 0);
541 (void) strlcpy(zent->zbrand, default_brand,
542 sizeof (zent->zbrand));
543 } else if (zone_get_brand(zent->zname, zent->zbrand,
544 sizeof (zent->zbrand)) != Z_OK) {
545 zperror2(zent->zname, gettext("could not get brand name"));
546 return (Z_ERR);
547 }
548
549 /*
550 * Get ip type of the zone.
551 * Note for global zone, ZS_SHARED is set always.
552 */
553 if (zid == GLOBAL_ZONEID) {
554 zent->ziptype = ZS_SHARED;
555 return (Z_OK);
556 }
557
558 /*
559 * There is a race condition where the zone could boot while
560 * we're walking the index file. In this case the zone state
561 * could be seen as running from the call above, but the zoneid
562 * would be undefined.
563 *
564 * There is also a race condition where the zone could shutdown after
565 * we got its running state above. This is also not an error and
566 * we fall back to getting the ziptype from the zone configuration.
567 */
568 if (zent->zstate_num == ZONE_STATE_RUNNING &&
569 zid != ZONE_ID_UNDEFINED) {
570 ushort_t flags;
571
572 if (zone_getattr(zid, ZONE_ATTR_FLAGS, &flags,
573 sizeof (flags)) >= 0) {
574 if (flags & ZF_NET_EXCL)
575 zent->ziptype = ZS_EXCLUSIVE;
576 else
577 zent->ziptype = ZS_SHARED;
578 return (Z_OK);
579 }
580 }
581
582 if ((handle = zonecfg_init_handle()) == NULL) {
583 zperror2(zent->zname, gettext("could not init handle"));
584 return (Z_ERR);
585 }
586 if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
587 zperror2(zent->zname, gettext("could not get handle"));
588 zonecfg_fini_handle(handle);
589 return (Z_ERR);
590 }
591
592 if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
593 zperror2(zent->zname, gettext("could not get ip-type"));
594 zonecfg_fini_handle(handle);
595 return (Z_ERR);
596 }
597 zonecfg_fini_handle(handle);
598
599 return (Z_OK);
600 }
601
602 /*
603 * fetch_zents() calls zone_list(2) to find out how many zones are running
604 * (which is stored in the global nzents), then calls zone_list(2) again
605 * to fetch the list of running zones (stored in the global zents). This
606 * function may be called multiple times, so if zents is already set, we
607 * return immediately to save work.
608 *
609 * Note that the data about running zones can change while this function
610 * is running, so its possible that the list of zones will have empty slots
611 * at the end.
612 */
613
614 static int
615 fetch_zents(void)
616 {
617 zoneid_t *zids = NULL;
2771 return_code = Z_ERR;
2772 if (!in_alt_root && verify_brand(handle, cmd_num, argv) != Z_OK)
2773 return_code = Z_ERR;
2774 if (!in_alt_root && verify_datasets(handle) != Z_OK)
2775 return_code = Z_ERR;
2776
2777 /*
2778 * As the "mount" command is used for patching/upgrading of zones
2779 * or other maintenance processes, the zone's privilege set is not
2780 * checked in this case. Instead, the default, safe set of
2781 * privileges will be used when this zone is created in the
2782 * kernel.
2783 */
2784 if (!in_alt_root && cmd_num != CMD_MOUNT &&
2785 verify_limitpriv(handle) != Z_OK)
2786 return_code = Z_ERR;
2787
2788 return (return_code);
2789 }
2790
2791 static int
2792 verify_details(int cmd_num, char *argv[])
2793 {
2794 zone_dochandle_t handle;
2795 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN];
2796 int return_code = Z_OK;
2797 int err;
2798
2799 if ((handle = zonecfg_init_handle()) == NULL) {
2800 zperror(cmd_to_str(cmd_num), B_TRUE);
2801 return (Z_ERR);
2802 }
2803 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
2804 errno = err;
2805 zperror(cmd_to_str(cmd_num), B_TRUE);
2806 zonecfg_fini_handle(handle);
2807 return (Z_ERR);
2808 }
2809 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) !=
2810 Z_OK) {
2833 (void) fprintf(stderr, gettext("The XML repository has "
2834 "zonepath '%s',\nbut the index file has zonepath '%s'.\n"
2835 "These must match, so fix the incorrect entry.\n"),
2836 zonepath, checkpath);
2837 zonecfg_fini_handle(handle);
2838 return (Z_ERR);
2839 }
2840 if (cmd_num != CMD_ATTACH &&
2841 validate_zonepath(zonepath, cmd_num) != Z_OK) {
2842 (void) fprintf(stderr, gettext("could not verify zonepath %s "
2843 "because of the above errors.\n"), zonepath);
2844 return_code = Z_ERR;
2845 }
2846
2847 if (verify_handle(cmd_num, handle, argv) != Z_OK)
2848 return_code = Z_ERR;
2849
2850 if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) {
2851 int vcommit = 0, obscommit = 0;
2852
2853 #if 0 /* XXX KEBE not yet */
2854 vcommit = verify_fix_did(handle);
2855 #endif /* XXX KEBE not yet */
2856 obscommit = zonecfg_fix_obsolete(handle);
2857
2858 if (vcommit || obscommit)
2859 if (zonecfg_save(handle) != Z_OK)
2860 (void) fprintf(stderr, gettext("Could not save "
2861 "updated configuration.\n"));
2862 }
2863
2864 zonecfg_fini_handle(handle);
2865 if (return_code == Z_ERR)
2866 (void) fprintf(stderr,
2867 gettext("%s: zone %s failed to verify\n"),
2868 execname, target_zone);
2869 return (return_code);
2870 }
2871
2872 static int
2873 verify_func(int argc, char *argv[])
2874 {
2875 int arg;
|
85 #include <pwd.h>
86 #include <auth_list.h>
87 #include <auth_attr.h>
88 #include <secdb.h>
89
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 {
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",
444 "IP");
445 }
446 if (!verbose) {
447 char *cp, *clim;
448 char zdid[80];
449
450 if (!parsable) {
451 (void) printf("%s\n", zent->zname);
452 return;
453 }
454 if (zent->zid == ZONE_ID_UNDEFINED)
455 (void) printf("-");
456 else
457 (void) printf("%lu", zent->zid);
458 (void) printf(":%s:%s:", zent->zname, zent->zstate_str);
459 cp = zent->zroot;
460 while ((clim = strchr(cp, ':')) != NULL) {
461 (void) printf("%.*s\\:", clim - cp, cp);
462 cp = clim + 1;
463 }
464 if (zent->zdid == -1)
465 zdid[0] = '\0';
466 else
467 (void) snprintf(zdid, sizeof (zdid), "%d", zent->zdid);
468 (void) printf("%s:%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand,
469 ip_type_str, zdid);
470 return;
471 }
472 if (zent->zstate_str != NULL) {
473 if (zent->zid == ZONE_ID_UNDEFINED)
474 (void) printf("%*s", ZONEID_WIDTH, "-");
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
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;
561 return (Z_OK);
562 }
563
564 if ((handle = zonecfg_init_handle()) == NULL) {
565 zperror2(zent->zname, gettext("could not init handle"));
566 return (Z_ERR);
567 }
568 if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) {
569 zperror2(zent->zname, gettext("could not get handle"));
570 zonecfg_fini_handle(handle);
571 return (Z_ERR);
572 }
573
574 if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) {
575 zperror2(zent->zname, gettext("could not get ip-type"));
576 zonecfg_fini_handle(handle);
577 return (Z_ERR);
578 }
579
580 /*
581 * There is a race condition where the zone could boot while
582 * we're walking the index file. In this case the zone state
583 * could be seen as running from the call above, but the zoneid
584 * would be undefined.
585 *
586 * There is also a race condition where the zone could shutdown after
587 * we got its running state above. This is also not an error and
588 * we fall back to getting the ziptype from the zone configuration.
589 */
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;
2779 return_code = Z_ERR;
2780 if (!in_alt_root && verify_brand(handle, cmd_num, argv) != Z_OK)
2781 return_code = Z_ERR;
2782 if (!in_alt_root && verify_datasets(handle) != Z_OK)
2783 return_code = Z_ERR;
2784
2785 /*
2786 * As the "mount" command is used for patching/upgrading of zones
2787 * or other maintenance processes, the zone's privilege set is not
2788 * checked in this case. Instead, the default, safe set of
2789 * privileges will be used when this zone is created in the
2790 * kernel.
2791 */
2792 if (!in_alt_root && cmd_num != CMD_MOUNT &&
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;
2860 int err;
2861
2862 if ((handle = zonecfg_init_handle()) == NULL) {
2863 zperror(cmd_to_str(cmd_num), B_TRUE);
2864 return (Z_ERR);
2865 }
2866 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) {
2867 errno = err;
2868 zperror(cmd_to_str(cmd_num), B_TRUE);
2869 zonecfg_fini_handle(handle);
2870 return (Z_ERR);
2871 }
2872 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) !=
2873 Z_OK) {
2896 (void) fprintf(stderr, gettext("The XML repository has "
2897 "zonepath '%s',\nbut the index file has zonepath '%s'.\n"
2898 "These must match, so fix the incorrect entry.\n"),
2899 zonepath, checkpath);
2900 zonecfg_fini_handle(handle);
2901 return (Z_ERR);
2902 }
2903 if (cmd_num != CMD_ATTACH &&
2904 validate_zonepath(zonepath, cmd_num) != Z_OK) {
2905 (void) fprintf(stderr, gettext("could not verify zonepath %s "
2906 "because of the above errors.\n"), zonepath);
2907 return_code = Z_ERR;
2908 }
2909
2910 if (verify_handle(cmd_num, handle, argv) != Z_OK)
2911 return_code = Z_ERR;
2912
2913 if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) {
2914 int vcommit = 0, obscommit = 0;
2915
2916 vcommit = verify_fix_did(handle);
2917 obscommit = zonecfg_fix_obsolete(handle);
2918
2919 if (vcommit || obscommit)
2920 if (zonecfg_save(handle) != Z_OK)
2921 (void) fprintf(stderr, gettext("Could not save "
2922 "updated configuration.\n"));
2923 }
2924
2925 zonecfg_fini_handle(handle);
2926 if (return_code == Z_ERR)
2927 (void) fprintf(stderr,
2928 gettext("%s: zone %s failed to verify\n"),
2929 execname, target_zone);
2930 return (return_code);
2931 }
2932
2933 static int
2934 verify_func(int argc, char *argv[])
2935 {
2936 int arg;
|