Print this page
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.


  80 #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  81 
  82 /* Hard-code the DTD element/attribute/entity names just once, here. */
  83 #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  84 #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  85 #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  86 #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  87 #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  88 #define DTD_ELEM_NET            (const xmlChar *) "network"
  89 #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  90 #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  91 #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
  92 #define DTD_ELEM_DATASET        (const xmlChar *) "dataset"
  93 #define DTD_ELEM_TMPPOOL        (const xmlChar *) "tmp_pool"
  94 #define DTD_ELEM_PSET           (const xmlChar *) "pset"
  95 #define DTD_ELEM_MCAP           (const xmlChar *) "mcap"
  96 #define DTD_ELEM_PACKAGE        (const xmlChar *) "package"
  97 #define DTD_ELEM_OBSOLETES      (const xmlChar *) "obsoletes"
  98 #define DTD_ELEM_DEV_PERM       (const xmlChar *) "dev-perm"
  99 #define DTD_ELEM_ADMIN          (const xmlChar *) "admin"

 100 
 101 #define DTD_ATTR_ACTION         (const xmlChar *) "action"
 102 #define DTD_ATTR_ADDRESS        (const xmlChar *) "address"
 103 #define DTD_ATTR_ALLOWED_ADDRESS        (const xmlChar *) "allowed-address"
 104 #define DTD_ATTR_AUTOBOOT       (const xmlChar *) "autoboot"
 105 #define DTD_ATTR_IPTYPE         (const xmlChar *) "ip-type"
 106 #define DTD_ATTR_DEFROUTER      (const xmlChar *) "defrouter"
 107 #define DTD_ATTR_DIR            (const xmlChar *) "directory"
 108 #define DTD_ATTR_LIMIT          (const xmlChar *) "limit"
 109 #define DTD_ATTR_LIMITPRIV      (const xmlChar *) "limitpriv"
 110 #define DTD_ATTR_BOOTARGS       (const xmlChar *) "bootargs"
 111 #define DTD_ATTR_SCHED          (const xmlChar *) "scheduling-class"
 112 #define DTD_ATTR_MATCH          (const xmlChar *) "match"
 113 #define DTD_ATTR_NAME           (const xmlChar *) "name"
 114 #define DTD_ATTR_PHYSICAL       (const xmlChar *) "physical"
 115 #define DTD_ATTR_POOL           (const xmlChar *) "pool"
 116 #define DTD_ATTR_PRIV           (const xmlChar *) "priv"
 117 #define DTD_ATTR_RAW            (const xmlChar *) "raw"
 118 #define DTD_ATTR_SPECIAL        (const xmlChar *) "special"
 119 #define DTD_ATTR_TYPE           (const xmlChar *) "type"
 120 #define DTD_ATTR_VALUE          (const xmlChar *) "value"
 121 #define DTD_ATTR_ZONEPATH       (const xmlChar *) "zonepath"
 122 #define DTD_ATTR_NCPU_MIN       (const xmlChar *) "ncpu_min"
 123 #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 124 #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 125 #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 126 #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 127 #define DTD_ATTR_ID             (const xmlChar *) "id"
 128 #define DTD_ATTR_UID            (const xmlChar *) "uid"
 129 #define DTD_ATTR_GID            (const xmlChar *) "gid"
 130 #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 131 #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 132 #define DTD_ATTR_BRAND          (const xmlChar *) "brand"
 133 #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 134 #define DTD_ATTR_USER           (const xmlChar *) "user"
 135 #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 136 #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"




 137 
 138 #define DTD_ENTITY_BOOLEAN      "boolean"
 139 #define DTD_ENTITY_DEVPATH      "devpath"
 140 #define DTD_ENTITY_DRIVER       "driver"
 141 #define DTD_ENTITY_DRVMIN       "drv_min"
 142 #define DTD_ENTITY_FALSE        "false"
 143 #define DTD_ENTITY_INT          "int"
 144 #define DTD_ENTITY_STRING       "string"
 145 #define DTD_ENTITY_TRUE         "true"
 146 #define DTD_ENTITY_UINT         "uint"
 147 
 148 #define DTD_ENTITY_BOOL_LEN     6       /* "false" */
 149 
 150 #define ATTACH_FORCED   "SUNWattached.xml"
 151 
 152 #define TMP_POOL_NAME   "SUNWtmp_%s"
 153 #define MAX_TMP_POOL_NAME       (ZONENAME_MAX + 9)
 154 #define RCAP_SERVICE    "system/rcap:default"
 155 #define POOLD_SERVICE   "system/pools/dynamic:default"
 156 


2618 }
2619 
2620 int
2621 zonecfg_add_admin(zone_dochandle_t handle, struct zone_admintab *tabptr,
2622     char *zonename)
2623 {
2624         int err;
2625 
2626         if (tabptr == NULL)
2627                 return (Z_INVAL);
2628 
2629         if ((err = operation_prep(handle)) != Z_OK)
2630                 return (err);
2631 
2632         if ((err = zonecfg_add_auth_core(handle, tabptr,
2633             zonename)) != Z_OK)
2634                 return (err);
2635 
2636         return (Z_OK);
2637 }

2638 static int
2639 zonecfg_delete_auth_core(zone_dochandle_t handle, struct zone_admintab *tabptr,
2640     char *zonename)
2641 {
2642         xmlNodePtr cur = handle->zone_dh_cur;
2643         boolean_t auth_match;
2644         int err;
2645 
2646         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
2647                 if (xmlStrcmp(cur->name, DTD_ELEM_ADMIN))
2648                         continue;
2649                 auth_match = match_prop(cur, DTD_ATTR_USER,
2650                     tabptr->zone_admin_user);
2651                 if (auth_match) {
2652                         if ((err = zonecfg_insert_userauths(
2653                             handle, tabptr->zone_admin_user,
2654                             zonename)) != Z_OK)
2655                                 return (err);
2656                         xmlUnlinkNode(cur);
2657                         xmlFreeNode(cur);


2730                                         return (Z_INSUFFICIENT_SPEC);
2731                         }
2732                 }
2733         }
2734         if (firstmatch == NULL)
2735                 return (Z_NO_RESOURCE_ID);
2736 
2737         cur = firstmatch;
2738 
2739         if ((err = fetchprop(cur, DTD_ATTR_USER, tabptr->zone_admin_user,
2740             sizeof (tabptr->zone_admin_user))) != Z_OK)
2741                 return (err);
2742 
2743         if ((err = fetchprop(cur, DTD_ATTR_AUTHS, tabptr->zone_admin_auths,
2744             sizeof (tabptr->zone_admin_auths))) != Z_OK)
2745                 return (err);
2746 
2747         return (Z_OK);
2748 }
2749 

























































































































































2750 
2751 /* Lock to serialize all devwalks */
2752 static pthread_mutex_t zonecfg_devwalk_lock = PTHREAD_MUTEX_INITIALIZER;
2753 /*
2754  * Global variables used to pass data from zonecfg_dev_manifest to the nftw
2755  * call-back (zonecfg_devwalk_cb).  g_devwalk_data is really the void*
2756  * parameter and g_devwalk_cb is really the *cb parameter from
2757  * zonecfg_dev_manifest.
2758  */
2759 typedef struct __g_devwalk_data *g_devwalk_data_t;
2760 static g_devwalk_data_t g_devwalk_data;
2761 static int (*g_devwalk_cb)(const char *, uid_t, gid_t, mode_t, const char *,
2762     void *);
2763 static size_t g_devwalk_skip_prefix;
2764 
2765 /*
2766  * zonecfg_dev_manifest call-back function used during detach to generate the
2767  * dev info in the manifest.
2768  */
2769 static int


2913         if (acl_set(path, aclp) == -1) {
2914                 free(aclp);
2915                 return (Z_SYSTEM);
2916         }
2917 
2918         free(aclp);
2919         return (Z_OK);
2920 }
2921 
2922 /*
2923  * This function finds everything mounted under a zone's rootpath.
2924  * This returns the number of mounts under rootpath, or -1 on error.
2925  * callback is called once per mount found with the first argument
2926  * pointing to a mnttab structure containing the mount's information.
2927  *
2928  * If the callback function returns non-zero zonecfg_find_mounts
2929  * aborts with an error.
2930  */
2931 int
2932 zonecfg_find_mounts(char *rootpath, int (*callback)(const struct mnttab *,
2933     void *), void *priv) {

2934         FILE *mnttab;
2935         struct mnttab m;
2936         size_t l;
2937         int zfsl;
2938         int rv = 0;
2939         char zfs_path[MAXPATHLEN];
2940 
2941         assert(rootpath != NULL);
2942 
2943         if ((zfsl = snprintf(zfs_path, sizeof (zfs_path), "%s/.zfs/", rootpath))
2944             >= sizeof (zfs_path))
2945                 return (-1);
2946 
2947         l = strlen(rootpath);
2948 
2949         mnttab = fopen("/etc/mnttab", "r");
2950 
2951         if (mnttab == NULL)
2952                 return (-1);
2953 


6904         if ((err = operation_prep(handle)) != Z_OK)
6905                 return (err);
6906 
6907         cur = handle->zone_dh_cur;
6908         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
6909                 if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0)
6910                         continue;
6911                 if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP,
6912                     tabptr->zone_physmem_cap,
6913                     sizeof (tabptr->zone_physmem_cap))) != Z_OK) {
6914                         handle->zone_dh_cur = handle->zone_dh_top;
6915                         return (err);
6916                 }
6917 
6918                 return (Z_OK);
6919         }
6920 
6921         return (Z_NO_ENTRY);
6922 }
6923 























































6924 static int
6925 getmcapent_core(zone_dochandle_t handle, struct zone_mcaptab *tabptr)
6926 {
6927         xmlNodePtr cur;
6928         int err;
6929 
6930         if (handle == NULL)
6931                 return (Z_INVAL);
6932 
6933         if ((cur = handle->zone_dh_cur) == NULL)
6934                 return (Z_NO_ENTRY);
6935 
6936         for (; cur != NULL; cur = cur->next)
6937                 if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) == 0)
6938                         break;
6939         if (cur == NULL) {
6940                 handle->zone_dh_cur = handle->zone_dh_top;
6941                 return (Z_NO_ENTRY);
6942         }
6943 




  80 #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  81 
  82 /* Hard-code the DTD element/attribute/entity names just once, here. */
  83 #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  84 #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  85 #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  86 #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  87 #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  88 #define DTD_ELEM_NET            (const xmlChar *) "network"
  89 #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  90 #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  91 #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
  92 #define DTD_ELEM_DATASET        (const xmlChar *) "dataset"
  93 #define DTD_ELEM_TMPPOOL        (const xmlChar *) "tmp_pool"
  94 #define DTD_ELEM_PSET           (const xmlChar *) "pset"
  95 #define DTD_ELEM_MCAP           (const xmlChar *) "mcap"
  96 #define DTD_ELEM_PACKAGE        (const xmlChar *) "package"
  97 #define DTD_ELEM_OBSOLETES      (const xmlChar *) "obsoletes"
  98 #define DTD_ELEM_DEV_PERM       (const xmlChar *) "dev-perm"
  99 #define DTD_ELEM_ADMIN          (const xmlChar *) "admin"
 100 #define DTD_ELEM_SECFLAGS       (const xmlChar *) "security-flags"
 101 
 102 #define DTD_ATTR_ACTION         (const xmlChar *) "action"
 103 #define DTD_ATTR_ADDRESS        (const xmlChar *) "address"
 104 #define DTD_ATTR_ALLOWED_ADDRESS        (const xmlChar *) "allowed-address"
 105 #define DTD_ATTR_AUTOBOOT       (const xmlChar *) "autoboot"
 106 #define DTD_ATTR_IPTYPE         (const xmlChar *) "ip-type"
 107 #define DTD_ATTR_DEFROUTER      (const xmlChar *) "defrouter"
 108 #define DTD_ATTR_DIR            (const xmlChar *) "directory"
 109 #define DTD_ATTR_LIMIT          (const xmlChar *) "limit"
 110 #define DTD_ATTR_LIMITPRIV      (const xmlChar *) "limitpriv"
 111 #define DTD_ATTR_BOOTARGS       (const xmlChar *) "bootargs"
 112 #define DTD_ATTR_SCHED          (const xmlChar *) "scheduling-class"
 113 #define DTD_ATTR_MATCH          (const xmlChar *) "match"
 114 #define DTD_ATTR_NAME           (const xmlChar *) "name"
 115 #define DTD_ATTR_PHYSICAL       (const xmlChar *) "physical"
 116 #define DTD_ATTR_POOL           (const xmlChar *) "pool"
 117 #define DTD_ATTR_PRIV           (const xmlChar *) "priv"
 118 #define DTD_ATTR_RAW            (const xmlChar *) "raw"
 119 #define DTD_ATTR_SPECIAL        (const xmlChar *) "special"
 120 #define DTD_ATTR_TYPE           (const xmlChar *) "type"
 121 #define DTD_ATTR_VALUE          (const xmlChar *) "value"
 122 #define DTD_ATTR_ZONEPATH       (const xmlChar *) "zonepath"
 123 #define DTD_ATTR_NCPU_MIN       (const xmlChar *) "ncpu_min"
 124 #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 125 #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 126 #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 127 #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 128 #define DTD_ATTR_ID             (const xmlChar *) "id"
 129 #define DTD_ATTR_UID            (const xmlChar *) "uid"
 130 #define DTD_ATTR_GID            (const xmlChar *) "gid"
 131 #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 132 #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 133 #define DTD_ATTR_BRAND          (const xmlChar *) "brand"
 134 #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 135 #define DTD_ATTR_USER           (const xmlChar *) "user"
 136 #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 137 #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"
 138 #define DTD_ATTR_DEFAULT        (const xmlChar *) "default"
 139 #define DTD_ATTR_LOWER          (const xmlChar *) "lower"
 140 #define DTD_ATTR_UPPER          (const xmlChar *) "upper"
 141 
 142 
 143 #define DTD_ENTITY_BOOLEAN      "boolean"
 144 #define DTD_ENTITY_DEVPATH      "devpath"
 145 #define DTD_ENTITY_DRIVER       "driver"
 146 #define DTD_ENTITY_DRVMIN       "drv_min"
 147 #define DTD_ENTITY_FALSE        "false"
 148 #define DTD_ENTITY_INT          "int"
 149 #define DTD_ENTITY_STRING       "string"
 150 #define DTD_ENTITY_TRUE         "true"
 151 #define DTD_ENTITY_UINT         "uint"
 152 
 153 #define DTD_ENTITY_BOOL_LEN     6       /* "false" */
 154 
 155 #define ATTACH_FORCED   "SUNWattached.xml"
 156 
 157 #define TMP_POOL_NAME   "SUNWtmp_%s"
 158 #define MAX_TMP_POOL_NAME       (ZONENAME_MAX + 9)
 159 #define RCAP_SERVICE    "system/rcap:default"
 160 #define POOLD_SERVICE   "system/pools/dynamic:default"
 161 


2623 }
2624 
2625 int
2626 zonecfg_add_admin(zone_dochandle_t handle, struct zone_admintab *tabptr,
2627     char *zonename)
2628 {
2629         int err;
2630 
2631         if (tabptr == NULL)
2632                 return (Z_INVAL);
2633 
2634         if ((err = operation_prep(handle)) != Z_OK)
2635                 return (err);
2636 
2637         if ((err = zonecfg_add_auth_core(handle, tabptr,
2638             zonename)) != Z_OK)
2639                 return (err);
2640 
2641         return (Z_OK);
2642 }
2643 
2644 static int
2645 zonecfg_delete_auth_core(zone_dochandle_t handle, struct zone_admintab *tabptr,
2646     char *zonename)
2647 {
2648         xmlNodePtr cur = handle->zone_dh_cur;
2649         boolean_t auth_match;
2650         int err;
2651 
2652         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
2653                 if (xmlStrcmp(cur->name, DTD_ELEM_ADMIN))
2654                         continue;
2655                 auth_match = match_prop(cur, DTD_ATTR_USER,
2656                     tabptr->zone_admin_user);
2657                 if (auth_match) {
2658                         if ((err = zonecfg_insert_userauths(
2659                             handle, tabptr->zone_admin_user,
2660                             zonename)) != Z_OK)
2661                                 return (err);
2662                         xmlUnlinkNode(cur);
2663                         xmlFreeNode(cur);


2736                                         return (Z_INSUFFICIENT_SPEC);
2737                         }
2738                 }
2739         }
2740         if (firstmatch == NULL)
2741                 return (Z_NO_RESOURCE_ID);
2742 
2743         cur = firstmatch;
2744 
2745         if ((err = fetchprop(cur, DTD_ATTR_USER, tabptr->zone_admin_user,
2746             sizeof (tabptr->zone_admin_user))) != Z_OK)
2747                 return (err);
2748 
2749         if ((err = fetchprop(cur, DTD_ATTR_AUTHS, tabptr->zone_admin_auths,
2750             sizeof (tabptr->zone_admin_auths))) != Z_OK)
2751                 return (err);
2752 
2753         return (Z_OK);
2754 }
2755 
2756 static int
2757 zonecfg_add_secflags_core(zone_dochandle_t handle,
2758     struct zone_secflagstab *tabptr)
2759 {
2760         xmlNodePtr newnode, cur = handle->zone_dh_cur;
2761         int err;
2762 
2763         newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_SECFLAGS, NULL);
2764         err = newprop(newnode, DTD_ATTR_DEFAULT, tabptr->zone_secflags_default);
2765         if (err != Z_OK)
2766                 return (err);
2767         err = newprop(newnode, DTD_ATTR_LOWER, tabptr->zone_secflags_lower);
2768         if (err != Z_OK)
2769                 return (err);
2770         err = newprop(newnode, DTD_ATTR_UPPER, tabptr->zone_secflags_upper);
2771         if (err != Z_OK)
2772                 return (err);
2773 
2774         return (Z_OK);
2775 }
2776 
2777 int
2778 zonecfg_add_secflags(zone_dochandle_t handle, struct zone_secflagstab *tabptr)
2779 {
2780         int err;
2781 
2782 
2783         if (tabptr == NULL)
2784                 return (Z_INVAL);
2785 
2786         if ((err = operation_prep(handle)) != Z_OK)
2787                 return (err);
2788 
2789         if ((err = zonecfg_add_secflags_core(handle, tabptr)) != Z_OK)
2790                 return (err);
2791 
2792         return (Z_OK);
2793 }
2794 
2795 static int
2796 zonecfg_delete_secflags_core(zone_dochandle_t handle,
2797     struct zone_secflagstab *tabptr)
2798 {
2799         xmlNodePtr cur = handle->zone_dh_cur;
2800         boolean_t def_match, low_match, up_match;
2801 
2802         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
2803                 if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) != 0)
2804                         continue;
2805 
2806                 def_match = match_prop(cur, DTD_ATTR_DEFAULT,
2807                     tabptr->zone_secflags_default);
2808                 low_match = match_prop(cur, DTD_ATTR_LOWER,
2809                     tabptr->zone_secflags_lower);
2810                 up_match = match_prop(cur, DTD_ATTR_UPPER,
2811                     tabptr->zone_secflags_upper);
2812 
2813                 if (def_match && low_match && up_match) {
2814                         xmlUnlinkNode(cur);
2815                         xmlFreeNode(cur);
2816                         return (Z_OK);
2817                 }
2818 
2819         }
2820         return (Z_NO_RESOURCE_ID);
2821 }
2822 
2823 int
2824 zonecfg_delete_secflags(zone_dochandle_t handle,
2825     struct zone_secflagstab *tabptr)
2826 {
2827         int err;
2828 
2829         if (tabptr == NULL)
2830                 return (Z_INVAL);
2831 
2832         if ((err = operation_prep(handle)) != Z_OK)
2833                 return (err);
2834 
2835         if ((err = zonecfg_delete_secflags_core(handle, tabptr)) != Z_OK)
2836                 return (err);
2837 
2838         return (Z_OK);
2839 }
2840 
2841 int
2842 zonecfg_modify_secflags(zone_dochandle_t handle,
2843     struct zone_secflagstab *oldtabptr,
2844     struct zone_secflagstab *newtabptr)
2845 {
2846         int err;
2847 
2848         if (oldtabptr == NULL || newtabptr == NULL)
2849                 return (Z_INVAL);
2850 
2851         if ((err = operation_prep(handle)) != Z_OK)
2852                 return (err);
2853 
2854         if ((err = zonecfg_delete_secflags_core(handle, oldtabptr))
2855             != Z_OK)
2856                 return (err);
2857 
2858         if ((err = zonecfg_add_secflags_core(handle, newtabptr)) != Z_OK)
2859                 return (err);
2860 
2861         return (Z_OK);
2862 }
2863 
2864 int
2865 zonecfg_lookup_secflags(zone_dochandle_t handle,
2866     struct zone_secflagstab *tabptr)
2867 {
2868         xmlNodePtr cur;
2869         int err;
2870 
2871         if (tabptr == NULL)
2872                 return (Z_INVAL);
2873 
2874         if ((err = operation_prep(handle)) != Z_OK)
2875                 return (err);
2876 
2877         cur = handle->zone_dh_cur;
2878 
2879         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
2880                 if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) != 0)
2881                         continue;
2882 
2883                 if ((err = fetchprop(cur, DTD_ATTR_DEFAULT,
2884                     tabptr->zone_secflags_default,
2885                     sizeof (tabptr->zone_secflags_default))) != Z_OK) {
2886                         handle->zone_dh_cur = handle->zone_dh_top;
2887                         return (err);
2888                 }
2889 
2890                 if ((err = fetchprop(cur, DTD_ATTR_LOWER,
2891                     tabptr->zone_secflags_lower,
2892                     sizeof (tabptr->zone_secflags_lower))) != Z_OK) {
2893                         handle->zone_dh_cur = handle->zone_dh_top;
2894                         return (err);
2895                 }
2896 
2897                 if ((err = fetchprop(cur, DTD_ATTR_UPPER,
2898                     tabptr->zone_secflags_upper,
2899                     sizeof (tabptr->zone_secflags_upper))) != Z_OK) {
2900                         handle->zone_dh_cur = handle->zone_dh_top;
2901                         return (err);
2902                 }
2903 
2904                 return (Z_OK);
2905         }
2906 
2907         return (Z_NO_ENTRY);
2908 }
2909 
2910 /* Lock to serialize all devwalks */
2911 static pthread_mutex_t zonecfg_devwalk_lock = PTHREAD_MUTEX_INITIALIZER;
2912 /*
2913  * Global variables used to pass data from zonecfg_dev_manifest to the nftw
2914  * call-back (zonecfg_devwalk_cb).  g_devwalk_data is really the void*
2915  * parameter and g_devwalk_cb is really the *cb parameter from
2916  * zonecfg_dev_manifest.
2917  */
2918 typedef struct __g_devwalk_data *g_devwalk_data_t;
2919 static g_devwalk_data_t g_devwalk_data;
2920 static int (*g_devwalk_cb)(const char *, uid_t, gid_t, mode_t, const char *,
2921     void *);
2922 static size_t g_devwalk_skip_prefix;
2923 
2924 /*
2925  * zonecfg_dev_manifest call-back function used during detach to generate the
2926  * dev info in the manifest.
2927  */
2928 static int


3072         if (acl_set(path, aclp) == -1) {
3073                 free(aclp);
3074                 return (Z_SYSTEM);
3075         }
3076 
3077         free(aclp);
3078         return (Z_OK);
3079 }
3080 
3081 /*
3082  * This function finds everything mounted under a zone's rootpath.
3083  * This returns the number of mounts under rootpath, or -1 on error.
3084  * callback is called once per mount found with the first argument
3085  * pointing to a mnttab structure containing the mount's information.
3086  *
3087  * If the callback function returns non-zero zonecfg_find_mounts
3088  * aborts with an error.
3089  */
3090 int
3091 zonecfg_find_mounts(char *rootpath, int (*callback)(const struct mnttab *,
3092     void *), void *priv)
3093 {
3094         FILE *mnttab;
3095         struct mnttab m;
3096         size_t l;
3097         int zfsl;
3098         int rv = 0;
3099         char zfs_path[MAXPATHLEN];
3100 
3101         assert(rootpath != NULL);
3102 
3103         if ((zfsl = snprintf(zfs_path, sizeof (zfs_path), "%s/.zfs/", rootpath))
3104             >= sizeof (zfs_path))
3105                 return (-1);
3106 
3107         l = strlen(rootpath);
3108 
3109         mnttab = fopen("/etc/mnttab", "r");
3110 
3111         if (mnttab == NULL)
3112                 return (-1);
3113 


7064         if ((err = operation_prep(handle)) != Z_OK)
7065                 return (err);
7066 
7067         cur = handle->zone_dh_cur;
7068         for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
7069                 if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0)
7070                         continue;
7071                 if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP,
7072                     tabptr->zone_physmem_cap,
7073                     sizeof (tabptr->zone_physmem_cap))) != Z_OK) {
7074                         handle->zone_dh_cur = handle->zone_dh_top;
7075                         return (err);
7076                 }
7077 
7078                 return (Z_OK);
7079         }
7080 
7081         return (Z_NO_ENTRY);
7082 }
7083 
7084 int
7085 zonecfg_getsecflagsent(zone_dochandle_t handle,
7086     struct zone_secflagstab *tabptr)
7087 {
7088         int err;
7089         xmlNodePtr cur;
7090 
7091         if (handle == NULL)
7092                 return (Z_INVAL);
7093 
7094         if ((err = zonecfg_setent(handle)) != Z_OK)
7095                 return (err);
7096 
7097 
7098         if ((cur = handle->zone_dh_cur) == NULL)
7099                 return (Z_NO_ENTRY);
7100 
7101         for (; cur != NULL; cur = cur->next) {
7102                 if (xmlStrcmp(cur->name, DTD_ELEM_SECFLAGS) == 0)
7103                         break;
7104         }
7105 
7106         if (cur == NULL) {
7107                 handle->zone_dh_cur = handle->zone_dh_top;
7108                 return (Z_NO_ENTRY);
7109         }
7110 
7111         if ((err = fetchprop(cur, DTD_ATTR_DEFAULT,
7112             tabptr->zone_secflags_default,
7113             sizeof (tabptr->zone_secflags_default))) != Z_OK) {
7114                 handle->zone_dh_cur = handle->zone_dh_top;
7115                 return (err);
7116         }
7117 
7118         if ((err = fetchprop(cur, DTD_ATTR_LOWER,
7119             tabptr->zone_secflags_lower,
7120             sizeof (tabptr->zone_secflags_lower))) != Z_OK) {
7121                 handle->zone_dh_cur = handle->zone_dh_top;
7122                 return (err);
7123         }
7124 
7125         if ((err = fetchprop(cur, DTD_ATTR_UPPER,
7126             tabptr->zone_secflags_upper,
7127             sizeof (tabptr->zone_secflags_upper))) != Z_OK) {
7128                 handle->zone_dh_cur = handle->zone_dh_top;
7129                 return (err);
7130         }
7131 
7132         handle->zone_dh_cur = cur->next;
7133 
7134         (void) zonecfg_endent(handle);
7135 
7136         return (err);
7137 }
7138 
7139 static int
7140 getmcapent_core(zone_dochandle_t handle, struct zone_mcaptab *tabptr)
7141 {
7142         xmlNodePtr cur;
7143         int err;
7144 
7145         if (handle == NULL)
7146                 return (Z_INVAL);
7147 
7148         if ((cur = handle->zone_dh_cur) == NULL)
7149                 return (Z_NO_ENTRY);
7150 
7151         for (; cur != NULL; cur = cur->next)
7152                 if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) == 0)
7153                         break;
7154         if (cur == NULL) {
7155                 handle->zone_dh_cur = handle->zone_dh_top;
7156                 return (Z_NO_ENTRY);
7157         }
7158