1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <errno.h> 30*7c478bd9Sstevel@tonic-gate #include <fnmatch.h> 31*7c478bd9Sstevel@tonic-gate #include <strings.h> 32*7c478bd9Sstevel@tonic-gate #include <unistd.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 34*7c478bd9Sstevel@tonic-gate #include <assert.h> 35*7c478bd9Sstevel@tonic-gate #include <libgen.h> 36*7c478bd9Sstevel@tonic-gate #include <libintl.h> 37*7c478bd9Sstevel@tonic-gate #include <alloca.h> 38*7c478bd9Sstevel@tonic-gate #include <ctype.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/mntio.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 43*7c478bd9Sstevel@tonic-gate #include <netdb.h> 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate #include <priv.h> 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate #include <libxml/xmlmemory.h> 48*7c478bd9Sstevel@tonic-gate #include <libxml/parser.h> 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #include <libdevinfo.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate #include <libzonecfg.h> 53*7c478bd9Sstevel@tonic-gate #include "zonecfg_impl.h" 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate #define _PATH_TMPFILE "/zonecfg.XXXXXX" 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate /* Hard-code the DTD element/attribute/entity names just once, here. */ 58*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_ATTR (const xmlChar *) "attr" 59*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_COMMENT (const xmlChar *) "comment" 60*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_DEVICE (const xmlChar *) "device" 61*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_FS (const xmlChar *) "filesystem" 62*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption" 63*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_IPD (const xmlChar *) "inherited-pkg-dir" 64*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_NET (const xmlChar *) "network" 65*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_RCTL (const xmlChar *) "rctl" 66*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" 67*7c478bd9Sstevel@tonic-gate #define DTD_ELEM_ZONE (const xmlChar *) "zone" 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_ACTION (const xmlChar *) "action" 70*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_ADDRESS (const xmlChar *) "address" 71*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_AUTOBOOT (const xmlChar *) "autoboot" 72*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_DIR (const xmlChar *) "directory" 73*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_LIMIT (const xmlChar *) "limit" 74*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_MATCH (const xmlChar *) "match" 75*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_NAME (const xmlChar *) "name" 76*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_PHYSICAL (const xmlChar *) "physical" 77*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_POOL (const xmlChar *) "pool" 78*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_PRIV (const xmlChar *) "priv" 79*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_RAW (const xmlChar *) "raw" 80*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_SPECIAL (const xmlChar *) "special" 81*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_TYPE (const xmlChar *) "type" 82*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_VALUE (const xmlChar *) "value" 83*7c478bd9Sstevel@tonic-gate #define DTD_ATTR_ZONEPATH (const xmlChar *) "zonepath" 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_BOOLEAN "boolean" 86*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_DEVPATH "devpath" 87*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_DRIVER "driver" 88*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_DRVMIN "drv_min" 89*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_FALSE "false" 90*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_INT "int" 91*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_STRING "string" 92*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_TRUE "true" 93*7c478bd9Sstevel@tonic-gate #define DTD_ENTITY_UINT "uint" 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate struct zone_dochandle { 96*7c478bd9Sstevel@tonic-gate char *zone_dh_rootdir; 97*7c478bd9Sstevel@tonic-gate xmlDocPtr zone_dh_doc; 98*7c478bd9Sstevel@tonic-gate xmlNodePtr zone_dh_cur; 99*7c478bd9Sstevel@tonic-gate xmlNodePtr zone_dh_top; 100*7c478bd9Sstevel@tonic-gate }; 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * For functions which return int, which is most of the functions herein, 104*7c478bd9Sstevel@tonic-gate * the return values should be from the Z_foo set defined in <libzonecfg.h>. 105*7c478bd9Sstevel@tonic-gate * In some instances, we take pains mapping some libc errno values to Z_foo 106*7c478bd9Sstevel@tonic-gate * values from this set. 107*7c478bd9Sstevel@tonic-gate */ 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* 110*7c478bd9Sstevel@tonic-gate * Callers of the _file_path() functions are expected to have the second 111*7c478bd9Sstevel@tonic-gate * parameter be a (char foo[MAXPATHLEN]). 112*7c478bd9Sstevel@tonic-gate */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate static void 115*7c478bd9Sstevel@tonic-gate config_file_path(const char *zonename, char *answer) 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate (void) snprintf(answer, MAXPATHLEN, 118*7c478bd9Sstevel@tonic-gate "%s/%s.xml", ZONE_CONFIG_ROOT, zonename); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate static void 122*7c478bd9Sstevel@tonic-gate snap_file_path(char *zonename, char *answer) 123*7c478bd9Sstevel@tonic-gate { 124*7c478bd9Sstevel@tonic-gate (void) snprintf(answer, MAXPATHLEN, 125*7c478bd9Sstevel@tonic-gate "%s/%s.snapshot.xml", ZONE_SNAPSHOT_ROOT, zonename); 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 129*7c478bd9Sstevel@tonic-gate static void 130*7c478bd9Sstevel@tonic-gate zonecfg_error_func(void *ctx, const char *msg, ...) 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate /* 133*7c478bd9Sstevel@tonic-gate * This function does nothing by design. Its purpose is to prevent 134*7c478bd9Sstevel@tonic-gate * libxml from dumping unwanted messages to stdout/stderr. 135*7c478bd9Sstevel@tonic-gate */ 136*7c478bd9Sstevel@tonic-gate } 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate zone_dochandle_t 139*7c478bd9Sstevel@tonic-gate zonecfg_init_handle(void) 140*7c478bd9Sstevel@tonic-gate { 141*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle = malloc(sizeof (struct zone_dochandle)); 142*7c478bd9Sstevel@tonic-gate if (handle == NULL) { 143*7c478bd9Sstevel@tonic-gate errno = Z_NOMEM; 144*7c478bd9Sstevel@tonic-gate return (NULL); 145*7c478bd9Sstevel@tonic-gate } 146*7c478bd9Sstevel@tonic-gate handle->zone_dh_doc = NULL; 147*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = NULL; 148*7c478bd9Sstevel@tonic-gate handle->zone_dh_top = NULL; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate /* generic libxml initialization */ 151*7c478bd9Sstevel@tonic-gate xmlLineNumbersDefault(1); 152*7c478bd9Sstevel@tonic-gate xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS; 153*7c478bd9Sstevel@tonic-gate xmlDoValidityCheckingDefaultValue = 1; 154*7c478bd9Sstevel@tonic-gate (void) xmlKeepBlanksDefault(0); 155*7c478bd9Sstevel@tonic-gate xmlGetWarningsDefaultValue = 0; 156*7c478bd9Sstevel@tonic-gate xmlSetGenericErrorFunc(NULL, zonecfg_error_func); 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate return (handle); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate int 162*7c478bd9Sstevel@tonic-gate zonecfg_check_handle(zone_dochandle_t handle) 163*7c478bd9Sstevel@tonic-gate { 164*7c478bd9Sstevel@tonic-gate if (handle == NULL || handle->zone_dh_doc == NULL) 165*7c478bd9Sstevel@tonic-gate return (Z_BAD_HANDLE); 166*7c478bd9Sstevel@tonic-gate return (Z_OK); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate void 170*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(zone_dochandle_t handle) 171*7c478bd9Sstevel@tonic-gate { 172*7c478bd9Sstevel@tonic-gate if (zonecfg_check_handle(handle) == Z_OK) 173*7c478bd9Sstevel@tonic-gate xmlFreeDoc(handle->zone_dh_doc); 174*7c478bd9Sstevel@tonic-gate if (handle != NULL) 175*7c478bd9Sstevel@tonic-gate free(handle); 176*7c478bd9Sstevel@tonic-gate } 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate static int 179*7c478bd9Sstevel@tonic-gate zonecfg_destroy_impl(char *filename) 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate if (unlink(filename) == -1) { 182*7c478bd9Sstevel@tonic-gate if (errno == EACCES) 183*7c478bd9Sstevel@tonic-gate return (Z_ACCES); 184*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) 185*7c478bd9Sstevel@tonic-gate return (Z_NO_ZONE); 186*7c478bd9Sstevel@tonic-gate return (Z_MISC_FS); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate return (Z_OK); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate int 192*7c478bd9Sstevel@tonic-gate zonecfg_destroy(const char *zonename) 193*7c478bd9Sstevel@tonic-gate { 194*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate config_file_path(zonename, path); 197*7c478bd9Sstevel@tonic-gate return (zonecfg_destroy_impl(path)); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate int 201*7c478bd9Sstevel@tonic-gate zonecfg_destroy_snapshot(char *zonename) 202*7c478bd9Sstevel@tonic-gate { 203*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate snap_file_path(zonename, path); 206*7c478bd9Sstevel@tonic-gate return (zonecfg_destroy_impl(path)); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate static int 210*7c478bd9Sstevel@tonic-gate operation_prep(zone_dochandle_t handle) 211*7c478bd9Sstevel@tonic-gate { 212*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate if (zonecfg_check_handle(handle) == Z_BAD_HANDLE) 215*7c478bd9Sstevel@tonic-gate return (Z_BAD_HANDLE); 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate if ((cur = xmlDocGetRootElement(handle->zone_dh_doc)) == NULL) { 218*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 219*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 223*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 224*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 225*7c478bd9Sstevel@tonic-gate } 226*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur; 227*7c478bd9Sstevel@tonic-gate handle->zone_dh_top = cur; 228*7c478bd9Sstevel@tonic-gate return (Z_OK); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate static int 232*7c478bd9Sstevel@tonic-gate zonecfg_get_handle_impl(char *zonename, char *filename, zone_dochandle_t handle) 233*7c478bd9Sstevel@tonic-gate { 234*7c478bd9Sstevel@tonic-gate xmlValidCtxtPtr cvp; 235*7c478bd9Sstevel@tonic-gate xmlDocPtr top; 236*7c478bd9Sstevel@tonic-gate xmlNodePtr child, next; 237*7c478bd9Sstevel@tonic-gate struct stat statbuf; 238*7c478bd9Sstevel@tonic-gate int valid; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate if (zonename == NULL) 241*7c478bd9Sstevel@tonic-gate return (Z_NO_ZONE); 242*7c478bd9Sstevel@tonic-gate if ((handle->zone_dh_doc = xmlParseFile(filename)) == NULL) { 243*7c478bd9Sstevel@tonic-gate /* distinguish file not found vs. found but not parsed */ 244*7c478bd9Sstevel@tonic-gate if (stat(filename, &statbuf) == 0) 245*7c478bd9Sstevel@tonic-gate return (Z_INVALID_DOCUMENT); 246*7c478bd9Sstevel@tonic-gate return (Z_NO_ZONE); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate if ((cvp = xmlNewValidCtxt()) == NULL) 249*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 250*7c478bd9Sstevel@tonic-gate cvp->error = zonecfg_error_func; 251*7c478bd9Sstevel@tonic-gate cvp->warning = zonecfg_error_func; 252*7c478bd9Sstevel@tonic-gate valid = xmlValidateDocument(cvp, handle->zone_dh_doc); 253*7c478bd9Sstevel@tonic-gate xmlFreeValidCtxt(cvp); 254*7c478bd9Sstevel@tonic-gate if (valid == 0) 255*7c478bd9Sstevel@tonic-gate return (Z_INVALID_DOCUMENT); 256*7c478bd9Sstevel@tonic-gate /* delete any comments such as inherited Sun copyright / ident str */ 257*7c478bd9Sstevel@tonic-gate top = handle->zone_dh_doc; 258*7c478bd9Sstevel@tonic-gate for (child = top->xmlChildrenNode; child != NULL; child = next) { 259*7c478bd9Sstevel@tonic-gate next = child->next; 260*7c478bd9Sstevel@tonic-gate if (child->name == NULL) 261*7c478bd9Sstevel@tonic-gate continue; 262*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(child->name, DTD_ELEM_COMMENT) == 0) { 263*7c478bd9Sstevel@tonic-gate next = child->next; 264*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(child); 265*7c478bd9Sstevel@tonic-gate xmlFreeNode(child); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate return (Z_OK); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate int 272*7c478bd9Sstevel@tonic-gate zonecfg_get_handle(char *zonename, zone_dochandle_t handle) 273*7c478bd9Sstevel@tonic-gate { 274*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate config_file_path(zonename, path); 277*7c478bd9Sstevel@tonic-gate return (zonecfg_get_handle_impl(zonename, path, handle)); 278*7c478bd9Sstevel@tonic-gate } 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate int 281*7c478bd9Sstevel@tonic-gate zonecfg_get_snapshot_handle(char *zonename, zone_dochandle_t handle) 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate snap_file_path(zonename, path); 286*7c478bd9Sstevel@tonic-gate return (zonecfg_get_handle_impl(zonename, path, handle)); 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate int 290*7c478bd9Sstevel@tonic-gate zonecfg_get_name(zone_dochandle_t handle, char *name, size_t namesize) 291*7c478bd9Sstevel@tonic-gate { 292*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 293*7c478bd9Sstevel@tonic-gate xmlChar *property; 294*7c478bd9Sstevel@tonic-gate size_t srcsize; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate if (handle == NULL) 297*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 300*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 301*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 302*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 306*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 307*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate if ((property = xmlGetProp(cur, DTD_ATTR_NAME)) == NULL) 310*7c478bd9Sstevel@tonic-gate return (Z_BAD_PROPERTY); 311*7c478bd9Sstevel@tonic-gate srcsize = strlcpy(name, (char *)property, namesize); 312*7c478bd9Sstevel@tonic-gate xmlFree(property); 313*7c478bd9Sstevel@tonic-gate if (srcsize >= namesize) 314*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 315*7c478bd9Sstevel@tonic-gate return (Z_OK); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate static int 319*7c478bd9Sstevel@tonic-gate zonecfg_save_impl(zone_dochandle_t handle, char *filename) 320*7c478bd9Sstevel@tonic-gate { 321*7c478bd9Sstevel@tonic-gate char tmpfile[MAXPATHLEN]; 322*7c478bd9Sstevel@tonic-gate int tmpfd; 323*7c478bd9Sstevel@tonic-gate xmlValidCtxt cvp = { NULL }; 324*7c478bd9Sstevel@tonic-gate xmlNodePtr comment; 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate (void) strlcpy(tmpfile, filename, sizeof (tmpfile)); 327*7c478bd9Sstevel@tonic-gate (void) dirname(tmpfile); 328*7c478bd9Sstevel@tonic-gate (void) strlcat(tmpfile, _PATH_TMPFILE, sizeof (tmpfile)); 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate tmpfd = mkstemp(tmpfile); 331*7c478bd9Sstevel@tonic-gate if (tmpfd == -1) { 332*7c478bd9Sstevel@tonic-gate (void) unlink(tmpfile); 333*7c478bd9Sstevel@tonic-gate return (Z_TEMP_FILE); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate (void) close(tmpfd); 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate cvp.error = zonecfg_error_func; 338*7c478bd9Sstevel@tonic-gate cvp.warning = zonecfg_error_func; 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate if ((comment = xmlNewComment((xmlChar *) "\n DO NOT EDIT THIS " 341*7c478bd9Sstevel@tonic-gate "FILE. Use zonecfg(1M) instead.\n")) == NULL) 342*7c478bd9Sstevel@tonic-gate goto err; 343*7c478bd9Sstevel@tonic-gate if (xmlAddPrevSibling(handle->zone_dh_top, comment) == 0) 344*7c478bd9Sstevel@tonic-gate goto err; 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate if (xmlValidateDocument(&cvp, handle->zone_dh_doc) == 0) 347*7c478bd9Sstevel@tonic-gate goto err; 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate if (xmlSaveFormatFile(tmpfile, handle->zone_dh_doc, 1) <= 0) 350*7c478bd9Sstevel@tonic-gate goto err; 351*7c478bd9Sstevel@tonic-gate (void) chmod(tmpfile, 0644); 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate if (rename(tmpfile, filename) == -1) { 354*7c478bd9Sstevel@tonic-gate (void) unlink(tmpfile); 355*7c478bd9Sstevel@tonic-gate if (errno == EACCES) 356*7c478bd9Sstevel@tonic-gate return (Z_ACCES); 357*7c478bd9Sstevel@tonic-gate return (Z_MISC_FS); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate return (Z_OK); 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate err: 362*7c478bd9Sstevel@tonic-gate (void) unlink(tmpfile); 363*7c478bd9Sstevel@tonic-gate return (Z_SAVING_FILE); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate 366*7c478bd9Sstevel@tonic-gate int 367*7c478bd9Sstevel@tonic-gate zonecfg_save(zone_dochandle_t handle) 368*7c478bd9Sstevel@tonic-gate { 369*7c478bd9Sstevel@tonic-gate char zname[MAXPATHLEN], path[MAXPATHLEN]; 370*7c478bd9Sstevel@tonic-gate int err; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_name(handle, zname, sizeof (zname))) != Z_OK) { 373*7c478bd9Sstevel@tonic-gate return (err); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate config_file_path(zname, path); 376*7c478bd9Sstevel@tonic-gate return (zonecfg_save_impl(handle, path)); 377*7c478bd9Sstevel@tonic-gate } 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate /* 380*7c478bd9Sstevel@tonic-gate * Special case: if access(2) fails with ENOENT, then try again using 381*7c478bd9Sstevel@tonic-gate * ZONE_CONFIG_ROOT instead of config_file_path(zonename). This is how we 382*7c478bd9Sstevel@tonic-gate * work around the case of a config file which has not been created yet: 383*7c478bd9Sstevel@tonic-gate * the user will need access to the directory so use that as a heuristic. 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate int 387*7c478bd9Sstevel@tonic-gate zonecfg_access(const char *zonename, int amode) 388*7c478bd9Sstevel@tonic-gate { 389*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate config_file_path(zonename, path); 392*7c478bd9Sstevel@tonic-gate if (access(path, amode) == 0) 393*7c478bd9Sstevel@tonic-gate return (Z_OK); 394*7c478bd9Sstevel@tonic-gate if (errno == ENOENT && access(ZONE_CONFIG_ROOT, amode) == 0) 395*7c478bd9Sstevel@tonic-gate return (Z_OK); 396*7c478bd9Sstevel@tonic-gate if (errno == EACCES) 397*7c478bd9Sstevel@tonic-gate return (Z_ACCES); 398*7c478bd9Sstevel@tonic-gate if (errno == EINVAL) 399*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 400*7c478bd9Sstevel@tonic-gate return (Z_MISC_FS); 401*7c478bd9Sstevel@tonic-gate } 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate int 404*7c478bd9Sstevel@tonic-gate zonecfg_create_snapshot(char *zonename) 405*7c478bd9Sstevel@tonic-gate { 406*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle; 407*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN], zonepath[MAXPATHLEN], rpath[MAXPATHLEN]; 408*7c478bd9Sstevel@tonic-gate int error = Z_OK, res; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate if ((handle = zonecfg_init_handle()) == NULL) { 411*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate if ((error = zonecfg_get_handle(zonename, handle)) != Z_OK) 415*7c478bd9Sstevel@tonic-gate goto out; 416*7c478bd9Sstevel@tonic-gate if ((error = operation_prep(handle)) != Z_OK) 417*7c478bd9Sstevel@tonic-gate goto out; 418*7c478bd9Sstevel@tonic-gate error = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath)); 419*7c478bd9Sstevel@tonic-gate if (error != Z_OK) 420*7c478bd9Sstevel@tonic-gate goto out; 421*7c478bd9Sstevel@tonic-gate if ((res = resolvepath(zonepath, rpath, sizeof (rpath))) == -1) { 422*7c478bd9Sstevel@tonic-gate error = Z_RESOLVED_PATH; 423*7c478bd9Sstevel@tonic-gate goto out; 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate /* 426*7c478bd9Sstevel@tonic-gate * If the resolved path is not the same as the original path, then 427*7c478bd9Sstevel@tonic-gate * save the resolved path in the snapshot, thus preventing any 428*7c478bd9Sstevel@tonic-gate * potential problems down the line when zoneadmd goes to unmount 429*7c478bd9Sstevel@tonic-gate * file systems and depends on initial string matches with resolved 430*7c478bd9Sstevel@tonic-gate * paths. 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate rpath[res] = '\0'; 433*7c478bd9Sstevel@tonic-gate if (strcmp(zonepath, rpath) != 0) { 434*7c478bd9Sstevel@tonic-gate if ((error = zonecfg_set_zonepath(handle, rpath)) != Z_OK) 435*7c478bd9Sstevel@tonic-gate goto out; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate if ((mkdir(ZONE_SNAPSHOT_ROOT, S_IRWXU) == -1) && (errno != EEXIST)) { 438*7c478bd9Sstevel@tonic-gate error = Z_MISC_FS; 439*7c478bd9Sstevel@tonic-gate goto out; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate snap_file_path(zonename, path); 443*7c478bd9Sstevel@tonic-gate error = zonecfg_save_impl(handle, path); 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate out: 446*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 447*7c478bd9Sstevel@tonic-gate return (error); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate int 451*7c478bd9Sstevel@tonic-gate zonecfg_set_name(zone_dochandle_t handle, char *name) 452*7c478bd9Sstevel@tonic-gate { 453*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate if (handle == NULL || name == NULL) 456*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 459*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 460*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 461*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 465*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 466*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate if (xmlSetProp(cur, DTD_ATTR_NAME, (const xmlChar *) name) == NULL) 469*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 470*7c478bd9Sstevel@tonic-gate return (Z_OK); 471*7c478bd9Sstevel@tonic-gate } 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate int 474*7c478bd9Sstevel@tonic-gate zonecfg_get_zonepath(zone_dochandle_t handle, char *path, size_t pathsize) 475*7c478bd9Sstevel@tonic-gate { 476*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 477*7c478bd9Sstevel@tonic-gate xmlChar *property; 478*7c478bd9Sstevel@tonic-gate size_t srcsize; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate if (handle == NULL) 481*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 484*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 485*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 486*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate 489*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 490*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 491*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate if ((property = xmlGetProp(cur, DTD_ATTR_ZONEPATH)) == NULL) 494*7c478bd9Sstevel@tonic-gate return (Z_BAD_PROPERTY); 495*7c478bd9Sstevel@tonic-gate srcsize = strlcpy(path, (char *)property, pathsize); 496*7c478bd9Sstevel@tonic-gate xmlFree(property); 497*7c478bd9Sstevel@tonic-gate if (srcsize >= pathsize) 498*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 499*7c478bd9Sstevel@tonic-gate return (Z_OK); 500*7c478bd9Sstevel@tonic-gate } 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate int 503*7c478bd9Sstevel@tonic-gate zonecfg_set_zonepath(zone_dochandle_t handle, char *zonepath) 504*7c478bd9Sstevel@tonic-gate { 505*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 506*7c478bd9Sstevel@tonic-gate char name[ZONENAME_MAX]; 507*7c478bd9Sstevel@tonic-gate struct zoneent ze; 508*7c478bd9Sstevel@tonic-gate int err; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate if (handle == NULL || zonepath == NULL) 511*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 514*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 515*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 516*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 517*7c478bd9Sstevel@tonic-gate } 518*7c478bd9Sstevel@tonic-gate 519*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 520*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 521*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate if (xmlSetProp(cur, DTD_ATTR_ZONEPATH, (const xmlChar *) zonepath) == 524*7c478bd9Sstevel@tonic-gate NULL) 525*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate /* now set the copy in the index file */ 528*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_name(handle, name, sizeof (name))) != Z_OK) 529*7c478bd9Sstevel@tonic-gate return (err); 530*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_name, name, sizeof (ze.zone_name)); 531*7c478bd9Sstevel@tonic-gate ze.zone_state = -1; 532*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_path, zonepath, sizeof (ze.zone_path)); 533*7c478bd9Sstevel@tonic-gate return (putzoneent(&ze, PZE_MODIFY)); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate int 537*7c478bd9Sstevel@tonic-gate zonecfg_get_autoboot(zone_dochandle_t handle, boolean_t *autoboot) 538*7c478bd9Sstevel@tonic-gate { 539*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 540*7c478bd9Sstevel@tonic-gate xmlChar *property; 541*7c478bd9Sstevel@tonic-gate int result = Z_OK; 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate if (handle == NULL) 544*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 547*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 548*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 549*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 553*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 554*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate if ((property = xmlGetProp(cur, DTD_ATTR_AUTOBOOT)) == NULL) 557*7c478bd9Sstevel@tonic-gate return (Z_BAD_PROPERTY); 558*7c478bd9Sstevel@tonic-gate if (strcmp((char *)property, DTD_ENTITY_TRUE) == 0) 559*7c478bd9Sstevel@tonic-gate *autoboot = B_TRUE; 560*7c478bd9Sstevel@tonic-gate else if (strcmp((char *)property, DTD_ENTITY_FALSE) == 0) 561*7c478bd9Sstevel@tonic-gate *autoboot = B_FALSE; 562*7c478bd9Sstevel@tonic-gate else 563*7c478bd9Sstevel@tonic-gate result = Z_BAD_PROPERTY; 564*7c478bd9Sstevel@tonic-gate xmlFree(property); 565*7c478bd9Sstevel@tonic-gate return (result); 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate 568*7c478bd9Sstevel@tonic-gate int 569*7c478bd9Sstevel@tonic-gate zonecfg_set_autoboot(zone_dochandle_t handle, boolean_t autoboot) 570*7c478bd9Sstevel@tonic-gate { 571*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate if (handle == NULL) 574*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 577*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 578*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 579*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 583*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 584*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate if (xmlSetProp(cur, DTD_ATTR_AUTOBOOT, autoboot ? 587*7c478bd9Sstevel@tonic-gate (const xmlChar *) DTD_ENTITY_TRUE : 588*7c478bd9Sstevel@tonic-gate (const xmlChar *) DTD_ENTITY_FALSE) == NULL) 589*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 590*7c478bd9Sstevel@tonic-gate return (Z_OK); 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate 593*7c478bd9Sstevel@tonic-gate int 594*7c478bd9Sstevel@tonic-gate zonecfg_get_pool(zone_dochandle_t handle, char *pool, size_t poolsize) 595*7c478bd9Sstevel@tonic-gate { 596*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 597*7c478bd9Sstevel@tonic-gate xmlChar *property; 598*7c478bd9Sstevel@tonic-gate size_t srcsize; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate if (handle == NULL) 601*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 604*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 605*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 606*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 607*7c478bd9Sstevel@tonic-gate } 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 610*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 611*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate property = xmlGetProp(cur, DTD_ATTR_POOL); 614*7c478bd9Sstevel@tonic-gate /* 615*7c478bd9Sstevel@tonic-gate * Because the DTD lists the pool as 'CDATA ""', we will get exactly 616*7c478bd9Sstevel@tonic-gate * that even if no pool is in the configuratin: a zero length string. 617*7c478bd9Sstevel@tonic-gate * So the NULL check below should (in theory) never trigger, but we 618*7c478bd9Sstevel@tonic-gate * have it for consistency with other _get_X() functions. 619*7c478bd9Sstevel@tonic-gate */ 620*7c478bd9Sstevel@tonic-gate if (property == NULL) 621*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 622*7c478bd9Sstevel@tonic-gate srcsize = strlcpy(pool, (char *)property, poolsize); 623*7c478bd9Sstevel@tonic-gate xmlFree(property); 624*7c478bd9Sstevel@tonic-gate if (srcsize >= poolsize) 625*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 626*7c478bd9Sstevel@tonic-gate return (Z_OK); 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate int 630*7c478bd9Sstevel@tonic-gate zonecfg_set_pool(zone_dochandle_t handle, char *pool) 631*7c478bd9Sstevel@tonic-gate { 632*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate if (handle == NULL || pool == NULL) 635*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate cur = xmlDocGetRootElement(handle->zone_dh_doc); 638*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 639*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 640*7c478bd9Sstevel@tonic-gate return (Z_EMPTY_DOCUMENT); 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate 643*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ZONE)) { 644*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 645*7c478bd9Sstevel@tonic-gate return (Z_WRONG_DOC_TYPE); 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate if (xmlSetProp(cur, DTD_ATTR_POOL, (const xmlChar *) pool) == NULL) 648*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 649*7c478bd9Sstevel@tonic-gate return (Z_OK); 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate static int 653*7c478bd9Sstevel@tonic-gate newprop(zone_dochandle_t handle, xmlNodePtr node, const xmlChar *attrname, 654*7c478bd9Sstevel@tonic-gate char *src) 655*7c478bd9Sstevel@tonic-gate { 656*7c478bd9Sstevel@tonic-gate xmlAttrPtr newattr; 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate newattr = xmlNewProp(node, attrname, (xmlChar *)src); 659*7c478bd9Sstevel@tonic-gate if (newattr == NULL) { 660*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(node); 661*7c478bd9Sstevel@tonic-gate xmlFreeNode(node); 662*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 663*7c478bd9Sstevel@tonic-gate return (Z_BAD_PROPERTY); 664*7c478bd9Sstevel@tonic-gate } 665*7c478bd9Sstevel@tonic-gate return (Z_OK); 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate static int 669*7c478bd9Sstevel@tonic-gate zonecfg_add_filesystem_core(zone_dochandle_t handle, struct zone_fstab *tabptr) 670*7c478bd9Sstevel@tonic-gate { 671*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur, options_node; 672*7c478bd9Sstevel@tonic-gate zone_fsopt_t *ptr; 673*7c478bd9Sstevel@tonic-gate int err; 674*7c478bd9Sstevel@tonic-gate 675*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_FS, NULL); 676*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_SPECIAL, 677*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_special)) != Z_OK) 678*7c478bd9Sstevel@tonic-gate return (err); 679*7c478bd9Sstevel@tonic-gate if (tabptr->zone_fs_raw[0] != '\0' && 680*7c478bd9Sstevel@tonic-gate (err = newprop(handle, newnode, DTD_ATTR_RAW, 681*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_raw)) != Z_OK) 682*7c478bd9Sstevel@tonic-gate return (err); 683*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_DIR, 684*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_dir)) != Z_OK) 685*7c478bd9Sstevel@tonic-gate return (err); 686*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_TYPE, 687*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_type)) != Z_OK) 688*7c478bd9Sstevel@tonic-gate return (err); 689*7c478bd9Sstevel@tonic-gate if (tabptr->zone_fs_options != NULL) { 690*7c478bd9Sstevel@tonic-gate for (ptr = tabptr->zone_fs_options; ptr != NULL; 691*7c478bd9Sstevel@tonic-gate ptr = ptr->zone_fsopt_next) { 692*7c478bd9Sstevel@tonic-gate options_node = xmlNewTextChild(newnode, NULL, 693*7c478bd9Sstevel@tonic-gate DTD_ELEM_FSOPTION, NULL); 694*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, options_node, DTD_ATTR_NAME, 695*7c478bd9Sstevel@tonic-gate ptr->zone_fsopt_opt)) != Z_OK) 696*7c478bd9Sstevel@tonic-gate return (err); 697*7c478bd9Sstevel@tonic-gate } 698*7c478bd9Sstevel@tonic-gate } 699*7c478bd9Sstevel@tonic-gate return (Z_OK); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate 702*7c478bd9Sstevel@tonic-gate int 703*7c478bd9Sstevel@tonic-gate zonecfg_add_filesystem(zone_dochandle_t handle, struct zone_fstab *tabptr) 704*7c478bd9Sstevel@tonic-gate { 705*7c478bd9Sstevel@tonic-gate int err; 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 708*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 709*7c478bd9Sstevel@tonic-gate 710*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 711*7c478bd9Sstevel@tonic-gate return (err); 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_filesystem_core(handle, tabptr)) != Z_OK) 714*7c478bd9Sstevel@tonic-gate return (err); 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate return (Z_OK); 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate static int 720*7c478bd9Sstevel@tonic-gate zonecfg_add_ipd_core(zone_dochandle_t handle, struct zone_fstab *tabptr) 721*7c478bd9Sstevel@tonic-gate { 722*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur; 723*7c478bd9Sstevel@tonic-gate int err; 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_IPD, NULL); 726*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_DIR, 727*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_dir)) != Z_OK) 728*7c478bd9Sstevel@tonic-gate return (err); 729*7c478bd9Sstevel@tonic-gate return (Z_OK); 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate int 733*7c478bd9Sstevel@tonic-gate zonecfg_add_ipd(zone_dochandle_t handle, struct zone_fstab *tabptr) 734*7c478bd9Sstevel@tonic-gate { 735*7c478bd9Sstevel@tonic-gate int err; 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 738*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 741*7c478bd9Sstevel@tonic-gate return (err); 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_ipd_core(handle, tabptr)) != Z_OK) 744*7c478bd9Sstevel@tonic-gate return (err); 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate return (Z_OK); 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate int 750*7c478bd9Sstevel@tonic-gate zonecfg_add_fs_option(struct zone_fstab *tabptr, char *option) 751*7c478bd9Sstevel@tonic-gate { 752*7c478bd9Sstevel@tonic-gate zone_fsopt_t *last, *old, *new; 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate last = tabptr->zone_fs_options; 755*7c478bd9Sstevel@tonic-gate for (old = last; old != NULL; old = old->zone_fsopt_next) 756*7c478bd9Sstevel@tonic-gate last = old; /* walk to the end of the list */ 757*7c478bd9Sstevel@tonic-gate new = (zone_fsopt_t *)malloc(sizeof (zone_fsopt_t)); 758*7c478bd9Sstevel@tonic-gate if (new == NULL) 759*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 760*7c478bd9Sstevel@tonic-gate (void) strlcpy(new->zone_fsopt_opt, option, 761*7c478bd9Sstevel@tonic-gate sizeof (new->zone_fsopt_opt)); 762*7c478bd9Sstevel@tonic-gate new->zone_fsopt_next = NULL; 763*7c478bd9Sstevel@tonic-gate if (last == NULL) 764*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_options = new; 765*7c478bd9Sstevel@tonic-gate else 766*7c478bd9Sstevel@tonic-gate last->zone_fsopt_next = new; 767*7c478bd9Sstevel@tonic-gate return (Z_OK); 768*7c478bd9Sstevel@tonic-gate } 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate int 771*7c478bd9Sstevel@tonic-gate zonecfg_remove_fs_option(struct zone_fstab *tabptr, char *option) 772*7c478bd9Sstevel@tonic-gate { 773*7c478bd9Sstevel@tonic-gate zone_fsopt_t *last, *this, *next; 774*7c478bd9Sstevel@tonic-gate 775*7c478bd9Sstevel@tonic-gate last = tabptr->zone_fs_options; 776*7c478bd9Sstevel@tonic-gate for (this = last; this != NULL; this = this->zone_fsopt_next) { 777*7c478bd9Sstevel@tonic-gate if (strcmp(this->zone_fsopt_opt, option) == 0) { 778*7c478bd9Sstevel@tonic-gate next = this->zone_fsopt_next; 779*7c478bd9Sstevel@tonic-gate if (this == tabptr->zone_fs_options) 780*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_options = next; 781*7c478bd9Sstevel@tonic-gate else 782*7c478bd9Sstevel@tonic-gate last->zone_fsopt_next = next; 783*7c478bd9Sstevel@tonic-gate free(this); 784*7c478bd9Sstevel@tonic-gate return (Z_OK); 785*7c478bd9Sstevel@tonic-gate } else 786*7c478bd9Sstevel@tonic-gate last = this; 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate return (Z_NO_PROPERTY_ID); 789*7c478bd9Sstevel@tonic-gate } 790*7c478bd9Sstevel@tonic-gate 791*7c478bd9Sstevel@tonic-gate void 792*7c478bd9Sstevel@tonic-gate zonecfg_free_fs_option_list(zone_fsopt_t *list) 793*7c478bd9Sstevel@tonic-gate { 794*7c478bd9Sstevel@tonic-gate zone_fsopt_t *this, *next; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate for (this = list; this != NULL; this = next) { 797*7c478bd9Sstevel@tonic-gate next = this->zone_fsopt_next; 798*7c478bd9Sstevel@tonic-gate free(this); 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate void 803*7c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(struct zone_rctlvaltab *valtab) 804*7c478bd9Sstevel@tonic-gate { 805*7c478bd9Sstevel@tonic-gate if (valtab == NULL) 806*7c478bd9Sstevel@tonic-gate return; 807*7c478bd9Sstevel@tonic-gate zonecfg_free_rctl_value_list(valtab->zone_rctlval_next); 808*7c478bd9Sstevel@tonic-gate free(valtab); 809*7c478bd9Sstevel@tonic-gate } 810*7c478bd9Sstevel@tonic-gate 811*7c478bd9Sstevel@tonic-gate static boolean_t 812*7c478bd9Sstevel@tonic-gate match_prop(xmlNodePtr cur, const xmlChar *attr, char *user_prop) 813*7c478bd9Sstevel@tonic-gate { 814*7c478bd9Sstevel@tonic-gate xmlChar *gotten_prop; 815*7c478bd9Sstevel@tonic-gate int prop_result; 816*7c478bd9Sstevel@tonic-gate 817*7c478bd9Sstevel@tonic-gate gotten_prop = xmlGetProp(cur, attr); 818*7c478bd9Sstevel@tonic-gate if (gotten_prop == NULL) /* shouldn't happen */ 819*7c478bd9Sstevel@tonic-gate return (B_FALSE); 820*7c478bd9Sstevel@tonic-gate prop_result = xmlStrcmp(gotten_prop, (const xmlChar *) user_prop); 821*7c478bd9Sstevel@tonic-gate xmlFree(gotten_prop); 822*7c478bd9Sstevel@tonic-gate return ((prop_result == 0)); 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate static int 826*7c478bd9Sstevel@tonic-gate zonecfg_delete_filesystem_core(zone_dochandle_t handle, 827*7c478bd9Sstevel@tonic-gate struct zone_fstab *tabptr) 828*7c478bd9Sstevel@tonic-gate { 829*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 830*7c478bd9Sstevel@tonic-gate boolean_t dir_match, spec_match, raw_match, type_match; 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 833*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_FS)) 834*7c478bd9Sstevel@tonic-gate continue; 835*7c478bd9Sstevel@tonic-gate dir_match = match_prop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir); 836*7c478bd9Sstevel@tonic-gate spec_match = match_prop(cur, DTD_ATTR_SPECIAL, 837*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_special); 838*7c478bd9Sstevel@tonic-gate raw_match = match_prop(cur, DTD_ATTR_RAW, 839*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_raw); 840*7c478bd9Sstevel@tonic-gate type_match = match_prop(cur, DTD_ATTR_TYPE, 841*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_type); 842*7c478bd9Sstevel@tonic-gate if (dir_match && spec_match && raw_match && type_match) { 843*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 844*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 845*7c478bd9Sstevel@tonic-gate return (Z_OK); 846*7c478bd9Sstevel@tonic-gate } 847*7c478bd9Sstevel@tonic-gate } 848*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate int 852*7c478bd9Sstevel@tonic-gate zonecfg_delete_filesystem(zone_dochandle_t handle, struct zone_fstab *tabptr) 853*7c478bd9Sstevel@tonic-gate { 854*7c478bd9Sstevel@tonic-gate int err; 855*7c478bd9Sstevel@tonic-gate 856*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 857*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 860*7c478bd9Sstevel@tonic-gate return (err); 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_filesystem_core(handle, tabptr)) != Z_OK) 863*7c478bd9Sstevel@tonic-gate return (err); 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate return (Z_OK); 866*7c478bd9Sstevel@tonic-gate } 867*7c478bd9Sstevel@tonic-gate 868*7c478bd9Sstevel@tonic-gate int 869*7c478bd9Sstevel@tonic-gate zonecfg_modify_filesystem( 870*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 871*7c478bd9Sstevel@tonic-gate struct zone_fstab *oldtabptr, 872*7c478bd9Sstevel@tonic-gate struct zone_fstab *newtabptr) 873*7c478bd9Sstevel@tonic-gate { 874*7c478bd9Sstevel@tonic-gate int err; 875*7c478bd9Sstevel@tonic-gate 876*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || newtabptr == NULL) 877*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 878*7c478bd9Sstevel@tonic-gate 879*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 880*7c478bd9Sstevel@tonic-gate return (err); 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_filesystem_core(handle, oldtabptr)) != Z_OK) 883*7c478bd9Sstevel@tonic-gate return (err); 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_filesystem_core(handle, newtabptr)) != Z_OK) 886*7c478bd9Sstevel@tonic-gate return (err); 887*7c478bd9Sstevel@tonic-gate 888*7c478bd9Sstevel@tonic-gate return (Z_OK); 889*7c478bd9Sstevel@tonic-gate } 890*7c478bd9Sstevel@tonic-gate 891*7c478bd9Sstevel@tonic-gate static int 892*7c478bd9Sstevel@tonic-gate zonecfg_delete_ipd_core(zone_dochandle_t handle, struct zone_fstab *tabptr) 893*7c478bd9Sstevel@tonic-gate { 894*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 895*7c478bd9Sstevel@tonic-gate 896*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 897*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_IPD)) 898*7c478bd9Sstevel@tonic-gate continue; 899*7c478bd9Sstevel@tonic-gate if (match_prop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir)) { 900*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 901*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 902*7c478bd9Sstevel@tonic-gate return (Z_OK); 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate int 909*7c478bd9Sstevel@tonic-gate zonecfg_delete_ipd(zone_dochandle_t handle, struct zone_fstab *tabptr) 910*7c478bd9Sstevel@tonic-gate { 911*7c478bd9Sstevel@tonic-gate int err; 912*7c478bd9Sstevel@tonic-gate 913*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 914*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 915*7c478bd9Sstevel@tonic-gate 916*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 917*7c478bd9Sstevel@tonic-gate return (err); 918*7c478bd9Sstevel@tonic-gate 919*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_ipd_core(handle, tabptr)) != Z_OK) 920*7c478bd9Sstevel@tonic-gate return (err); 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate return (Z_OK); 923*7c478bd9Sstevel@tonic-gate } 924*7c478bd9Sstevel@tonic-gate 925*7c478bd9Sstevel@tonic-gate int 926*7c478bd9Sstevel@tonic-gate zonecfg_modify_ipd(zone_dochandle_t handle, struct zone_fstab *oldtabptr, 927*7c478bd9Sstevel@tonic-gate struct zone_fstab *newtabptr) 928*7c478bd9Sstevel@tonic-gate { 929*7c478bd9Sstevel@tonic-gate int err; 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || newtabptr == NULL) 932*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 933*7c478bd9Sstevel@tonic-gate 934*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 935*7c478bd9Sstevel@tonic-gate return (err); 936*7c478bd9Sstevel@tonic-gate 937*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_ipd_core(handle, oldtabptr)) != Z_OK) 938*7c478bd9Sstevel@tonic-gate return (err); 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_ipd_core(handle, newtabptr)) != Z_OK) 941*7c478bd9Sstevel@tonic-gate return (err); 942*7c478bd9Sstevel@tonic-gate 943*7c478bd9Sstevel@tonic-gate return (Z_OK); 944*7c478bd9Sstevel@tonic-gate } 945*7c478bd9Sstevel@tonic-gate 946*7c478bd9Sstevel@tonic-gate static int 947*7c478bd9Sstevel@tonic-gate fetchprop(xmlNodePtr cur, const xmlChar *propname, char *dst, size_t dstsize) 948*7c478bd9Sstevel@tonic-gate { 949*7c478bd9Sstevel@tonic-gate xmlChar *property; 950*7c478bd9Sstevel@tonic-gate size_t srcsize; 951*7c478bd9Sstevel@tonic-gate 952*7c478bd9Sstevel@tonic-gate if ((property = xmlGetProp(cur, propname)) == NULL) 953*7c478bd9Sstevel@tonic-gate return (Z_BAD_PROPERTY); 954*7c478bd9Sstevel@tonic-gate srcsize = strlcpy(dst, (char *)property, dstsize); 955*7c478bd9Sstevel@tonic-gate xmlFree(property); 956*7c478bd9Sstevel@tonic-gate if (srcsize >= dstsize) 957*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 958*7c478bd9Sstevel@tonic-gate return (Z_OK); 959*7c478bd9Sstevel@tonic-gate } 960*7c478bd9Sstevel@tonic-gate 961*7c478bd9Sstevel@tonic-gate int 962*7c478bd9Sstevel@tonic-gate zonecfg_lookup_filesystem( 963*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 964*7c478bd9Sstevel@tonic-gate struct zone_fstab *tabptr) 965*7c478bd9Sstevel@tonic-gate { 966*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, options, firstmatch; 967*7c478bd9Sstevel@tonic-gate int err; 968*7c478bd9Sstevel@tonic-gate char dirname[MAXPATHLEN], special[MAXPATHLEN], raw[MAXPATHLEN]; 969*7c478bd9Sstevel@tonic-gate char type[FSTYPSZ]; 970*7c478bd9Sstevel@tonic-gate char options_str[MAX_MNTOPT_STR]; 971*7c478bd9Sstevel@tonic-gate 972*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 973*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 976*7c478bd9Sstevel@tonic-gate return (err); 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate /* 979*7c478bd9Sstevel@tonic-gate * Walk the list of children looking for matches on any properties 980*7c478bd9Sstevel@tonic-gate * specified in the fstab parameter. If more than one resource 981*7c478bd9Sstevel@tonic-gate * matches, we return Z_INSUFFICIENT_SPEC; if none match, we return 982*7c478bd9Sstevel@tonic-gate * Z_NO_RESOURCE_ID. 983*7c478bd9Sstevel@tonic-gate */ 984*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 985*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 986*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 987*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_FS)) 988*7c478bd9Sstevel@tonic-gate continue; 989*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_fs_dir) > 0) { 990*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_DIR, dirname, 991*7c478bd9Sstevel@tonic-gate sizeof (dirname)) == Z_OK) && 992*7c478bd9Sstevel@tonic-gate (strcmp(tabptr->zone_fs_dir, dirname) == 0)) { 993*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 994*7c478bd9Sstevel@tonic-gate firstmatch = cur; 995*7c478bd9Sstevel@tonic-gate else 996*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate } 999*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_fs_special) > 0) { 1000*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_SPECIAL, special, 1001*7c478bd9Sstevel@tonic-gate sizeof (special)) == Z_OK)) { 1002*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_fs_special, 1003*7c478bd9Sstevel@tonic-gate special) == 0) { 1004*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1005*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1006*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1007*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1008*7c478bd9Sstevel@tonic-gate } else { 1009*7c478bd9Sstevel@tonic-gate /* 1010*7c478bd9Sstevel@tonic-gate * If another property matched but this 1011*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1012*7c478bd9Sstevel@tonic-gate */ 1013*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1014*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1015*7c478bd9Sstevel@tonic-gate } 1016*7c478bd9Sstevel@tonic-gate } 1017*7c478bd9Sstevel@tonic-gate } 1018*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_fs_raw) > 0) { 1019*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_RAW, raw, 1020*7c478bd9Sstevel@tonic-gate sizeof (raw)) == Z_OK)) { 1021*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_fs_raw, raw) == 0) { 1022*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1023*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1024*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1025*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1026*7c478bd9Sstevel@tonic-gate } else { 1027*7c478bd9Sstevel@tonic-gate /* 1028*7c478bd9Sstevel@tonic-gate * If another property matched but this 1029*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1030*7c478bd9Sstevel@tonic-gate */ 1031*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1032*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1033*7c478bd9Sstevel@tonic-gate } 1034*7c478bd9Sstevel@tonic-gate } 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_fs_type) > 0) { 1037*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_TYPE, type, 1038*7c478bd9Sstevel@tonic-gate sizeof (type)) == Z_OK)) { 1039*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_fs_type, type) == 0) { 1040*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1041*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1042*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1043*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1044*7c478bd9Sstevel@tonic-gate } else { 1045*7c478bd9Sstevel@tonic-gate /* 1046*7c478bd9Sstevel@tonic-gate * If another property matched but this 1047*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1048*7c478bd9Sstevel@tonic-gate */ 1049*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1050*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1051*7c478bd9Sstevel@tonic-gate } 1052*7c478bd9Sstevel@tonic-gate } 1053*7c478bd9Sstevel@tonic-gate } 1054*7c478bd9Sstevel@tonic-gate } 1055*7c478bd9Sstevel@tonic-gate 1056*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1057*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate cur = firstmatch; 1060*7c478bd9Sstevel@tonic-gate 1061*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir, 1062*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_dir))) != Z_OK) 1063*7c478bd9Sstevel@tonic-gate return (err); 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_SPECIAL, tabptr->zone_fs_special, 1066*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_special))) != Z_OK) 1067*7c478bd9Sstevel@tonic-gate return (err); 1068*7c478bd9Sstevel@tonic-gate 1069*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_RAW, tabptr->zone_fs_raw, 1070*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_raw))) != Z_OK) 1071*7c478bd9Sstevel@tonic-gate return (err); 1072*7c478bd9Sstevel@tonic-gate 1073*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_TYPE, tabptr->zone_fs_type, 1074*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_type))) != Z_OK) 1075*7c478bd9Sstevel@tonic-gate return (err); 1076*7c478bd9Sstevel@tonic-gate 1077*7c478bd9Sstevel@tonic-gate /* options are optional */ 1078*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_options = NULL; 1079*7c478bd9Sstevel@tonic-gate for (options = cur->xmlChildrenNode; options != NULL; 1080*7c478bd9Sstevel@tonic-gate options = options->next) { 1081*7c478bd9Sstevel@tonic-gate if ((fetchprop(options, DTD_ATTR_NAME, options_str, 1082*7c478bd9Sstevel@tonic-gate sizeof (options_str)) != Z_OK)) 1083*7c478bd9Sstevel@tonic-gate break; 1084*7c478bd9Sstevel@tonic-gate if (zonecfg_add_fs_option(tabptr, options_str) != Z_OK) 1085*7c478bd9Sstevel@tonic-gate break; 1086*7c478bd9Sstevel@tonic-gate } 1087*7c478bd9Sstevel@tonic-gate return (Z_OK); 1088*7c478bd9Sstevel@tonic-gate } 1089*7c478bd9Sstevel@tonic-gate 1090*7c478bd9Sstevel@tonic-gate int 1091*7c478bd9Sstevel@tonic-gate zonecfg_lookup_ipd(zone_dochandle_t handle, struct zone_fstab *tabptr) 1092*7c478bd9Sstevel@tonic-gate { 1093*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, match; 1094*7c478bd9Sstevel@tonic-gate int err; 1095*7c478bd9Sstevel@tonic-gate char dirname[MAXPATHLEN]; 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1098*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1099*7c478bd9Sstevel@tonic-gate 1100*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1101*7c478bd9Sstevel@tonic-gate return (err); 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate /* 1104*7c478bd9Sstevel@tonic-gate * General algorithm: 1105*7c478bd9Sstevel@tonic-gate * Walk the list of children looking for matches on any properties 1106*7c478bd9Sstevel@tonic-gate * specified in the fstab parameter. If more than one resource 1107*7c478bd9Sstevel@tonic-gate * matches, we return Z_INSUFFICIENT_SPEC; if none match, we return 1108*7c478bd9Sstevel@tonic-gate * Z_NO_RESOURCE_ID. 1109*7c478bd9Sstevel@tonic-gate */ 1110*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1111*7c478bd9Sstevel@tonic-gate match = NULL; 1112*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1113*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_IPD)) 1114*7c478bd9Sstevel@tonic-gate continue; 1115*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_fs_dir) > 0) { 1116*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_DIR, dirname, 1117*7c478bd9Sstevel@tonic-gate sizeof (dirname)) == Z_OK) && 1118*7c478bd9Sstevel@tonic-gate (strcmp(tabptr->zone_fs_dir, dirname) == 0)) { 1119*7c478bd9Sstevel@tonic-gate if (match == NULL) 1120*7c478bd9Sstevel@tonic-gate match = cur; 1121*7c478bd9Sstevel@tonic-gate else 1122*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate } 1125*7c478bd9Sstevel@tonic-gate } 1126*7c478bd9Sstevel@tonic-gate 1127*7c478bd9Sstevel@tonic-gate if (match == NULL) 1128*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1129*7c478bd9Sstevel@tonic-gate 1130*7c478bd9Sstevel@tonic-gate cur = match; 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir, 1133*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_dir))) != Z_OK) 1134*7c478bd9Sstevel@tonic-gate return (err); 1135*7c478bd9Sstevel@tonic-gate 1136*7c478bd9Sstevel@tonic-gate return (Z_OK); 1137*7c478bd9Sstevel@tonic-gate } 1138*7c478bd9Sstevel@tonic-gate 1139*7c478bd9Sstevel@tonic-gate /* 1140*7c478bd9Sstevel@tonic-gate * Compare two IP addresses in string form. Allow for the possibility that 1141*7c478bd9Sstevel@tonic-gate * one might have "/<prefix-length>" at the end: allow a match on just the 1142*7c478bd9Sstevel@tonic-gate * IP address (or host name) part. 1143*7c478bd9Sstevel@tonic-gate */ 1144*7c478bd9Sstevel@tonic-gate 1145*7c478bd9Sstevel@tonic-gate boolean_t 1146*7c478bd9Sstevel@tonic-gate zonecfg_same_net_address(char *a1, char *a2) 1147*7c478bd9Sstevel@tonic-gate { 1148*7c478bd9Sstevel@tonic-gate char *slashp, *slashp1, *slashp2; 1149*7c478bd9Sstevel@tonic-gate int result; 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate if (strcmp(a1, a2) == 0) 1152*7c478bd9Sstevel@tonic-gate return (B_TRUE); 1153*7c478bd9Sstevel@tonic-gate 1154*7c478bd9Sstevel@tonic-gate /* 1155*7c478bd9Sstevel@tonic-gate * If neither has a slash or both do, they need to match to be 1156*7c478bd9Sstevel@tonic-gate * considered the same, but they did not match above, so fail. 1157*7c478bd9Sstevel@tonic-gate */ 1158*7c478bd9Sstevel@tonic-gate slashp1 = strchr(a1, '/'); 1159*7c478bd9Sstevel@tonic-gate slashp2 = strchr(a2, '/'); 1160*7c478bd9Sstevel@tonic-gate if ((slashp1 == NULL && slashp2 == NULL) || 1161*7c478bd9Sstevel@tonic-gate (slashp1 != NULL && slashp2 != NULL)) 1162*7c478bd9Sstevel@tonic-gate return (B_FALSE); 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate /* 1165*7c478bd9Sstevel@tonic-gate * Only one had a slash: pick that one, zero out the slash, compare 1166*7c478bd9Sstevel@tonic-gate * the "address only" strings, restore the slash, and return the 1167*7c478bd9Sstevel@tonic-gate * result of the comparison. 1168*7c478bd9Sstevel@tonic-gate */ 1169*7c478bd9Sstevel@tonic-gate slashp = (slashp1 == NULL) ? slashp2 : slashp1; 1170*7c478bd9Sstevel@tonic-gate *slashp = '\0'; 1171*7c478bd9Sstevel@tonic-gate result = strcmp(a1, a2); 1172*7c478bd9Sstevel@tonic-gate *slashp = '/'; 1173*7c478bd9Sstevel@tonic-gate return ((result == 0)); 1174*7c478bd9Sstevel@tonic-gate } 1175*7c478bd9Sstevel@tonic-gate 1176*7c478bd9Sstevel@tonic-gate int 1177*7c478bd9Sstevel@tonic-gate zonecfg_valid_net_address(char *address, struct lifreq *lifr) 1178*7c478bd9Sstevel@tonic-gate { 1179*7c478bd9Sstevel@tonic-gate struct sockaddr_in *sin4; 1180*7c478bd9Sstevel@tonic-gate struct sockaddr_in6 *sin6; 1181*7c478bd9Sstevel@tonic-gate struct addrinfo hints, *result; 1182*7c478bd9Sstevel@tonic-gate char *slashp = strchr(address, '/'); 1183*7c478bd9Sstevel@tonic-gate 1184*7c478bd9Sstevel@tonic-gate bzero(lifr, sizeof (struct lifreq)); 1185*7c478bd9Sstevel@tonic-gate sin4 = (struct sockaddr_in *)&lifr->lifr_addr; 1186*7c478bd9Sstevel@tonic-gate sin6 = (struct sockaddr_in6 *)&lifr->lifr_addr; 1187*7c478bd9Sstevel@tonic-gate if (slashp != NULL) 1188*7c478bd9Sstevel@tonic-gate *slashp = '\0'; 1189*7c478bd9Sstevel@tonic-gate if (inet_pton(AF_INET, address, &sin4->sin_addr) == 1) { 1190*7c478bd9Sstevel@tonic-gate sin4->sin_family = AF_INET; 1191*7c478bd9Sstevel@tonic-gate } else if (inet_pton(AF_INET6, address, &sin6->sin6_addr) == 1) { 1192*7c478bd9Sstevel@tonic-gate if (slashp == NULL) 1193*7c478bd9Sstevel@tonic-gate return (Z_IPV6_ADDR_PREFIX_LEN); 1194*7c478bd9Sstevel@tonic-gate sin6->sin6_family = AF_INET6; 1195*7c478bd9Sstevel@tonic-gate } else { 1196*7c478bd9Sstevel@tonic-gate /* "address" may be a host name */ 1197*7c478bd9Sstevel@tonic-gate (void) memset(&hints, 0, sizeof (hints)); 1198*7c478bd9Sstevel@tonic-gate hints.ai_family = PF_INET; 1199*7c478bd9Sstevel@tonic-gate if (getaddrinfo(address, NULL, &hints, &result) != 0) 1200*7c478bd9Sstevel@tonic-gate return (Z_BOGUS_ADDRESS); 1201*7c478bd9Sstevel@tonic-gate sin4->sin_family = result->ai_family; 1202*7c478bd9Sstevel@tonic-gate (void) memcpy(&sin4->sin_addr, 1203*7c478bd9Sstevel@tonic-gate /* LINTED E_BAD_PTR_CAST_ALIGN */ 1204*7c478bd9Sstevel@tonic-gate &((struct sockaddr_in *)result->ai_addr)->sin_addr, 1205*7c478bd9Sstevel@tonic-gate sizeof (struct in_addr)); 1206*7c478bd9Sstevel@tonic-gate freeaddrinfo(result); 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate return (Z_OK); 1209*7c478bd9Sstevel@tonic-gate } 1210*7c478bd9Sstevel@tonic-gate 1211*7c478bd9Sstevel@tonic-gate int 1212*7c478bd9Sstevel@tonic-gate zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 1213*7c478bd9Sstevel@tonic-gate { 1214*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, firstmatch; 1215*7c478bd9Sstevel@tonic-gate int err; 1216*7c478bd9Sstevel@tonic-gate char address[INET6_ADDRSTRLEN], physical[LIFNAMSIZ]; 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1219*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1220*7c478bd9Sstevel@tonic-gate 1221*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1222*7c478bd9Sstevel@tonic-gate return (err); 1223*7c478bd9Sstevel@tonic-gate 1224*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1225*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1226*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1227*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_NET)) 1228*7c478bd9Sstevel@tonic-gate continue; 1229*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_nwif_physical) > 0) { 1230*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_PHYSICAL, physical, 1231*7c478bd9Sstevel@tonic-gate sizeof (physical)) == Z_OK) && 1232*7c478bd9Sstevel@tonic-gate (strcmp(tabptr->zone_nwif_physical, 1233*7c478bd9Sstevel@tonic-gate physical) == 0)) { 1234*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1235*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1236*7c478bd9Sstevel@tonic-gate else 1237*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1238*7c478bd9Sstevel@tonic-gate } 1239*7c478bd9Sstevel@tonic-gate } 1240*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_nwif_address) > 0) { 1241*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_ADDRESS, address, 1242*7c478bd9Sstevel@tonic-gate sizeof (address)) == Z_OK)) { 1243*7c478bd9Sstevel@tonic-gate if (zonecfg_same_net_address( 1244*7c478bd9Sstevel@tonic-gate tabptr->zone_nwif_address, address)) { 1245*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1246*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1247*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1248*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1249*7c478bd9Sstevel@tonic-gate } else { 1250*7c478bd9Sstevel@tonic-gate /* 1251*7c478bd9Sstevel@tonic-gate * If another property matched but this 1252*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1253*7c478bd9Sstevel@tonic-gate */ 1254*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1255*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1256*7c478bd9Sstevel@tonic-gate } 1257*7c478bd9Sstevel@tonic-gate } 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate } 1260*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1261*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1262*7c478bd9Sstevel@tonic-gate 1263*7c478bd9Sstevel@tonic-gate cur = firstmatch; 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical, 1266*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_nwif_physical))) != Z_OK) 1267*7c478bd9Sstevel@tonic-gate return (err); 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_ADDRESS, tabptr->zone_nwif_address, 1270*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_nwif_address))) != Z_OK) 1271*7c478bd9Sstevel@tonic-gate return (err); 1272*7c478bd9Sstevel@tonic-gate 1273*7c478bd9Sstevel@tonic-gate return (Z_OK); 1274*7c478bd9Sstevel@tonic-gate } 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate static int 1277*7c478bd9Sstevel@tonic-gate zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 1278*7c478bd9Sstevel@tonic-gate { 1279*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur; 1280*7c478bd9Sstevel@tonic-gate int err; 1281*7c478bd9Sstevel@tonic-gate 1282*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); 1283*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_ADDRESS, 1284*7c478bd9Sstevel@tonic-gate tabptr->zone_nwif_address)) != Z_OK) 1285*7c478bd9Sstevel@tonic-gate return (err); 1286*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_PHYSICAL, 1287*7c478bd9Sstevel@tonic-gate tabptr->zone_nwif_physical)) != Z_OK) 1288*7c478bd9Sstevel@tonic-gate return (err); 1289*7c478bd9Sstevel@tonic-gate return (Z_OK); 1290*7c478bd9Sstevel@tonic-gate } 1291*7c478bd9Sstevel@tonic-gate 1292*7c478bd9Sstevel@tonic-gate int 1293*7c478bd9Sstevel@tonic-gate zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 1294*7c478bd9Sstevel@tonic-gate { 1295*7c478bd9Sstevel@tonic-gate int err; 1296*7c478bd9Sstevel@tonic-gate 1297*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1298*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1299*7c478bd9Sstevel@tonic-gate 1300*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1301*7c478bd9Sstevel@tonic-gate return (err); 1302*7c478bd9Sstevel@tonic-gate 1303*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_nwif_core(handle, tabptr)) != Z_OK) 1304*7c478bd9Sstevel@tonic-gate return (err); 1305*7c478bd9Sstevel@tonic-gate 1306*7c478bd9Sstevel@tonic-gate return (Z_OK); 1307*7c478bd9Sstevel@tonic-gate } 1308*7c478bd9Sstevel@tonic-gate 1309*7c478bd9Sstevel@tonic-gate static int 1310*7c478bd9Sstevel@tonic-gate zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 1311*7c478bd9Sstevel@tonic-gate { 1312*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 1313*7c478bd9Sstevel@tonic-gate boolean_t addr_match, phys_match; 1314*7c478bd9Sstevel@tonic-gate 1315*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1316*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_NET)) 1317*7c478bd9Sstevel@tonic-gate continue; 1318*7c478bd9Sstevel@tonic-gate 1319*7c478bd9Sstevel@tonic-gate addr_match = match_prop(cur, DTD_ATTR_ADDRESS, 1320*7c478bd9Sstevel@tonic-gate tabptr->zone_nwif_address); 1321*7c478bd9Sstevel@tonic-gate phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, 1322*7c478bd9Sstevel@tonic-gate tabptr->zone_nwif_physical); 1323*7c478bd9Sstevel@tonic-gate 1324*7c478bd9Sstevel@tonic-gate if (addr_match && phys_match) { 1325*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 1326*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 1327*7c478bd9Sstevel@tonic-gate return (Z_OK); 1328*7c478bd9Sstevel@tonic-gate } 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1331*7c478bd9Sstevel@tonic-gate } 1332*7c478bd9Sstevel@tonic-gate 1333*7c478bd9Sstevel@tonic-gate int 1334*7c478bd9Sstevel@tonic-gate zonecfg_delete_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 1335*7c478bd9Sstevel@tonic-gate { 1336*7c478bd9Sstevel@tonic-gate int err; 1337*7c478bd9Sstevel@tonic-gate 1338*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1339*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1340*7c478bd9Sstevel@tonic-gate 1341*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1342*7c478bd9Sstevel@tonic-gate return (err); 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_nwif_core(handle, tabptr)) != Z_OK) 1345*7c478bd9Sstevel@tonic-gate return (err); 1346*7c478bd9Sstevel@tonic-gate 1347*7c478bd9Sstevel@tonic-gate return (Z_OK); 1348*7c478bd9Sstevel@tonic-gate } 1349*7c478bd9Sstevel@tonic-gate 1350*7c478bd9Sstevel@tonic-gate int 1351*7c478bd9Sstevel@tonic-gate zonecfg_modify_nwif( 1352*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 1353*7c478bd9Sstevel@tonic-gate struct zone_nwiftab *oldtabptr, 1354*7c478bd9Sstevel@tonic-gate struct zone_nwiftab *newtabptr) 1355*7c478bd9Sstevel@tonic-gate { 1356*7c478bd9Sstevel@tonic-gate int err; 1357*7c478bd9Sstevel@tonic-gate 1358*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || newtabptr == NULL) 1359*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1362*7c478bd9Sstevel@tonic-gate return (err); 1363*7c478bd9Sstevel@tonic-gate 1364*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_nwif_core(handle, oldtabptr)) != Z_OK) 1365*7c478bd9Sstevel@tonic-gate return (err); 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_nwif_core(handle, newtabptr)) != Z_OK) 1368*7c478bd9Sstevel@tonic-gate return (err); 1369*7c478bd9Sstevel@tonic-gate 1370*7c478bd9Sstevel@tonic-gate return (Z_OK); 1371*7c478bd9Sstevel@tonic-gate } 1372*7c478bd9Sstevel@tonic-gate 1373*7c478bd9Sstevel@tonic-gate int 1374*7c478bd9Sstevel@tonic-gate zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) 1375*7c478bd9Sstevel@tonic-gate { 1376*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, firstmatch; 1377*7c478bd9Sstevel@tonic-gate int err; 1378*7c478bd9Sstevel@tonic-gate char match[MAXPATHLEN]; 1379*7c478bd9Sstevel@tonic-gate 1380*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1381*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1382*7c478bd9Sstevel@tonic-gate 1383*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1384*7c478bd9Sstevel@tonic-gate return (err); 1385*7c478bd9Sstevel@tonic-gate 1386*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1387*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1388*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1389*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_DEVICE)) 1390*7c478bd9Sstevel@tonic-gate continue; 1391*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_dev_match) == 0) 1392*7c478bd9Sstevel@tonic-gate continue; 1393*7c478bd9Sstevel@tonic-gate 1394*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_MATCH, match, 1395*7c478bd9Sstevel@tonic-gate sizeof (match)) == Z_OK)) { 1396*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_dev_match, 1397*7c478bd9Sstevel@tonic-gate match) == 0) { 1398*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1399*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1400*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1401*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1402*7c478bd9Sstevel@tonic-gate } else { 1403*7c478bd9Sstevel@tonic-gate /* 1404*7c478bd9Sstevel@tonic-gate * If another property matched but this 1405*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1406*7c478bd9Sstevel@tonic-gate */ 1407*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1408*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1409*7c478bd9Sstevel@tonic-gate } 1410*7c478bd9Sstevel@tonic-gate } 1411*7c478bd9Sstevel@tonic-gate } 1412*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1413*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate cur = firstmatch; 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, 1418*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_dev_match))) != Z_OK) 1419*7c478bd9Sstevel@tonic-gate return (err); 1420*7c478bd9Sstevel@tonic-gate 1421*7c478bd9Sstevel@tonic-gate return (Z_OK); 1422*7c478bd9Sstevel@tonic-gate } 1423*7c478bd9Sstevel@tonic-gate 1424*7c478bd9Sstevel@tonic-gate static int 1425*7c478bd9Sstevel@tonic-gate zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) 1426*7c478bd9Sstevel@tonic-gate { 1427*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur; 1428*7c478bd9Sstevel@tonic-gate int err; 1429*7c478bd9Sstevel@tonic-gate 1430*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); 1431*7c478bd9Sstevel@tonic-gate 1432*7c478bd9Sstevel@tonic-gate if ((err = newprop(handle, newnode, DTD_ATTR_MATCH, 1433*7c478bd9Sstevel@tonic-gate tabptr->zone_dev_match)) != Z_OK) 1434*7c478bd9Sstevel@tonic-gate return (err); 1435*7c478bd9Sstevel@tonic-gate 1436*7c478bd9Sstevel@tonic-gate return (Z_OK); 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate int 1440*7c478bd9Sstevel@tonic-gate zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) 1441*7c478bd9Sstevel@tonic-gate { 1442*7c478bd9Sstevel@tonic-gate int err; 1443*7c478bd9Sstevel@tonic-gate 1444*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1445*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1446*7c478bd9Sstevel@tonic-gate 1447*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1448*7c478bd9Sstevel@tonic-gate return (err); 1449*7c478bd9Sstevel@tonic-gate 1450*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_dev_core(handle, tabptr)) != Z_OK) 1451*7c478bd9Sstevel@tonic-gate return (err); 1452*7c478bd9Sstevel@tonic-gate 1453*7c478bd9Sstevel@tonic-gate return (Z_OK); 1454*7c478bd9Sstevel@tonic-gate } 1455*7c478bd9Sstevel@tonic-gate 1456*7c478bd9Sstevel@tonic-gate static int 1457*7c478bd9Sstevel@tonic-gate zonecfg_delete_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) 1458*7c478bd9Sstevel@tonic-gate { 1459*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 1460*7c478bd9Sstevel@tonic-gate int match_match; 1461*7c478bd9Sstevel@tonic-gate 1462*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1463*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_DEVICE)) 1464*7c478bd9Sstevel@tonic-gate continue; 1465*7c478bd9Sstevel@tonic-gate 1466*7c478bd9Sstevel@tonic-gate match_match = match_prop(cur, DTD_ATTR_MATCH, 1467*7c478bd9Sstevel@tonic-gate tabptr->zone_dev_match); 1468*7c478bd9Sstevel@tonic-gate 1469*7c478bd9Sstevel@tonic-gate if (match_match) { 1470*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 1471*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 1472*7c478bd9Sstevel@tonic-gate return (Z_OK); 1473*7c478bd9Sstevel@tonic-gate } 1474*7c478bd9Sstevel@tonic-gate } 1475*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1476*7c478bd9Sstevel@tonic-gate } 1477*7c478bd9Sstevel@tonic-gate 1478*7c478bd9Sstevel@tonic-gate int 1479*7c478bd9Sstevel@tonic-gate zonecfg_delete_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) 1480*7c478bd9Sstevel@tonic-gate { 1481*7c478bd9Sstevel@tonic-gate int err; 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1484*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1485*7c478bd9Sstevel@tonic-gate 1486*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1487*7c478bd9Sstevel@tonic-gate return (err); 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_dev_core(handle, tabptr)) != Z_OK) 1490*7c478bd9Sstevel@tonic-gate return (err); 1491*7c478bd9Sstevel@tonic-gate 1492*7c478bd9Sstevel@tonic-gate return (Z_OK); 1493*7c478bd9Sstevel@tonic-gate } 1494*7c478bd9Sstevel@tonic-gate 1495*7c478bd9Sstevel@tonic-gate int 1496*7c478bd9Sstevel@tonic-gate zonecfg_modify_dev( 1497*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 1498*7c478bd9Sstevel@tonic-gate struct zone_devtab *oldtabptr, 1499*7c478bd9Sstevel@tonic-gate struct zone_devtab *newtabptr) 1500*7c478bd9Sstevel@tonic-gate { 1501*7c478bd9Sstevel@tonic-gate int err; 1502*7c478bd9Sstevel@tonic-gate 1503*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || newtabptr == NULL) 1504*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1505*7c478bd9Sstevel@tonic-gate 1506*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1507*7c478bd9Sstevel@tonic-gate return (err); 1508*7c478bd9Sstevel@tonic-gate 1509*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_dev_core(handle, oldtabptr)) != Z_OK) 1510*7c478bd9Sstevel@tonic-gate return (err); 1511*7c478bd9Sstevel@tonic-gate 1512*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_dev_core(handle, newtabptr)) != Z_OK) 1513*7c478bd9Sstevel@tonic-gate return (err); 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate return (Z_OK); 1516*7c478bd9Sstevel@tonic-gate } 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate /* 1519*7c478bd9Sstevel@tonic-gate * This is the set of devices which must be present in every zone. Users 1520*7c478bd9Sstevel@tonic-gate * can augment this list with additional device rules in their zone 1521*7c478bd9Sstevel@tonic-gate * configuration, but at present cannot remove any of the this set of 1522*7c478bd9Sstevel@tonic-gate * standard devices. All matching is done by /dev pathname (the "/dev" 1523*7c478bd9Sstevel@tonic-gate * part is implicit. Try to keep rules which match a large number of 1524*7c478bd9Sstevel@tonic-gate * devices (like the pts rule) first. 1525*7c478bd9Sstevel@tonic-gate */ 1526*7c478bd9Sstevel@tonic-gate static const char *standard_devs[] = { 1527*7c478bd9Sstevel@tonic-gate "pts/*", 1528*7c478bd9Sstevel@tonic-gate "ptmx", 1529*7c478bd9Sstevel@tonic-gate "random", 1530*7c478bd9Sstevel@tonic-gate "urandom", 1531*7c478bd9Sstevel@tonic-gate "poll", 1532*7c478bd9Sstevel@tonic-gate "pool", 1533*7c478bd9Sstevel@tonic-gate "kstat", 1534*7c478bd9Sstevel@tonic-gate "zero", 1535*7c478bd9Sstevel@tonic-gate "null", 1536*7c478bd9Sstevel@tonic-gate "crypto", 1537*7c478bd9Sstevel@tonic-gate "cryptoadm", 1538*7c478bd9Sstevel@tonic-gate "ticots", 1539*7c478bd9Sstevel@tonic-gate "ticotsord", 1540*7c478bd9Sstevel@tonic-gate "ticlts", 1541*7c478bd9Sstevel@tonic-gate "lo0", 1542*7c478bd9Sstevel@tonic-gate "lo1", 1543*7c478bd9Sstevel@tonic-gate "lo2", 1544*7c478bd9Sstevel@tonic-gate "lo3", 1545*7c478bd9Sstevel@tonic-gate "sad/user", 1546*7c478bd9Sstevel@tonic-gate "tty", 1547*7c478bd9Sstevel@tonic-gate "logindmux", 1548*7c478bd9Sstevel@tonic-gate "log", 1549*7c478bd9Sstevel@tonic-gate "conslog", 1550*7c478bd9Sstevel@tonic-gate "arp", 1551*7c478bd9Sstevel@tonic-gate "tcp", 1552*7c478bd9Sstevel@tonic-gate "tcp6", 1553*7c478bd9Sstevel@tonic-gate "udp", 1554*7c478bd9Sstevel@tonic-gate "udp6", 1555*7c478bd9Sstevel@tonic-gate "sysevent", 1556*7c478bd9Sstevel@tonic-gate #ifdef __sparc 1557*7c478bd9Sstevel@tonic-gate "openprom", 1558*7c478bd9Sstevel@tonic-gate #endif 1559*7c478bd9Sstevel@tonic-gate "cpu/self/cpuid", 1560*7c478bd9Sstevel@tonic-gate "dtrace/helper", 1561*7c478bd9Sstevel@tonic-gate NULL 1562*7c478bd9Sstevel@tonic-gate }; 1563*7c478bd9Sstevel@tonic-gate 1564*7c478bd9Sstevel@tonic-gate /* 1565*7c478bd9Sstevel@tonic-gate * This function finds everything mounted under a zone's rootpath. 1566*7c478bd9Sstevel@tonic-gate * This returns the number of mounts under rootpath, or -1 on error. 1567*7c478bd9Sstevel@tonic-gate * callback is called once per mount found with the first argument 1568*7c478bd9Sstevel@tonic-gate * pointing to the mount point. 1569*7c478bd9Sstevel@tonic-gate * 1570*7c478bd9Sstevel@tonic-gate * If the callback function returns non-zero zonecfg_find_mounts 1571*7c478bd9Sstevel@tonic-gate * aborts with an error. 1572*7c478bd9Sstevel@tonic-gate */ 1573*7c478bd9Sstevel@tonic-gate 1574*7c478bd9Sstevel@tonic-gate int 1575*7c478bd9Sstevel@tonic-gate zonecfg_find_mounts(char *rootpath, int (*callback)(const char *, void *), 1576*7c478bd9Sstevel@tonic-gate void *priv) { 1577*7c478bd9Sstevel@tonic-gate FILE *mnttab; 1578*7c478bd9Sstevel@tonic-gate struct mnttab m; 1579*7c478bd9Sstevel@tonic-gate size_t l; 1580*7c478bd9Sstevel@tonic-gate int rv = 0; 1581*7c478bd9Sstevel@tonic-gate 1582*7c478bd9Sstevel@tonic-gate assert(rootpath != NULL); 1583*7c478bd9Sstevel@tonic-gate 1584*7c478bd9Sstevel@tonic-gate l = strlen(rootpath); 1585*7c478bd9Sstevel@tonic-gate 1586*7c478bd9Sstevel@tonic-gate mnttab = fopen("/etc/mnttab", "r"); 1587*7c478bd9Sstevel@tonic-gate 1588*7c478bd9Sstevel@tonic-gate if (mnttab == NULL) 1589*7c478bd9Sstevel@tonic-gate return (-1); 1590*7c478bd9Sstevel@tonic-gate 1591*7c478bd9Sstevel@tonic-gate if (ioctl(fileno(mnttab), MNTIOC_SHOWHIDDEN, NULL) < 0) { 1592*7c478bd9Sstevel@tonic-gate rv = -1; 1593*7c478bd9Sstevel@tonic-gate goto out; 1594*7c478bd9Sstevel@tonic-gate } 1595*7c478bd9Sstevel@tonic-gate 1596*7c478bd9Sstevel@tonic-gate while (!getmntent(mnttab, &m)) { 1597*7c478bd9Sstevel@tonic-gate if ((strncmp(rootpath, m.mnt_mountp, l) == 0) && 1598*7c478bd9Sstevel@tonic-gate (m.mnt_mountp[l] == '/')) { 1599*7c478bd9Sstevel@tonic-gate rv++; 1600*7c478bd9Sstevel@tonic-gate if (callback == NULL) 1601*7c478bd9Sstevel@tonic-gate continue; 1602*7c478bd9Sstevel@tonic-gate if (callback(m.mnt_mountp, priv)) { 1603*7c478bd9Sstevel@tonic-gate rv = -1; 1604*7c478bd9Sstevel@tonic-gate goto out; 1605*7c478bd9Sstevel@tonic-gate 1606*7c478bd9Sstevel@tonic-gate } 1607*7c478bd9Sstevel@tonic-gate } 1608*7c478bd9Sstevel@tonic-gate } 1609*7c478bd9Sstevel@tonic-gate 1610*7c478bd9Sstevel@tonic-gate out: 1611*7c478bd9Sstevel@tonic-gate (void) fclose(mnttab); 1612*7c478bd9Sstevel@tonic-gate return (rv); 1613*7c478bd9Sstevel@tonic-gate } 1614*7c478bd9Sstevel@tonic-gate 1615*7c478bd9Sstevel@tonic-gate /* 1616*7c478bd9Sstevel@tonic-gate * This routine is used to determine if a given device should appear in the 1617*7c478bd9Sstevel@tonic-gate * zone represented by 'handle'. First it consults the list of "standard" 1618*7c478bd9Sstevel@tonic-gate * zone devices. Then it scans the user-supplied device entries. 1619*7c478bd9Sstevel@tonic-gate */ 1620*7c478bd9Sstevel@tonic-gate int 1621*7c478bd9Sstevel@tonic-gate zonecfg_match_dev(zone_dochandle_t handle, char *devpath, 1622*7c478bd9Sstevel@tonic-gate struct zone_devtab *out_match) 1623*7c478bd9Sstevel@tonic-gate { 1624*7c478bd9Sstevel@tonic-gate int err; 1625*7c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE; 1626*7c478bd9Sstevel@tonic-gate char match[MAXPATHLEN]; 1627*7c478bd9Sstevel@tonic-gate const char **stdmatch; 1628*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 1629*7c478bd9Sstevel@tonic-gate 1630*7c478bd9Sstevel@tonic-gate if (handle == NULL || devpath == NULL) 1631*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1632*7c478bd9Sstevel@tonic-gate 1633*7c478bd9Sstevel@tonic-gate /* 1634*7c478bd9Sstevel@tonic-gate * Check the "standard" devices which we require to be present. 1635*7c478bd9Sstevel@tonic-gate */ 1636*7c478bd9Sstevel@tonic-gate for (stdmatch = &standard_devs[0]; *stdmatch != NULL; stdmatch++) { 1637*7c478bd9Sstevel@tonic-gate /* 1638*7c478bd9Sstevel@tonic-gate * fnmatch gives us simple but powerful shell-style matching. 1639*7c478bd9Sstevel@tonic-gate */ 1640*7c478bd9Sstevel@tonic-gate if (fnmatch(*stdmatch, devpath, FNM_PATHNAME) == 0) { 1641*7c478bd9Sstevel@tonic-gate if (!out_match) 1642*7c478bd9Sstevel@tonic-gate return (Z_OK); 1643*7c478bd9Sstevel@tonic-gate (void) snprintf(out_match->zone_dev_match, 1644*7c478bd9Sstevel@tonic-gate sizeof (out_match->zone_dev_match), 1645*7c478bd9Sstevel@tonic-gate "/dev/%s", *stdmatch); 1646*7c478bd9Sstevel@tonic-gate return (Z_OK); 1647*7c478bd9Sstevel@tonic-gate } 1648*7c478bd9Sstevel@tonic-gate } 1649*7c478bd9Sstevel@tonic-gate 1650*7c478bd9Sstevel@tonic-gate /* 1651*7c478bd9Sstevel@tonic-gate * We got no hits in the set of standard devices. On to the user 1652*7c478bd9Sstevel@tonic-gate * supplied ones. 1653*7c478bd9Sstevel@tonic-gate */ 1654*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) { 1655*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = NULL; 1656*7c478bd9Sstevel@tonic-gate return (err); 1657*7c478bd9Sstevel@tonic-gate } 1658*7c478bd9Sstevel@tonic-gate 1659*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1660*7c478bd9Sstevel@tonic-gate cur = cur->xmlChildrenNode; 1661*7c478bd9Sstevel@tonic-gate if (cur == NULL) 1662*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 1663*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur; 1664*7c478bd9Sstevel@tonic-gate 1665*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) { 1666*7c478bd9Sstevel@tonic-gate char *m; 1667*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_DEVICE) != 0) 1668*7c478bd9Sstevel@tonic-gate continue; 1669*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_MATCH, match, 1670*7c478bd9Sstevel@tonic-gate sizeof (match))) != Z_OK) { 1671*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 1672*7c478bd9Sstevel@tonic-gate return (err); 1673*7c478bd9Sstevel@tonic-gate } 1674*7c478bd9Sstevel@tonic-gate m = match; 1675*7c478bd9Sstevel@tonic-gate /* 1676*7c478bd9Sstevel@tonic-gate * fnmatch gives us simple but powerful shell-style matching; 1677*7c478bd9Sstevel@tonic-gate * but first, we need to strip out /dev/ from the matching rule. 1678*7c478bd9Sstevel@tonic-gate */ 1679*7c478bd9Sstevel@tonic-gate if (strncmp(m, "/dev/", 5) == 0) 1680*7c478bd9Sstevel@tonic-gate m += 5; 1681*7c478bd9Sstevel@tonic-gate 1682*7c478bd9Sstevel@tonic-gate if (fnmatch(m, devpath, FNM_PATHNAME) == 0) { 1683*7c478bd9Sstevel@tonic-gate found = B_TRUE; 1684*7c478bd9Sstevel@tonic-gate break; 1685*7c478bd9Sstevel@tonic-gate } 1686*7c478bd9Sstevel@tonic-gate } 1687*7c478bd9Sstevel@tonic-gate 1688*7c478bd9Sstevel@tonic-gate if (!found) 1689*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 1690*7c478bd9Sstevel@tonic-gate 1691*7c478bd9Sstevel@tonic-gate if (!out_match) 1692*7c478bd9Sstevel@tonic-gate return (Z_OK); 1693*7c478bd9Sstevel@tonic-gate 1694*7c478bd9Sstevel@tonic-gate (void) strlcpy(out_match->zone_dev_match, match, 1695*7c478bd9Sstevel@tonic-gate sizeof (out_match->zone_dev_match)); 1696*7c478bd9Sstevel@tonic-gate return (Z_OK); 1697*7c478bd9Sstevel@tonic-gate } 1698*7c478bd9Sstevel@tonic-gate 1699*7c478bd9Sstevel@tonic-gate int 1700*7c478bd9Sstevel@tonic-gate zonecfg_lookup_attr(zone_dochandle_t handle, struct zone_attrtab *tabptr) 1701*7c478bd9Sstevel@tonic-gate { 1702*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, firstmatch; 1703*7c478bd9Sstevel@tonic-gate int err; 1704*7c478bd9Sstevel@tonic-gate char name[MAXNAMELEN], type[MAXNAMELEN], value[MAXNAMELEN]; 1705*7c478bd9Sstevel@tonic-gate 1706*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1707*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1708*7c478bd9Sstevel@tonic-gate 1709*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1710*7c478bd9Sstevel@tonic-gate return (err); 1711*7c478bd9Sstevel@tonic-gate 1712*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1713*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1714*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1715*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ATTR)) 1716*7c478bd9Sstevel@tonic-gate continue; 1717*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_attr_name) > 0) { 1718*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_NAME, name, 1719*7c478bd9Sstevel@tonic-gate sizeof (name)) == Z_OK) && 1720*7c478bd9Sstevel@tonic-gate (strcmp(tabptr->zone_attr_name, name) == 0)) { 1721*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1722*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1723*7c478bd9Sstevel@tonic-gate else 1724*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1725*7c478bd9Sstevel@tonic-gate } 1726*7c478bd9Sstevel@tonic-gate } 1727*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_attr_type) > 0) { 1728*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_TYPE, type, 1729*7c478bd9Sstevel@tonic-gate sizeof (type)) == Z_OK)) { 1730*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_attr_type, type) == 0) { 1731*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1732*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1733*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1734*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1735*7c478bd9Sstevel@tonic-gate } else { 1736*7c478bd9Sstevel@tonic-gate /* 1737*7c478bd9Sstevel@tonic-gate * If another property matched but this 1738*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1739*7c478bd9Sstevel@tonic-gate */ 1740*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1741*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1742*7c478bd9Sstevel@tonic-gate } 1743*7c478bd9Sstevel@tonic-gate } 1744*7c478bd9Sstevel@tonic-gate } 1745*7c478bd9Sstevel@tonic-gate if (strlen(tabptr->zone_attr_value) > 0) { 1746*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_VALUE, value, 1747*7c478bd9Sstevel@tonic-gate sizeof (value)) == Z_OK)) { 1748*7c478bd9Sstevel@tonic-gate if (strcmp(tabptr->zone_attr_value, value) == 1749*7c478bd9Sstevel@tonic-gate 0) { 1750*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1751*7c478bd9Sstevel@tonic-gate firstmatch = cur; 1752*7c478bd9Sstevel@tonic-gate else if (firstmatch != cur) 1753*7c478bd9Sstevel@tonic-gate return (Z_INSUFFICIENT_SPEC); 1754*7c478bd9Sstevel@tonic-gate } else { 1755*7c478bd9Sstevel@tonic-gate /* 1756*7c478bd9Sstevel@tonic-gate * If another property matched but this 1757*7c478bd9Sstevel@tonic-gate * one doesn't then reset firstmatch. 1758*7c478bd9Sstevel@tonic-gate */ 1759*7c478bd9Sstevel@tonic-gate if (firstmatch == cur) 1760*7c478bd9Sstevel@tonic-gate firstmatch = NULL; 1761*7c478bd9Sstevel@tonic-gate } 1762*7c478bd9Sstevel@tonic-gate } 1763*7c478bd9Sstevel@tonic-gate } 1764*7c478bd9Sstevel@tonic-gate } 1765*7c478bd9Sstevel@tonic-gate if (firstmatch == NULL) 1766*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1767*7c478bd9Sstevel@tonic-gate 1768*7c478bd9Sstevel@tonic-gate cur = firstmatch; 1769*7c478bd9Sstevel@tonic-gate 1770*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_NAME, tabptr->zone_attr_name, 1771*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_name))) != Z_OK) 1772*7c478bd9Sstevel@tonic-gate return (err); 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_TYPE, tabptr->zone_attr_type, 1775*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_type))) != Z_OK) 1776*7c478bd9Sstevel@tonic-gate return (err); 1777*7c478bd9Sstevel@tonic-gate 1778*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_VALUE, tabptr->zone_attr_value, 1779*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_value))) != Z_OK) 1780*7c478bd9Sstevel@tonic-gate return (err); 1781*7c478bd9Sstevel@tonic-gate 1782*7c478bd9Sstevel@tonic-gate return (Z_OK); 1783*7c478bd9Sstevel@tonic-gate } 1784*7c478bd9Sstevel@tonic-gate 1785*7c478bd9Sstevel@tonic-gate static int 1786*7c478bd9Sstevel@tonic-gate zonecfg_add_attr_core(zone_dochandle_t handle, struct zone_attrtab *tabptr) 1787*7c478bd9Sstevel@tonic-gate { 1788*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur; 1789*7c478bd9Sstevel@tonic-gate int err; 1790*7c478bd9Sstevel@tonic-gate 1791*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_ATTR, NULL); 1792*7c478bd9Sstevel@tonic-gate err = newprop(handle, newnode, DTD_ATTR_NAME, tabptr->zone_attr_name); 1793*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 1794*7c478bd9Sstevel@tonic-gate return (err); 1795*7c478bd9Sstevel@tonic-gate err = newprop(handle, newnode, DTD_ATTR_TYPE, tabptr->zone_attr_type); 1796*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 1797*7c478bd9Sstevel@tonic-gate return (err); 1798*7c478bd9Sstevel@tonic-gate err = newprop(handle, newnode, DTD_ATTR_VALUE, tabptr->zone_attr_value); 1799*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 1800*7c478bd9Sstevel@tonic-gate return (err); 1801*7c478bd9Sstevel@tonic-gate return (Z_OK); 1802*7c478bd9Sstevel@tonic-gate } 1803*7c478bd9Sstevel@tonic-gate 1804*7c478bd9Sstevel@tonic-gate int 1805*7c478bd9Sstevel@tonic-gate zonecfg_add_attr(zone_dochandle_t handle, struct zone_attrtab *tabptr) 1806*7c478bd9Sstevel@tonic-gate { 1807*7c478bd9Sstevel@tonic-gate int err; 1808*7c478bd9Sstevel@tonic-gate 1809*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1810*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1811*7c478bd9Sstevel@tonic-gate 1812*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1813*7c478bd9Sstevel@tonic-gate return (err); 1814*7c478bd9Sstevel@tonic-gate 1815*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_attr_core(handle, tabptr)) != Z_OK) 1816*7c478bd9Sstevel@tonic-gate return (err); 1817*7c478bd9Sstevel@tonic-gate 1818*7c478bd9Sstevel@tonic-gate return (Z_OK); 1819*7c478bd9Sstevel@tonic-gate } 1820*7c478bd9Sstevel@tonic-gate 1821*7c478bd9Sstevel@tonic-gate static int 1822*7c478bd9Sstevel@tonic-gate zonecfg_delete_attr_core(zone_dochandle_t handle, struct zone_attrtab *tabptr) 1823*7c478bd9Sstevel@tonic-gate { 1824*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 1825*7c478bd9Sstevel@tonic-gate int name_match, type_match, value_match; 1826*7c478bd9Sstevel@tonic-gate 1827*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1828*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_ATTR)) 1829*7c478bd9Sstevel@tonic-gate continue; 1830*7c478bd9Sstevel@tonic-gate 1831*7c478bd9Sstevel@tonic-gate name_match = match_prop(cur, DTD_ATTR_NAME, 1832*7c478bd9Sstevel@tonic-gate tabptr->zone_attr_name); 1833*7c478bd9Sstevel@tonic-gate type_match = match_prop(cur, DTD_ATTR_TYPE, 1834*7c478bd9Sstevel@tonic-gate tabptr->zone_attr_type); 1835*7c478bd9Sstevel@tonic-gate value_match = match_prop(cur, DTD_ATTR_VALUE, 1836*7c478bd9Sstevel@tonic-gate tabptr->zone_attr_value); 1837*7c478bd9Sstevel@tonic-gate 1838*7c478bd9Sstevel@tonic-gate if (name_match && type_match && value_match) { 1839*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 1840*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 1841*7c478bd9Sstevel@tonic-gate return (Z_OK); 1842*7c478bd9Sstevel@tonic-gate } 1843*7c478bd9Sstevel@tonic-gate } 1844*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 1845*7c478bd9Sstevel@tonic-gate } 1846*7c478bd9Sstevel@tonic-gate 1847*7c478bd9Sstevel@tonic-gate int 1848*7c478bd9Sstevel@tonic-gate zonecfg_delete_attr(zone_dochandle_t handle, struct zone_attrtab *tabptr) 1849*7c478bd9Sstevel@tonic-gate { 1850*7c478bd9Sstevel@tonic-gate int err; 1851*7c478bd9Sstevel@tonic-gate 1852*7c478bd9Sstevel@tonic-gate if (tabptr == NULL) 1853*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1854*7c478bd9Sstevel@tonic-gate 1855*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1856*7c478bd9Sstevel@tonic-gate return (err); 1857*7c478bd9Sstevel@tonic-gate 1858*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_attr_core(handle, tabptr)) != Z_OK) 1859*7c478bd9Sstevel@tonic-gate return (err); 1860*7c478bd9Sstevel@tonic-gate 1861*7c478bd9Sstevel@tonic-gate return (Z_OK); 1862*7c478bd9Sstevel@tonic-gate } 1863*7c478bd9Sstevel@tonic-gate 1864*7c478bd9Sstevel@tonic-gate int 1865*7c478bd9Sstevel@tonic-gate zonecfg_modify_attr( 1866*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 1867*7c478bd9Sstevel@tonic-gate struct zone_attrtab *oldtabptr, 1868*7c478bd9Sstevel@tonic-gate struct zone_attrtab *newtabptr) 1869*7c478bd9Sstevel@tonic-gate { 1870*7c478bd9Sstevel@tonic-gate int err; 1871*7c478bd9Sstevel@tonic-gate 1872*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || newtabptr == NULL) 1873*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1874*7c478bd9Sstevel@tonic-gate 1875*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1876*7c478bd9Sstevel@tonic-gate return (err); 1877*7c478bd9Sstevel@tonic-gate 1878*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_attr_core(handle, oldtabptr)) != Z_OK) 1879*7c478bd9Sstevel@tonic-gate return (err); 1880*7c478bd9Sstevel@tonic-gate 1881*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_attr_core(handle, newtabptr)) != Z_OK) 1882*7c478bd9Sstevel@tonic-gate return (err); 1883*7c478bd9Sstevel@tonic-gate 1884*7c478bd9Sstevel@tonic-gate return (Z_OK); 1885*7c478bd9Sstevel@tonic-gate } 1886*7c478bd9Sstevel@tonic-gate 1887*7c478bd9Sstevel@tonic-gate int 1888*7c478bd9Sstevel@tonic-gate zonecfg_get_attr_boolean(const struct zone_attrtab *attr, boolean_t *value) 1889*7c478bd9Sstevel@tonic-gate { 1890*7c478bd9Sstevel@tonic-gate if (attr == NULL) 1891*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1892*7c478bd9Sstevel@tonic-gate 1893*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_type, DTD_ENTITY_BOOLEAN) != 0) 1894*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1895*7c478bd9Sstevel@tonic-gate 1896*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_value, DTD_ENTITY_TRUE) == 0) { 1897*7c478bd9Sstevel@tonic-gate *value = B_TRUE; 1898*7c478bd9Sstevel@tonic-gate return (Z_OK); 1899*7c478bd9Sstevel@tonic-gate } 1900*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_value, DTD_ENTITY_FALSE) == 0) { 1901*7c478bd9Sstevel@tonic-gate *value = B_FALSE; 1902*7c478bd9Sstevel@tonic-gate return (Z_OK); 1903*7c478bd9Sstevel@tonic-gate } 1904*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1905*7c478bd9Sstevel@tonic-gate } 1906*7c478bd9Sstevel@tonic-gate 1907*7c478bd9Sstevel@tonic-gate int 1908*7c478bd9Sstevel@tonic-gate zonecfg_get_attr_int(const struct zone_attrtab *attr, int64_t *value) 1909*7c478bd9Sstevel@tonic-gate { 1910*7c478bd9Sstevel@tonic-gate long long result; 1911*7c478bd9Sstevel@tonic-gate char *endptr; 1912*7c478bd9Sstevel@tonic-gate 1913*7c478bd9Sstevel@tonic-gate if (attr == NULL) 1914*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1915*7c478bd9Sstevel@tonic-gate 1916*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_type, DTD_ENTITY_INT) != 0) 1917*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1918*7c478bd9Sstevel@tonic-gate 1919*7c478bd9Sstevel@tonic-gate errno = 0; 1920*7c478bd9Sstevel@tonic-gate result = strtoll(attr->zone_attr_value, &endptr, 10); 1921*7c478bd9Sstevel@tonic-gate if (errno != 0 || *endptr != '\0') 1922*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1923*7c478bd9Sstevel@tonic-gate *value = result; 1924*7c478bd9Sstevel@tonic-gate return (Z_OK); 1925*7c478bd9Sstevel@tonic-gate } 1926*7c478bd9Sstevel@tonic-gate 1927*7c478bd9Sstevel@tonic-gate int 1928*7c478bd9Sstevel@tonic-gate zonecfg_get_attr_string(const struct zone_attrtab *attr, char *value, 1929*7c478bd9Sstevel@tonic-gate size_t val_sz) 1930*7c478bd9Sstevel@tonic-gate { 1931*7c478bd9Sstevel@tonic-gate if (attr == NULL) 1932*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1933*7c478bd9Sstevel@tonic-gate 1934*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_type, DTD_ENTITY_STRING) != 0) 1935*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1936*7c478bd9Sstevel@tonic-gate 1937*7c478bd9Sstevel@tonic-gate if (strlcpy(value, attr->zone_attr_value, val_sz) >= val_sz) 1938*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 1939*7c478bd9Sstevel@tonic-gate return (Z_OK); 1940*7c478bd9Sstevel@tonic-gate } 1941*7c478bd9Sstevel@tonic-gate 1942*7c478bd9Sstevel@tonic-gate int 1943*7c478bd9Sstevel@tonic-gate zonecfg_get_attr_uint(const struct zone_attrtab *attr, uint64_t *value) 1944*7c478bd9Sstevel@tonic-gate { 1945*7c478bd9Sstevel@tonic-gate unsigned long long result; 1946*7c478bd9Sstevel@tonic-gate long long neg_result; 1947*7c478bd9Sstevel@tonic-gate char *endptr; 1948*7c478bd9Sstevel@tonic-gate 1949*7c478bd9Sstevel@tonic-gate if (attr == NULL) 1950*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1951*7c478bd9Sstevel@tonic-gate 1952*7c478bd9Sstevel@tonic-gate if (strcmp(attr->zone_attr_type, DTD_ENTITY_UINT) != 0) 1953*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1954*7c478bd9Sstevel@tonic-gate 1955*7c478bd9Sstevel@tonic-gate errno = 0; 1956*7c478bd9Sstevel@tonic-gate result = strtoull(attr->zone_attr_value, &endptr, 10); 1957*7c478bd9Sstevel@tonic-gate if (errno != 0 || *endptr != '\0') 1958*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1959*7c478bd9Sstevel@tonic-gate errno = 0; 1960*7c478bd9Sstevel@tonic-gate neg_result = strtoll(attr->zone_attr_value, &endptr, 10); 1961*7c478bd9Sstevel@tonic-gate /* 1962*7c478bd9Sstevel@tonic-gate * Incredibly, strtoull("<negative number>", ...) will not fail but 1963*7c478bd9Sstevel@tonic-gate * return whatever (negative) number cast as a u_longlong_t, so we 1964*7c478bd9Sstevel@tonic-gate * need to look for this here. 1965*7c478bd9Sstevel@tonic-gate */ 1966*7c478bd9Sstevel@tonic-gate if (errno == 0 && neg_result < 0) 1967*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1968*7c478bd9Sstevel@tonic-gate *value = result; 1969*7c478bd9Sstevel@tonic-gate return (Z_OK); 1970*7c478bd9Sstevel@tonic-gate } 1971*7c478bd9Sstevel@tonic-gate 1972*7c478bd9Sstevel@tonic-gate int 1973*7c478bd9Sstevel@tonic-gate zonecfg_lookup_rctl(zone_dochandle_t handle, struct zone_rctltab *tabptr) 1974*7c478bd9Sstevel@tonic-gate { 1975*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, val; 1976*7c478bd9Sstevel@tonic-gate char savedname[MAXNAMELEN]; 1977*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valptr; 1978*7c478bd9Sstevel@tonic-gate int err; 1979*7c478bd9Sstevel@tonic-gate 1980*7c478bd9Sstevel@tonic-gate if (tabptr->zone_rctl_name == NULL || 1981*7c478bd9Sstevel@tonic-gate strlen(tabptr->zone_rctl_name) == 0) 1982*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 1983*7c478bd9Sstevel@tonic-gate 1984*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 1985*7c478bd9Sstevel@tonic-gate return (err); 1986*7c478bd9Sstevel@tonic-gate 1987*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 1988*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 1989*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_RCTL)) 1990*7c478bd9Sstevel@tonic-gate continue; 1991*7c478bd9Sstevel@tonic-gate if ((fetchprop(cur, DTD_ATTR_NAME, savedname, 1992*7c478bd9Sstevel@tonic-gate sizeof (savedname)) == Z_OK) && 1993*7c478bd9Sstevel@tonic-gate (strcmp(savedname, tabptr->zone_rctl_name) == 0)) { 1994*7c478bd9Sstevel@tonic-gate tabptr->zone_rctl_valptr = NULL; 1995*7c478bd9Sstevel@tonic-gate for (val = cur->xmlChildrenNode; val != NULL; 1996*7c478bd9Sstevel@tonic-gate val = val->next) { 1997*7c478bd9Sstevel@tonic-gate valptr = (struct zone_rctlvaltab *)malloc( 1998*7c478bd9Sstevel@tonic-gate sizeof (struct zone_rctlvaltab)); 1999*7c478bd9Sstevel@tonic-gate if (valptr == NULL) 2000*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 2001*7c478bd9Sstevel@tonic-gate if ((fetchprop(val, DTD_ATTR_PRIV, 2002*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_priv, 2003*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_priv)) != 2004*7c478bd9Sstevel@tonic-gate Z_OK)) 2005*7c478bd9Sstevel@tonic-gate break; 2006*7c478bd9Sstevel@tonic-gate if ((fetchprop(val, DTD_ATTR_LIMIT, 2007*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_limit, 2008*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_limit)) != 2009*7c478bd9Sstevel@tonic-gate Z_OK)) 2010*7c478bd9Sstevel@tonic-gate break; 2011*7c478bd9Sstevel@tonic-gate if ((fetchprop(val, DTD_ATTR_ACTION, 2012*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_action, 2013*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_action)) != 2014*7c478bd9Sstevel@tonic-gate Z_OK)) 2015*7c478bd9Sstevel@tonic-gate break; 2016*7c478bd9Sstevel@tonic-gate if (zonecfg_add_rctl_value(tabptr, valptr) != 2017*7c478bd9Sstevel@tonic-gate Z_OK) 2018*7c478bd9Sstevel@tonic-gate break; 2019*7c478bd9Sstevel@tonic-gate } 2020*7c478bd9Sstevel@tonic-gate return (Z_OK); 2021*7c478bd9Sstevel@tonic-gate } 2022*7c478bd9Sstevel@tonic-gate } 2023*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 2024*7c478bd9Sstevel@tonic-gate } 2025*7c478bd9Sstevel@tonic-gate 2026*7c478bd9Sstevel@tonic-gate static int 2027*7c478bd9Sstevel@tonic-gate zonecfg_add_rctl_core(zone_dochandle_t handle, struct zone_rctltab *tabptr) 2028*7c478bd9Sstevel@tonic-gate { 2029*7c478bd9Sstevel@tonic-gate xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; 2030*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valptr; 2031*7c478bd9Sstevel@tonic-gate int err; 2032*7c478bd9Sstevel@tonic-gate 2033*7c478bd9Sstevel@tonic-gate newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_RCTL, NULL); 2034*7c478bd9Sstevel@tonic-gate err = newprop(handle, newnode, DTD_ATTR_NAME, tabptr->zone_rctl_name); 2035*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 2036*7c478bd9Sstevel@tonic-gate return (err); 2037*7c478bd9Sstevel@tonic-gate for (valptr = tabptr->zone_rctl_valptr; valptr != NULL; 2038*7c478bd9Sstevel@tonic-gate valptr = valptr->zone_rctlval_next) { 2039*7c478bd9Sstevel@tonic-gate valnode = xmlNewTextChild(newnode, NULL, 2040*7c478bd9Sstevel@tonic-gate DTD_ELEM_RCTLVALUE, NULL); 2041*7c478bd9Sstevel@tonic-gate err = newprop(handle, valnode, DTD_ATTR_PRIV, 2042*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_priv); 2043*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 2044*7c478bd9Sstevel@tonic-gate return (err); 2045*7c478bd9Sstevel@tonic-gate err = newprop(handle, valnode, DTD_ATTR_LIMIT, 2046*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_limit); 2047*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 2048*7c478bd9Sstevel@tonic-gate return (err); 2049*7c478bd9Sstevel@tonic-gate err = newprop(handle, valnode, DTD_ATTR_ACTION, 2050*7c478bd9Sstevel@tonic-gate valptr->zone_rctlval_action); 2051*7c478bd9Sstevel@tonic-gate if (err != Z_OK) 2052*7c478bd9Sstevel@tonic-gate return (err); 2053*7c478bd9Sstevel@tonic-gate } 2054*7c478bd9Sstevel@tonic-gate return (Z_OK); 2055*7c478bd9Sstevel@tonic-gate } 2056*7c478bd9Sstevel@tonic-gate 2057*7c478bd9Sstevel@tonic-gate int 2058*7c478bd9Sstevel@tonic-gate zonecfg_add_rctl(zone_dochandle_t handle, struct zone_rctltab *tabptr) 2059*7c478bd9Sstevel@tonic-gate { 2060*7c478bd9Sstevel@tonic-gate int err; 2061*7c478bd9Sstevel@tonic-gate 2062*7c478bd9Sstevel@tonic-gate if (tabptr == NULL || tabptr->zone_rctl_name == NULL) 2063*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2064*7c478bd9Sstevel@tonic-gate 2065*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 2066*7c478bd9Sstevel@tonic-gate return (err); 2067*7c478bd9Sstevel@tonic-gate 2068*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_rctl_core(handle, tabptr)) != Z_OK) 2069*7c478bd9Sstevel@tonic-gate return (err); 2070*7c478bd9Sstevel@tonic-gate 2071*7c478bd9Sstevel@tonic-gate return (Z_OK); 2072*7c478bd9Sstevel@tonic-gate } 2073*7c478bd9Sstevel@tonic-gate 2074*7c478bd9Sstevel@tonic-gate static int 2075*7c478bd9Sstevel@tonic-gate zonecfg_delete_rctl_core(zone_dochandle_t handle, struct zone_rctltab *tabptr) 2076*7c478bd9Sstevel@tonic-gate { 2077*7c478bd9Sstevel@tonic-gate xmlNodePtr cur = handle->zone_dh_cur; 2078*7c478bd9Sstevel@tonic-gate xmlChar *savedname; 2079*7c478bd9Sstevel@tonic-gate int name_result; 2080*7c478bd9Sstevel@tonic-gate 2081*7c478bd9Sstevel@tonic-gate for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { 2082*7c478bd9Sstevel@tonic-gate if (xmlStrcmp(cur->name, DTD_ELEM_RCTL)) 2083*7c478bd9Sstevel@tonic-gate continue; 2084*7c478bd9Sstevel@tonic-gate 2085*7c478bd9Sstevel@tonic-gate savedname = xmlGetProp(cur, DTD_ATTR_NAME); 2086*7c478bd9Sstevel@tonic-gate if (savedname == NULL) /* shouldn't happen */ 2087*7c478bd9Sstevel@tonic-gate continue; 2088*7c478bd9Sstevel@tonic-gate name_result = xmlStrcmp(savedname, 2089*7c478bd9Sstevel@tonic-gate (const xmlChar *) tabptr->zone_rctl_name); 2090*7c478bd9Sstevel@tonic-gate xmlFree(savedname); 2091*7c478bd9Sstevel@tonic-gate 2092*7c478bd9Sstevel@tonic-gate if (name_result == 0) { 2093*7c478bd9Sstevel@tonic-gate xmlUnlinkNode(cur); 2094*7c478bd9Sstevel@tonic-gate xmlFreeNode(cur); 2095*7c478bd9Sstevel@tonic-gate return (Z_OK); 2096*7c478bd9Sstevel@tonic-gate } 2097*7c478bd9Sstevel@tonic-gate } 2098*7c478bd9Sstevel@tonic-gate return (Z_NO_RESOURCE_ID); 2099*7c478bd9Sstevel@tonic-gate } 2100*7c478bd9Sstevel@tonic-gate 2101*7c478bd9Sstevel@tonic-gate int 2102*7c478bd9Sstevel@tonic-gate zonecfg_delete_rctl(zone_dochandle_t handle, struct zone_rctltab *tabptr) 2103*7c478bd9Sstevel@tonic-gate { 2104*7c478bd9Sstevel@tonic-gate int err; 2105*7c478bd9Sstevel@tonic-gate 2106*7c478bd9Sstevel@tonic-gate if (tabptr == NULL || tabptr->zone_rctl_name == NULL) 2107*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2108*7c478bd9Sstevel@tonic-gate 2109*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 2110*7c478bd9Sstevel@tonic-gate return (err); 2111*7c478bd9Sstevel@tonic-gate 2112*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_rctl_core(handle, tabptr)) != Z_OK) 2113*7c478bd9Sstevel@tonic-gate return (err); 2114*7c478bd9Sstevel@tonic-gate 2115*7c478bd9Sstevel@tonic-gate return (Z_OK); 2116*7c478bd9Sstevel@tonic-gate } 2117*7c478bd9Sstevel@tonic-gate 2118*7c478bd9Sstevel@tonic-gate int 2119*7c478bd9Sstevel@tonic-gate zonecfg_modify_rctl( 2120*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle, 2121*7c478bd9Sstevel@tonic-gate struct zone_rctltab *oldtabptr, 2122*7c478bd9Sstevel@tonic-gate struct zone_rctltab *newtabptr) 2123*7c478bd9Sstevel@tonic-gate { 2124*7c478bd9Sstevel@tonic-gate int err; 2125*7c478bd9Sstevel@tonic-gate 2126*7c478bd9Sstevel@tonic-gate if (oldtabptr == NULL || oldtabptr->zone_rctl_name == NULL || 2127*7c478bd9Sstevel@tonic-gate newtabptr == NULL || newtabptr->zone_rctl_name == NULL) 2128*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2129*7c478bd9Sstevel@tonic-gate 2130*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) 2131*7c478bd9Sstevel@tonic-gate return (err); 2132*7c478bd9Sstevel@tonic-gate 2133*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_delete_rctl_core(handle, oldtabptr)) != Z_OK) 2134*7c478bd9Sstevel@tonic-gate return (err); 2135*7c478bd9Sstevel@tonic-gate 2136*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_add_rctl_core(handle, newtabptr)) != Z_OK) 2137*7c478bd9Sstevel@tonic-gate return (err); 2138*7c478bd9Sstevel@tonic-gate 2139*7c478bd9Sstevel@tonic-gate return (Z_OK); 2140*7c478bd9Sstevel@tonic-gate } 2141*7c478bd9Sstevel@tonic-gate 2142*7c478bd9Sstevel@tonic-gate int 2143*7c478bd9Sstevel@tonic-gate zonecfg_add_rctl_value( 2144*7c478bd9Sstevel@tonic-gate struct zone_rctltab *tabptr, 2145*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valtabptr) 2146*7c478bd9Sstevel@tonic-gate { 2147*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *last, *old, *new; 2148*7c478bd9Sstevel@tonic-gate rctlblk_t *rctlblk = alloca(rctlblk_size()); 2149*7c478bd9Sstevel@tonic-gate 2150*7c478bd9Sstevel@tonic-gate last = tabptr->zone_rctl_valptr; 2151*7c478bd9Sstevel@tonic-gate for (old = last; old != NULL; old = old->zone_rctlval_next) 2152*7c478bd9Sstevel@tonic-gate last = old; /* walk to the end of the list */ 2153*7c478bd9Sstevel@tonic-gate new = valtabptr; /* alloc'd by caller */ 2154*7c478bd9Sstevel@tonic-gate new->zone_rctlval_next = NULL; 2155*7c478bd9Sstevel@tonic-gate if (zonecfg_construct_rctlblk(valtabptr, rctlblk) != Z_OK) 2156*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2157*7c478bd9Sstevel@tonic-gate if (!zonecfg_valid_rctlblk(rctlblk)) 2158*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2159*7c478bd9Sstevel@tonic-gate if (last == NULL) 2160*7c478bd9Sstevel@tonic-gate tabptr->zone_rctl_valptr = new; 2161*7c478bd9Sstevel@tonic-gate else 2162*7c478bd9Sstevel@tonic-gate last->zone_rctlval_next = new; 2163*7c478bd9Sstevel@tonic-gate return (Z_OK); 2164*7c478bd9Sstevel@tonic-gate } 2165*7c478bd9Sstevel@tonic-gate 2166*7c478bd9Sstevel@tonic-gate int 2167*7c478bd9Sstevel@tonic-gate zonecfg_remove_rctl_value( 2168*7c478bd9Sstevel@tonic-gate struct zone_rctltab *tabptr, 2169*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valtabptr) 2170*7c478bd9Sstevel@tonic-gate { 2171*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *last, *this, *next; 2172*7c478bd9Sstevel@tonic-gate 2173*7c478bd9Sstevel@tonic-gate last = tabptr->zone_rctl_valptr; 2174*7c478bd9Sstevel@tonic-gate for (this = last; this != NULL; this = this->zone_rctlval_next) { 2175*7c478bd9Sstevel@tonic-gate if (strcmp(this->zone_rctlval_priv, 2176*7c478bd9Sstevel@tonic-gate valtabptr->zone_rctlval_priv) == 0 && 2177*7c478bd9Sstevel@tonic-gate strcmp(this->zone_rctlval_limit, 2178*7c478bd9Sstevel@tonic-gate valtabptr->zone_rctlval_limit) == 0 && 2179*7c478bd9Sstevel@tonic-gate strcmp(this->zone_rctlval_action, 2180*7c478bd9Sstevel@tonic-gate valtabptr->zone_rctlval_action) == 0) { 2181*7c478bd9Sstevel@tonic-gate next = this->zone_rctlval_next; 2182*7c478bd9Sstevel@tonic-gate if (this == tabptr->zone_rctl_valptr) 2183*7c478bd9Sstevel@tonic-gate tabptr->zone_rctl_valptr = next; 2184*7c478bd9Sstevel@tonic-gate else 2185*7c478bd9Sstevel@tonic-gate last->zone_rctlval_next = next; 2186*7c478bd9Sstevel@tonic-gate free(this); 2187*7c478bd9Sstevel@tonic-gate return (Z_OK); 2188*7c478bd9Sstevel@tonic-gate } else 2189*7c478bd9Sstevel@tonic-gate last = this; 2190*7c478bd9Sstevel@tonic-gate } 2191*7c478bd9Sstevel@tonic-gate return (Z_NO_PROPERTY_ID); 2192*7c478bd9Sstevel@tonic-gate } 2193*7c478bd9Sstevel@tonic-gate 2194*7c478bd9Sstevel@tonic-gate char * 2195*7c478bd9Sstevel@tonic-gate zonecfg_strerror(int errnum) 2196*7c478bd9Sstevel@tonic-gate { 2197*7c478bd9Sstevel@tonic-gate switch (errnum) { 2198*7c478bd9Sstevel@tonic-gate case Z_OK: 2199*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "OK")); 2200*7c478bd9Sstevel@tonic-gate case Z_EMPTY_DOCUMENT: 2201*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Empty document")); 2202*7c478bd9Sstevel@tonic-gate case Z_WRONG_DOC_TYPE: 2203*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Wrong document type")); 2204*7c478bd9Sstevel@tonic-gate case Z_BAD_PROPERTY: 2205*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Bad document property")); 2206*7c478bd9Sstevel@tonic-gate case Z_TEMP_FILE: 2207*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, 2208*7c478bd9Sstevel@tonic-gate "Problem creating temporary file")); 2209*7c478bd9Sstevel@tonic-gate case Z_SAVING_FILE: 2210*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Problem saving file")); 2211*7c478bd9Sstevel@tonic-gate case Z_NO_ENTRY: 2212*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such entry")); 2213*7c478bd9Sstevel@tonic-gate case Z_BOGUS_ZONE_NAME: 2214*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Bogus zone name")); 2215*7c478bd9Sstevel@tonic-gate case Z_REQD_RESOURCE_MISSING: 2216*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Required resource missing")); 2217*7c478bd9Sstevel@tonic-gate case Z_REQD_PROPERTY_MISSING: 2218*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Required property missing")); 2219*7c478bd9Sstevel@tonic-gate case Z_BAD_HANDLE: 2220*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Bad handle")); 2221*7c478bd9Sstevel@tonic-gate case Z_NOMEM: 2222*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Out of memory")); 2223*7c478bd9Sstevel@tonic-gate case Z_INVAL: 2224*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Invalid argument")); 2225*7c478bd9Sstevel@tonic-gate case Z_ACCES: 2226*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Permission denied")); 2227*7c478bd9Sstevel@tonic-gate case Z_TOO_BIG: 2228*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Argument list too long")); 2229*7c478bd9Sstevel@tonic-gate case Z_MISC_FS: 2230*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, 2231*7c478bd9Sstevel@tonic-gate "Miscellaneous file system error")); 2232*7c478bd9Sstevel@tonic-gate case Z_NO_ZONE: 2233*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such zone configured")); 2234*7c478bd9Sstevel@tonic-gate case Z_NO_RESOURCE_TYPE: 2235*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such resource type")); 2236*7c478bd9Sstevel@tonic-gate case Z_NO_RESOURCE_ID: 2237*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such resource with that id")); 2238*7c478bd9Sstevel@tonic-gate case Z_NO_PROPERTY_TYPE: 2239*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such property type")); 2240*7c478bd9Sstevel@tonic-gate case Z_NO_PROPERTY_ID: 2241*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such property with that id")); 2242*7c478bd9Sstevel@tonic-gate case Z_RESOURCE_EXISTS: 2243*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, 2244*7c478bd9Sstevel@tonic-gate "Resource already exists with that id")); 2245*7c478bd9Sstevel@tonic-gate case Z_INVALID_DOCUMENT: 2246*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Invalid document")); 2247*7c478bd9Sstevel@tonic-gate case Z_ID_IN_USE: 2248*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Zone ID in use")); 2249*7c478bd9Sstevel@tonic-gate case Z_NO_SUCH_ID: 2250*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "No such zone ID")); 2251*7c478bd9Sstevel@tonic-gate case Z_UPDATING_INDEX: 2252*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Problem updating index file")); 2253*7c478bd9Sstevel@tonic-gate case Z_LOCKING_FILE: 2254*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Locking index file")); 2255*7c478bd9Sstevel@tonic-gate case Z_UNLOCKING_FILE: 2256*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Unlocking index file")); 2257*7c478bd9Sstevel@tonic-gate case Z_INSUFFICIENT_SPEC: 2258*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Insufficient specification")); 2259*7c478bd9Sstevel@tonic-gate case Z_RESOLVED_PATH: 2260*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Resolved path mismatch")); 2261*7c478bd9Sstevel@tonic-gate case Z_IPV6_ADDR_PREFIX_LEN: 2262*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, 2263*7c478bd9Sstevel@tonic-gate "IPv6 address missing required prefix length")); 2264*7c478bd9Sstevel@tonic-gate case Z_BOGUS_ADDRESS: 2265*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, 2266*7c478bd9Sstevel@tonic-gate "Neither an IPv4 nor an IPv6 address nor a host name")); 2267*7c478bd9Sstevel@tonic-gate default: 2268*7c478bd9Sstevel@tonic-gate return (dgettext(TEXT_DOMAIN, "Unknown error")); 2269*7c478bd9Sstevel@tonic-gate } 2270*7c478bd9Sstevel@tonic-gate } 2271*7c478bd9Sstevel@tonic-gate 2272*7c478bd9Sstevel@tonic-gate /* 2273*7c478bd9Sstevel@tonic-gate * Note that the zonecfg_setXent() and zonecfg_endXent() calls are all the 2274*7c478bd9Sstevel@tonic-gate * same, as they just turn around and call zonecfg_setent() / zonecfg_endent(). 2275*7c478bd9Sstevel@tonic-gate */ 2276*7c478bd9Sstevel@tonic-gate 2277*7c478bd9Sstevel@tonic-gate static int 2278*7c478bd9Sstevel@tonic-gate zonecfg_setent(zone_dochandle_t handle) 2279*7c478bd9Sstevel@tonic-gate { 2280*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 2281*7c478bd9Sstevel@tonic-gate int err; 2282*7c478bd9Sstevel@tonic-gate 2283*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2284*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2285*7c478bd9Sstevel@tonic-gate 2286*7c478bd9Sstevel@tonic-gate if ((err = operation_prep(handle)) != Z_OK) { 2287*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = NULL; 2288*7c478bd9Sstevel@tonic-gate return (err); 2289*7c478bd9Sstevel@tonic-gate } 2290*7c478bd9Sstevel@tonic-gate cur = handle->zone_dh_cur; 2291*7c478bd9Sstevel@tonic-gate cur = cur->xmlChildrenNode; 2292*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur; 2293*7c478bd9Sstevel@tonic-gate return (Z_OK); 2294*7c478bd9Sstevel@tonic-gate } 2295*7c478bd9Sstevel@tonic-gate 2296*7c478bd9Sstevel@tonic-gate static int 2297*7c478bd9Sstevel@tonic-gate zonecfg_endent(zone_dochandle_t handle) 2298*7c478bd9Sstevel@tonic-gate { 2299*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2300*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2301*7c478bd9Sstevel@tonic-gate 2302*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2303*7c478bd9Sstevel@tonic-gate return (Z_OK); 2304*7c478bd9Sstevel@tonic-gate } 2305*7c478bd9Sstevel@tonic-gate 2306*7c478bd9Sstevel@tonic-gate int 2307*7c478bd9Sstevel@tonic-gate zonecfg_setfsent(zone_dochandle_t handle) 2308*7c478bd9Sstevel@tonic-gate { 2309*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2310*7c478bd9Sstevel@tonic-gate } 2311*7c478bd9Sstevel@tonic-gate 2312*7c478bd9Sstevel@tonic-gate int 2313*7c478bd9Sstevel@tonic-gate zonecfg_getfsent(zone_dochandle_t handle, struct zone_fstab *tabptr) 2314*7c478bd9Sstevel@tonic-gate { 2315*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, options; 2316*7c478bd9Sstevel@tonic-gate char options_str[MAX_MNTOPT_STR]; 2317*7c478bd9Sstevel@tonic-gate int err; 2318*7c478bd9Sstevel@tonic-gate 2319*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2320*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2321*7c478bd9Sstevel@tonic-gate 2322*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2323*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2324*7c478bd9Sstevel@tonic-gate 2325*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2326*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_FS)) 2327*7c478bd9Sstevel@tonic-gate break; 2328*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2329*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2330*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2331*7c478bd9Sstevel@tonic-gate } 2332*7c478bd9Sstevel@tonic-gate 2333*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_SPECIAL, tabptr->zone_fs_special, 2334*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_special))) != Z_OK) { 2335*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2336*7c478bd9Sstevel@tonic-gate return (err); 2337*7c478bd9Sstevel@tonic-gate } 2338*7c478bd9Sstevel@tonic-gate 2339*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_RAW, tabptr->zone_fs_raw, 2340*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_raw))) != Z_OK) { 2341*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2342*7c478bd9Sstevel@tonic-gate return (err); 2343*7c478bd9Sstevel@tonic-gate } 2344*7c478bd9Sstevel@tonic-gate 2345*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir, 2346*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_dir))) != Z_OK) { 2347*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2348*7c478bd9Sstevel@tonic-gate return (err); 2349*7c478bd9Sstevel@tonic-gate } 2350*7c478bd9Sstevel@tonic-gate 2351*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_TYPE, tabptr->zone_fs_type, 2352*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_type))) != Z_OK) { 2353*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2354*7c478bd9Sstevel@tonic-gate return (err); 2355*7c478bd9Sstevel@tonic-gate } 2356*7c478bd9Sstevel@tonic-gate 2357*7c478bd9Sstevel@tonic-gate /* OK for options to be NULL */ 2358*7c478bd9Sstevel@tonic-gate tabptr->zone_fs_options = NULL; 2359*7c478bd9Sstevel@tonic-gate for (options = cur->xmlChildrenNode; options != NULL; 2360*7c478bd9Sstevel@tonic-gate options = options->next) { 2361*7c478bd9Sstevel@tonic-gate if (fetchprop(options, DTD_ATTR_NAME, options_str, 2362*7c478bd9Sstevel@tonic-gate sizeof (options_str)) != Z_OK) 2363*7c478bd9Sstevel@tonic-gate break; 2364*7c478bd9Sstevel@tonic-gate if (zonecfg_add_fs_option(tabptr, options_str) != Z_OK) 2365*7c478bd9Sstevel@tonic-gate break; 2366*7c478bd9Sstevel@tonic-gate } 2367*7c478bd9Sstevel@tonic-gate 2368*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2369*7c478bd9Sstevel@tonic-gate return (Z_OK); 2370*7c478bd9Sstevel@tonic-gate } 2371*7c478bd9Sstevel@tonic-gate 2372*7c478bd9Sstevel@tonic-gate int 2373*7c478bd9Sstevel@tonic-gate zonecfg_endfsent(zone_dochandle_t handle) 2374*7c478bd9Sstevel@tonic-gate { 2375*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2376*7c478bd9Sstevel@tonic-gate } 2377*7c478bd9Sstevel@tonic-gate 2378*7c478bd9Sstevel@tonic-gate int 2379*7c478bd9Sstevel@tonic-gate zonecfg_setipdent(zone_dochandle_t handle) 2380*7c478bd9Sstevel@tonic-gate { 2381*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2382*7c478bd9Sstevel@tonic-gate } 2383*7c478bd9Sstevel@tonic-gate 2384*7c478bd9Sstevel@tonic-gate int 2385*7c478bd9Sstevel@tonic-gate zonecfg_getipdent(zone_dochandle_t handle, struct zone_fstab *tabptr) 2386*7c478bd9Sstevel@tonic-gate { 2387*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 2388*7c478bd9Sstevel@tonic-gate int err; 2389*7c478bd9Sstevel@tonic-gate 2390*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2391*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2392*7c478bd9Sstevel@tonic-gate 2393*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2394*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2395*7c478bd9Sstevel@tonic-gate 2396*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2397*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_IPD)) 2398*7c478bd9Sstevel@tonic-gate break; 2399*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2400*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2401*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2402*7c478bd9Sstevel@tonic-gate } 2403*7c478bd9Sstevel@tonic-gate 2404*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_DIR, tabptr->zone_fs_dir, 2405*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_fs_dir))) != Z_OK) { 2406*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2407*7c478bd9Sstevel@tonic-gate return (err); 2408*7c478bd9Sstevel@tonic-gate } 2409*7c478bd9Sstevel@tonic-gate 2410*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2411*7c478bd9Sstevel@tonic-gate return (Z_OK); 2412*7c478bd9Sstevel@tonic-gate } 2413*7c478bd9Sstevel@tonic-gate 2414*7c478bd9Sstevel@tonic-gate int 2415*7c478bd9Sstevel@tonic-gate zonecfg_endipdent(zone_dochandle_t handle) 2416*7c478bd9Sstevel@tonic-gate { 2417*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2418*7c478bd9Sstevel@tonic-gate } 2419*7c478bd9Sstevel@tonic-gate 2420*7c478bd9Sstevel@tonic-gate int 2421*7c478bd9Sstevel@tonic-gate zonecfg_setnwifent(zone_dochandle_t handle) 2422*7c478bd9Sstevel@tonic-gate { 2423*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2424*7c478bd9Sstevel@tonic-gate } 2425*7c478bd9Sstevel@tonic-gate 2426*7c478bd9Sstevel@tonic-gate int 2427*7c478bd9Sstevel@tonic-gate zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) 2428*7c478bd9Sstevel@tonic-gate { 2429*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 2430*7c478bd9Sstevel@tonic-gate int err; 2431*7c478bd9Sstevel@tonic-gate 2432*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2433*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2434*7c478bd9Sstevel@tonic-gate 2435*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2436*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2437*7c478bd9Sstevel@tonic-gate 2438*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2439*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_NET)) 2440*7c478bd9Sstevel@tonic-gate break; 2441*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2442*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2443*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2444*7c478bd9Sstevel@tonic-gate } 2445*7c478bd9Sstevel@tonic-gate 2446*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_ADDRESS, tabptr->zone_nwif_address, 2447*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_nwif_address))) != Z_OK) { 2448*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2449*7c478bd9Sstevel@tonic-gate return (err); 2450*7c478bd9Sstevel@tonic-gate } 2451*7c478bd9Sstevel@tonic-gate 2452*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical, 2453*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_nwif_physical))) != Z_OK) { 2454*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2455*7c478bd9Sstevel@tonic-gate return (err); 2456*7c478bd9Sstevel@tonic-gate } 2457*7c478bd9Sstevel@tonic-gate 2458*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2459*7c478bd9Sstevel@tonic-gate return (Z_OK); 2460*7c478bd9Sstevel@tonic-gate } 2461*7c478bd9Sstevel@tonic-gate 2462*7c478bd9Sstevel@tonic-gate int 2463*7c478bd9Sstevel@tonic-gate zonecfg_endnwifent(zone_dochandle_t handle) 2464*7c478bd9Sstevel@tonic-gate { 2465*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2466*7c478bd9Sstevel@tonic-gate } 2467*7c478bd9Sstevel@tonic-gate 2468*7c478bd9Sstevel@tonic-gate int 2469*7c478bd9Sstevel@tonic-gate zonecfg_setdevent(zone_dochandle_t handle) 2470*7c478bd9Sstevel@tonic-gate { 2471*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2472*7c478bd9Sstevel@tonic-gate } 2473*7c478bd9Sstevel@tonic-gate 2474*7c478bd9Sstevel@tonic-gate int 2475*7c478bd9Sstevel@tonic-gate zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) 2476*7c478bd9Sstevel@tonic-gate { 2477*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 2478*7c478bd9Sstevel@tonic-gate int err; 2479*7c478bd9Sstevel@tonic-gate 2480*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2481*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2482*7c478bd9Sstevel@tonic-gate 2483*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2484*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2485*7c478bd9Sstevel@tonic-gate 2486*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2487*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_DEVICE)) 2488*7c478bd9Sstevel@tonic-gate break; 2489*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2490*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2491*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2492*7c478bd9Sstevel@tonic-gate } 2493*7c478bd9Sstevel@tonic-gate 2494*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, 2495*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_dev_match))) != Z_OK) { 2496*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2497*7c478bd9Sstevel@tonic-gate return (err); 2498*7c478bd9Sstevel@tonic-gate } 2499*7c478bd9Sstevel@tonic-gate 2500*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2501*7c478bd9Sstevel@tonic-gate return (Z_OK); 2502*7c478bd9Sstevel@tonic-gate } 2503*7c478bd9Sstevel@tonic-gate 2504*7c478bd9Sstevel@tonic-gate int 2505*7c478bd9Sstevel@tonic-gate zonecfg_enddevent(zone_dochandle_t handle) 2506*7c478bd9Sstevel@tonic-gate { 2507*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2508*7c478bd9Sstevel@tonic-gate } 2509*7c478bd9Sstevel@tonic-gate 2510*7c478bd9Sstevel@tonic-gate int 2511*7c478bd9Sstevel@tonic-gate zonecfg_setrctlent(zone_dochandle_t handle) 2512*7c478bd9Sstevel@tonic-gate { 2513*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2514*7c478bd9Sstevel@tonic-gate } 2515*7c478bd9Sstevel@tonic-gate 2516*7c478bd9Sstevel@tonic-gate int 2517*7c478bd9Sstevel@tonic-gate zonecfg_getrctlent(zone_dochandle_t handle, struct zone_rctltab *tabptr) 2518*7c478bd9Sstevel@tonic-gate { 2519*7c478bd9Sstevel@tonic-gate xmlNodePtr cur, val; 2520*7c478bd9Sstevel@tonic-gate struct zone_rctlvaltab *valptr; 2521*7c478bd9Sstevel@tonic-gate int err; 2522*7c478bd9Sstevel@tonic-gate 2523*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2524*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2525*7c478bd9Sstevel@tonic-gate 2526*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2527*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2528*7c478bd9Sstevel@tonic-gate 2529*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2530*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_RCTL)) 2531*7c478bd9Sstevel@tonic-gate break; 2532*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2533*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2534*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2535*7c478bd9Sstevel@tonic-gate } 2536*7c478bd9Sstevel@tonic-gate 2537*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_NAME, tabptr->zone_rctl_name, 2538*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_rctl_name))) != Z_OK) { 2539*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2540*7c478bd9Sstevel@tonic-gate return (err); 2541*7c478bd9Sstevel@tonic-gate } 2542*7c478bd9Sstevel@tonic-gate 2543*7c478bd9Sstevel@tonic-gate tabptr->zone_rctl_valptr = NULL; 2544*7c478bd9Sstevel@tonic-gate for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { 2545*7c478bd9Sstevel@tonic-gate valptr = (struct zone_rctlvaltab *)malloc( 2546*7c478bd9Sstevel@tonic-gate sizeof (struct zone_rctlvaltab)); 2547*7c478bd9Sstevel@tonic-gate if (valptr == NULL) 2548*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 2549*7c478bd9Sstevel@tonic-gate if (fetchprop(val, DTD_ATTR_PRIV, valptr->zone_rctlval_priv, 2550*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_priv)) != Z_OK) 2551*7c478bd9Sstevel@tonic-gate break; 2552*7c478bd9Sstevel@tonic-gate if (fetchprop(val, DTD_ATTR_LIMIT, valptr->zone_rctlval_limit, 2553*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_limit)) != Z_OK) 2554*7c478bd9Sstevel@tonic-gate break; 2555*7c478bd9Sstevel@tonic-gate if (fetchprop(val, DTD_ATTR_ACTION, valptr->zone_rctlval_action, 2556*7c478bd9Sstevel@tonic-gate sizeof (valptr->zone_rctlval_action)) != Z_OK) 2557*7c478bd9Sstevel@tonic-gate break; 2558*7c478bd9Sstevel@tonic-gate if (zonecfg_add_rctl_value(tabptr, valptr) != Z_OK) 2559*7c478bd9Sstevel@tonic-gate break; 2560*7c478bd9Sstevel@tonic-gate } 2561*7c478bd9Sstevel@tonic-gate 2562*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2563*7c478bd9Sstevel@tonic-gate return (Z_OK); 2564*7c478bd9Sstevel@tonic-gate } 2565*7c478bd9Sstevel@tonic-gate 2566*7c478bd9Sstevel@tonic-gate int 2567*7c478bd9Sstevel@tonic-gate zonecfg_endrctlent(zone_dochandle_t handle) 2568*7c478bd9Sstevel@tonic-gate { 2569*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2570*7c478bd9Sstevel@tonic-gate } 2571*7c478bd9Sstevel@tonic-gate 2572*7c478bd9Sstevel@tonic-gate int 2573*7c478bd9Sstevel@tonic-gate zonecfg_setattrent(zone_dochandle_t handle) 2574*7c478bd9Sstevel@tonic-gate { 2575*7c478bd9Sstevel@tonic-gate return (zonecfg_setent(handle)); 2576*7c478bd9Sstevel@tonic-gate } 2577*7c478bd9Sstevel@tonic-gate 2578*7c478bd9Sstevel@tonic-gate int 2579*7c478bd9Sstevel@tonic-gate zonecfg_getattrent(zone_dochandle_t handle, struct zone_attrtab *tabptr) 2580*7c478bd9Sstevel@tonic-gate { 2581*7c478bd9Sstevel@tonic-gate xmlNodePtr cur; 2582*7c478bd9Sstevel@tonic-gate int err; 2583*7c478bd9Sstevel@tonic-gate 2584*7c478bd9Sstevel@tonic-gate if (handle == NULL) 2585*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2586*7c478bd9Sstevel@tonic-gate 2587*7c478bd9Sstevel@tonic-gate if ((cur = handle->zone_dh_cur) == NULL) 2588*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2589*7c478bd9Sstevel@tonic-gate 2590*7c478bd9Sstevel@tonic-gate for (; cur != NULL; cur = cur->next) 2591*7c478bd9Sstevel@tonic-gate if (!xmlStrcmp(cur->name, DTD_ELEM_ATTR)) 2592*7c478bd9Sstevel@tonic-gate break; 2593*7c478bd9Sstevel@tonic-gate if (cur == NULL) { 2594*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2595*7c478bd9Sstevel@tonic-gate return (Z_NO_ENTRY); 2596*7c478bd9Sstevel@tonic-gate } 2597*7c478bd9Sstevel@tonic-gate 2598*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_NAME, tabptr->zone_attr_name, 2599*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_name))) != Z_OK) { 2600*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2601*7c478bd9Sstevel@tonic-gate return (err); 2602*7c478bd9Sstevel@tonic-gate } 2603*7c478bd9Sstevel@tonic-gate 2604*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_TYPE, tabptr->zone_attr_type, 2605*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_type))) != Z_OK) { 2606*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2607*7c478bd9Sstevel@tonic-gate return (err); 2608*7c478bd9Sstevel@tonic-gate } 2609*7c478bd9Sstevel@tonic-gate 2610*7c478bd9Sstevel@tonic-gate if ((err = fetchprop(cur, DTD_ATTR_VALUE, tabptr->zone_attr_value, 2611*7c478bd9Sstevel@tonic-gate sizeof (tabptr->zone_attr_value))) != Z_OK) { 2612*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = handle->zone_dh_top; 2613*7c478bd9Sstevel@tonic-gate return (err); 2614*7c478bd9Sstevel@tonic-gate } 2615*7c478bd9Sstevel@tonic-gate 2616*7c478bd9Sstevel@tonic-gate handle->zone_dh_cur = cur->next; 2617*7c478bd9Sstevel@tonic-gate return (Z_OK); 2618*7c478bd9Sstevel@tonic-gate } 2619*7c478bd9Sstevel@tonic-gate 2620*7c478bd9Sstevel@tonic-gate int 2621*7c478bd9Sstevel@tonic-gate zonecfg_endattrent(zone_dochandle_t handle) 2622*7c478bd9Sstevel@tonic-gate { 2623*7c478bd9Sstevel@tonic-gate return (zonecfg_endent(handle)); 2624*7c478bd9Sstevel@tonic-gate } 2625*7c478bd9Sstevel@tonic-gate 2626*7c478bd9Sstevel@tonic-gate /* This will ultimately be configurable. */ 2627*7c478bd9Sstevel@tonic-gate static const char *priv_list[] = { 2628*7c478bd9Sstevel@tonic-gate PRIV_FILE_CHOWN, 2629*7c478bd9Sstevel@tonic-gate PRIV_FILE_CHOWN_SELF, 2630*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_EXECUTE, 2631*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_READ, 2632*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_SEARCH, 2633*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_WRITE, 2634*7c478bd9Sstevel@tonic-gate PRIV_FILE_OWNER, 2635*7c478bd9Sstevel@tonic-gate PRIV_FILE_SETID, 2636*7c478bd9Sstevel@tonic-gate PRIV_IPC_DAC_READ, 2637*7c478bd9Sstevel@tonic-gate PRIV_IPC_DAC_WRITE, 2638*7c478bd9Sstevel@tonic-gate PRIV_IPC_OWNER, 2639*7c478bd9Sstevel@tonic-gate PRIV_NET_ICMPACCESS, 2640*7c478bd9Sstevel@tonic-gate PRIV_NET_PRIVADDR, 2641*7c478bd9Sstevel@tonic-gate PRIV_PROC_CHROOT, 2642*7c478bd9Sstevel@tonic-gate PRIV_SYS_AUDIT, 2643*7c478bd9Sstevel@tonic-gate PRIV_PROC_AUDIT, 2644*7c478bd9Sstevel@tonic-gate PRIV_PROC_OWNER, 2645*7c478bd9Sstevel@tonic-gate PRIV_PROC_SETID, 2646*7c478bd9Sstevel@tonic-gate PRIV_PROC_TASKID, 2647*7c478bd9Sstevel@tonic-gate PRIV_SYS_ACCT, 2648*7c478bd9Sstevel@tonic-gate PRIV_SYS_ADMIN, 2649*7c478bd9Sstevel@tonic-gate PRIV_SYS_MOUNT, 2650*7c478bd9Sstevel@tonic-gate PRIV_SYS_NFS, 2651*7c478bd9Sstevel@tonic-gate PRIV_SYS_RESOURCE, 2652*7c478bd9Sstevel@tonic-gate PRIV_CONTRACT_EVENT, 2653*7c478bd9Sstevel@tonic-gate PRIV_CONTRACT_OBSERVER, 2654*7c478bd9Sstevel@tonic-gate NULL 2655*7c478bd9Sstevel@tonic-gate }; 2656*7c478bd9Sstevel@tonic-gate 2657*7c478bd9Sstevel@tonic-gate int 2658*7c478bd9Sstevel@tonic-gate zonecfg_get_privset(priv_set_t *privs) 2659*7c478bd9Sstevel@tonic-gate { 2660*7c478bd9Sstevel@tonic-gate const char **strp; 2661*7c478bd9Sstevel@tonic-gate priv_set_t *basic = priv_str_to_set("basic", ",", NULL); 2662*7c478bd9Sstevel@tonic-gate 2663*7c478bd9Sstevel@tonic-gate if (basic == NULL) 2664*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2665*7c478bd9Sstevel@tonic-gate 2666*7c478bd9Sstevel@tonic-gate priv_union(basic, privs); 2667*7c478bd9Sstevel@tonic-gate priv_freeset(basic); 2668*7c478bd9Sstevel@tonic-gate 2669*7c478bd9Sstevel@tonic-gate for (strp = priv_list; *strp != NULL; strp++) { 2670*7c478bd9Sstevel@tonic-gate if (priv_addset(privs, *strp) != 0) { 2671*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2672*7c478bd9Sstevel@tonic-gate } 2673*7c478bd9Sstevel@tonic-gate } 2674*7c478bd9Sstevel@tonic-gate return (Z_OK); 2675*7c478bd9Sstevel@tonic-gate } 2676*7c478bd9Sstevel@tonic-gate 2677*7c478bd9Sstevel@tonic-gate int 2678*7c478bd9Sstevel@tonic-gate zonecfg_add_index(char *zone, char *path) 2679*7c478bd9Sstevel@tonic-gate { 2680*7c478bd9Sstevel@tonic-gate struct zoneent ze; 2681*7c478bd9Sstevel@tonic-gate 2682*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name)); 2683*7c478bd9Sstevel@tonic-gate ze.zone_state = ZONE_STATE_CONFIGURED; 2684*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_path, path, sizeof (ze.zone_path)); 2685*7c478bd9Sstevel@tonic-gate return (putzoneent(&ze, PZE_ADD)); 2686*7c478bd9Sstevel@tonic-gate } 2687*7c478bd9Sstevel@tonic-gate 2688*7c478bd9Sstevel@tonic-gate int 2689*7c478bd9Sstevel@tonic-gate zonecfg_delete_index(char *zone) 2690*7c478bd9Sstevel@tonic-gate { 2691*7c478bd9Sstevel@tonic-gate struct zoneent ze; 2692*7c478bd9Sstevel@tonic-gate 2693*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name)); 2694*7c478bd9Sstevel@tonic-gate return (putzoneent(&ze, PZE_REMOVE)); 2695*7c478bd9Sstevel@tonic-gate } 2696*7c478bd9Sstevel@tonic-gate 2697*7c478bd9Sstevel@tonic-gate int 2698*7c478bd9Sstevel@tonic-gate zone_get_zonepath(char *zone_name, char *zonepath, size_t rp_sz) 2699*7c478bd9Sstevel@tonic-gate { 2700*7c478bd9Sstevel@tonic-gate zone_dochandle_t handle; 2701*7c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE; 2702*7c478bd9Sstevel@tonic-gate struct zoneent *ze; 2703*7c478bd9Sstevel@tonic-gate FILE *cookie; 2704*7c478bd9Sstevel@tonic-gate int err; 2705*7c478bd9Sstevel@tonic-gate 2706*7c478bd9Sstevel@tonic-gate if (zone_name == NULL) 2707*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2708*7c478bd9Sstevel@tonic-gate 2709*7c478bd9Sstevel@tonic-gate if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) { 2710*7c478bd9Sstevel@tonic-gate (void) strlcpy(zonepath, "/", rp_sz); 2711*7c478bd9Sstevel@tonic-gate return (Z_OK); 2712*7c478bd9Sstevel@tonic-gate } 2713*7c478bd9Sstevel@tonic-gate 2714*7c478bd9Sstevel@tonic-gate /* 2715*7c478bd9Sstevel@tonic-gate * First check the index file. Because older versions did not have 2716*7c478bd9Sstevel@tonic-gate * a copy of the zone path, allow for it to be zero length, in which 2717*7c478bd9Sstevel@tonic-gate * case we ignore this result and fall back to the XML files. 2718*7c478bd9Sstevel@tonic-gate */ 2719*7c478bd9Sstevel@tonic-gate (void) strlcpy(zonepath, "", rp_sz); 2720*7c478bd9Sstevel@tonic-gate cookie = setzoneent(); 2721*7c478bd9Sstevel@tonic-gate while ((ze = getzoneent_private(cookie)) != NULL) { 2722*7c478bd9Sstevel@tonic-gate if (strcmp(ze->zone_name, zone_name) == 0) { 2723*7c478bd9Sstevel@tonic-gate found = B_TRUE; 2724*7c478bd9Sstevel@tonic-gate if (strlen(ze->zone_path) > 0) 2725*7c478bd9Sstevel@tonic-gate (void) strlcpy(zonepath, ze->zone_path, rp_sz); 2726*7c478bd9Sstevel@tonic-gate } 2727*7c478bd9Sstevel@tonic-gate free(ze); 2728*7c478bd9Sstevel@tonic-gate if (found) 2729*7c478bd9Sstevel@tonic-gate break; 2730*7c478bd9Sstevel@tonic-gate } 2731*7c478bd9Sstevel@tonic-gate endzoneent(cookie); 2732*7c478bd9Sstevel@tonic-gate if (found && strlen(zonepath) > 0) 2733*7c478bd9Sstevel@tonic-gate return (Z_OK); 2734*7c478bd9Sstevel@tonic-gate 2735*7c478bd9Sstevel@tonic-gate /* Fall back to the XML files. */ 2736*7c478bd9Sstevel@tonic-gate if ((handle = zonecfg_init_handle()) == NULL) 2737*7c478bd9Sstevel@tonic-gate return (Z_NOMEM); 2738*7c478bd9Sstevel@tonic-gate 2739*7c478bd9Sstevel@tonic-gate /* 2740*7c478bd9Sstevel@tonic-gate * Check the snapshot first: if a zone is running, its zonepath 2741*7c478bd9Sstevel@tonic-gate * may have changed. 2742*7c478bd9Sstevel@tonic-gate */ 2743*7c478bd9Sstevel@tonic-gate if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 2744*7c478bd9Sstevel@tonic-gate if ((err = zonecfg_get_handle(zone_name, handle)) != Z_OK) 2745*7c478bd9Sstevel@tonic-gate return (err); 2746*7c478bd9Sstevel@tonic-gate } 2747*7c478bd9Sstevel@tonic-gate err = zonecfg_get_zonepath(handle, zonepath, rp_sz); 2748*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(handle); 2749*7c478bd9Sstevel@tonic-gate return (err); 2750*7c478bd9Sstevel@tonic-gate } 2751*7c478bd9Sstevel@tonic-gate 2752*7c478bd9Sstevel@tonic-gate int 2753*7c478bd9Sstevel@tonic-gate zone_get_rootpath(char *zone_name, char *rootpath, size_t rp_sz) 2754*7c478bd9Sstevel@tonic-gate { 2755*7c478bd9Sstevel@tonic-gate int err; 2756*7c478bd9Sstevel@tonic-gate 2757*7c478bd9Sstevel@tonic-gate /* This function makes sense for non-global zones only. */ 2758*7c478bd9Sstevel@tonic-gate if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) 2759*7c478bd9Sstevel@tonic-gate return (Z_BOGUS_ZONE_NAME); 2760*7c478bd9Sstevel@tonic-gate if ((err = zone_get_zonepath(zone_name, rootpath, rp_sz)) != Z_OK) 2761*7c478bd9Sstevel@tonic-gate return (err); 2762*7c478bd9Sstevel@tonic-gate if (strlcat(rootpath, "/root", rp_sz) >= rp_sz) 2763*7c478bd9Sstevel@tonic-gate return (Z_TOO_BIG); 2764*7c478bd9Sstevel@tonic-gate return (Z_OK); 2765*7c478bd9Sstevel@tonic-gate } 2766*7c478bd9Sstevel@tonic-gate 2767*7c478bd9Sstevel@tonic-gate static zone_state_t 2768*7c478bd9Sstevel@tonic-gate kernel_state_to_user_state(zone_status_t kernel_state) 2769*7c478bd9Sstevel@tonic-gate { 2770*7c478bd9Sstevel@tonic-gate assert(kernel_state <= ZONE_MAX_STATE); 2771*7c478bd9Sstevel@tonic-gate switch (kernel_state) { 2772*7c478bd9Sstevel@tonic-gate case ZONE_IS_UNINITIALIZED: 2773*7c478bd9Sstevel@tonic-gate case ZONE_IS_READY: 2774*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_READY); 2775*7c478bd9Sstevel@tonic-gate case ZONE_IS_BOOTING: 2776*7c478bd9Sstevel@tonic-gate case ZONE_IS_RUNNING: 2777*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_RUNNING); 2778*7c478bd9Sstevel@tonic-gate case ZONE_IS_SHUTTING_DOWN: 2779*7c478bd9Sstevel@tonic-gate case ZONE_IS_EMPTY: 2780*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_SHUTTING_DOWN); 2781*7c478bd9Sstevel@tonic-gate case ZONE_IS_DOWN: 2782*7c478bd9Sstevel@tonic-gate case ZONE_IS_DYING: 2783*7c478bd9Sstevel@tonic-gate case ZONE_IS_DEAD: 2784*7c478bd9Sstevel@tonic-gate default: 2785*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_DOWN); 2786*7c478bd9Sstevel@tonic-gate } 2787*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2788*7c478bd9Sstevel@tonic-gate } 2789*7c478bd9Sstevel@tonic-gate 2790*7c478bd9Sstevel@tonic-gate int 2791*7c478bd9Sstevel@tonic-gate zone_get_state(char *zone_name, zone_state_t *state_num) 2792*7c478bd9Sstevel@tonic-gate { 2793*7c478bd9Sstevel@tonic-gate zone_status_t status; 2794*7c478bd9Sstevel@tonic-gate zoneid_t zone_id; 2795*7c478bd9Sstevel@tonic-gate struct zoneent *ze; 2796*7c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE; 2797*7c478bd9Sstevel@tonic-gate FILE *cookie; 2798*7c478bd9Sstevel@tonic-gate 2799*7c478bd9Sstevel@tonic-gate if (zone_name == NULL) 2800*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2801*7c478bd9Sstevel@tonic-gate 2802*7c478bd9Sstevel@tonic-gate /* check to see if zone is running */ 2803*7c478bd9Sstevel@tonic-gate if ((zone_id = getzoneidbyname(zone_name)) != -1 && 2804*7c478bd9Sstevel@tonic-gate zone_getattr(zone_id, ZONE_ATTR_STATUS, &status, 2805*7c478bd9Sstevel@tonic-gate sizeof (status)) >= 0) { 2806*7c478bd9Sstevel@tonic-gate *state_num = kernel_state_to_user_state(status); 2807*7c478bd9Sstevel@tonic-gate return (Z_OK); 2808*7c478bd9Sstevel@tonic-gate } 2809*7c478bd9Sstevel@tonic-gate 2810*7c478bd9Sstevel@tonic-gate cookie = setzoneent(); 2811*7c478bd9Sstevel@tonic-gate while ((ze = getzoneent_private(cookie)) != NULL) { 2812*7c478bd9Sstevel@tonic-gate if (strcmp(ze->zone_name, zone_name) == 0) { 2813*7c478bd9Sstevel@tonic-gate found = B_TRUE; 2814*7c478bd9Sstevel@tonic-gate *state_num = ze->zone_state; 2815*7c478bd9Sstevel@tonic-gate } 2816*7c478bd9Sstevel@tonic-gate free(ze); 2817*7c478bd9Sstevel@tonic-gate if (found) 2818*7c478bd9Sstevel@tonic-gate break; 2819*7c478bd9Sstevel@tonic-gate } 2820*7c478bd9Sstevel@tonic-gate endzoneent(cookie); 2821*7c478bd9Sstevel@tonic-gate return ((found) ? Z_OK : Z_NO_ZONE); 2822*7c478bd9Sstevel@tonic-gate } 2823*7c478bd9Sstevel@tonic-gate 2824*7c478bd9Sstevel@tonic-gate int 2825*7c478bd9Sstevel@tonic-gate zone_set_state(char *zone, zone_state_t state) 2826*7c478bd9Sstevel@tonic-gate { 2827*7c478bd9Sstevel@tonic-gate struct zoneent ze; 2828*7c478bd9Sstevel@tonic-gate 2829*7c478bd9Sstevel@tonic-gate if (state != ZONE_STATE_CONFIGURED && state != ZONE_STATE_INSTALLED && 2830*7c478bd9Sstevel@tonic-gate state != ZONE_STATE_INCOMPLETE) 2831*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2832*7c478bd9Sstevel@tonic-gate 2833*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name)); 2834*7c478bd9Sstevel@tonic-gate ze.zone_state = state; 2835*7c478bd9Sstevel@tonic-gate (void) strlcpy(ze.zone_path, "", sizeof (ze.zone_path)); 2836*7c478bd9Sstevel@tonic-gate return (putzoneent(&ze, PZE_MODIFY)); 2837*7c478bd9Sstevel@tonic-gate } 2838*7c478bd9Sstevel@tonic-gate 2839*7c478bd9Sstevel@tonic-gate /* 2840*7c478bd9Sstevel@tonic-gate * Get id (if any) for specified zone. There are four possible outcomes: 2841*7c478bd9Sstevel@tonic-gate * - If the string corresponds to the numeric id of an active (booted) 2842*7c478bd9Sstevel@tonic-gate * zone, sets *zip to the zone id and returns 0. 2843*7c478bd9Sstevel@tonic-gate * - If the string corresponds to the name of an active (booted) zone, 2844*7c478bd9Sstevel@tonic-gate * sets *zip to the zone id and returns 0. 2845*7c478bd9Sstevel@tonic-gate * - If the string is a name in the configuration but is not booted, 2846*7c478bd9Sstevel@tonic-gate * sets *zip to ZONE_ID_UNDEFINED and returns 0. 2847*7c478bd9Sstevel@tonic-gate * - Otherwise, leaves *zip unchanged and returns -1. 2848*7c478bd9Sstevel@tonic-gate * 2849*7c478bd9Sstevel@tonic-gate * This function acts as an auxiliary filter on the function of the same 2850*7c478bd9Sstevel@tonic-gate * name in libc; the linker binds to this version if libzonecfg exists, 2851*7c478bd9Sstevel@tonic-gate * and the libc version if it doesn't. Any changes to this version of 2852*7c478bd9Sstevel@tonic-gate * the function should probably be reflected in the libc version as well. 2853*7c478bd9Sstevel@tonic-gate */ 2854*7c478bd9Sstevel@tonic-gate int 2855*7c478bd9Sstevel@tonic-gate zone_get_id(const char *str, zoneid_t *zip) 2856*7c478bd9Sstevel@tonic-gate { 2857*7c478bd9Sstevel@tonic-gate zone_dochandle_t hdl; 2858*7c478bd9Sstevel@tonic-gate zoneid_t zoneid; 2859*7c478bd9Sstevel@tonic-gate char *cp; 2860*7c478bd9Sstevel@tonic-gate int err; 2861*7c478bd9Sstevel@tonic-gate 2862*7c478bd9Sstevel@tonic-gate /* first try looking for active zone by id */ 2863*7c478bd9Sstevel@tonic-gate errno = 0; 2864*7c478bd9Sstevel@tonic-gate zoneid = (zoneid_t)strtol(str, &cp, 0); 2865*7c478bd9Sstevel@tonic-gate if (errno == 0 && cp != str && *cp == '\0' && 2866*7c478bd9Sstevel@tonic-gate getzonenamebyid(zoneid, NULL, 0) != -1) { 2867*7c478bd9Sstevel@tonic-gate *zip = zoneid; 2868*7c478bd9Sstevel@tonic-gate return (0); 2869*7c478bd9Sstevel@tonic-gate } 2870*7c478bd9Sstevel@tonic-gate 2871*7c478bd9Sstevel@tonic-gate /* then look for active zone by name */ 2872*7c478bd9Sstevel@tonic-gate if ((zoneid = getzoneidbyname(str)) != -1) { 2873*7c478bd9Sstevel@tonic-gate *zip = zoneid; 2874*7c478bd9Sstevel@tonic-gate return (0); 2875*7c478bd9Sstevel@tonic-gate } 2876*7c478bd9Sstevel@tonic-gate 2877*7c478bd9Sstevel@tonic-gate /* if in global zone, try looking up name in configuration database */ 2878*7c478bd9Sstevel@tonic-gate if (getzoneid() != GLOBAL_ZONEID || 2879*7c478bd9Sstevel@tonic-gate (hdl = zonecfg_init_handle()) == NULL) 2880*7c478bd9Sstevel@tonic-gate return (-1); 2881*7c478bd9Sstevel@tonic-gate 2882*7c478bd9Sstevel@tonic-gate if (zonecfg_get_handle((char *)str, hdl) == Z_OK) { 2883*7c478bd9Sstevel@tonic-gate /* zone exists but isn't active */ 2884*7c478bd9Sstevel@tonic-gate *zip = ZONE_ID_UNDEFINED; 2885*7c478bd9Sstevel@tonic-gate err = 0; 2886*7c478bd9Sstevel@tonic-gate } else { 2887*7c478bd9Sstevel@tonic-gate err = -1; 2888*7c478bd9Sstevel@tonic-gate } 2889*7c478bd9Sstevel@tonic-gate 2890*7c478bd9Sstevel@tonic-gate zonecfg_fini_handle(hdl); 2891*7c478bd9Sstevel@tonic-gate return (err); 2892*7c478bd9Sstevel@tonic-gate } 2893*7c478bd9Sstevel@tonic-gate 2894*7c478bd9Sstevel@tonic-gate char * 2895*7c478bd9Sstevel@tonic-gate zone_state_str(zone_state_t state_num) 2896*7c478bd9Sstevel@tonic-gate { 2897*7c478bd9Sstevel@tonic-gate switch (state_num) { 2898*7c478bd9Sstevel@tonic-gate case ZONE_STATE_CONFIGURED: 2899*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_CONFIGURED); 2900*7c478bd9Sstevel@tonic-gate case ZONE_STATE_INCOMPLETE: 2901*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_INCOMPLETE); 2902*7c478bd9Sstevel@tonic-gate case ZONE_STATE_INSTALLED: 2903*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_INSTALLED); 2904*7c478bd9Sstevel@tonic-gate case ZONE_STATE_READY: 2905*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_READY); 2906*7c478bd9Sstevel@tonic-gate case ZONE_STATE_RUNNING: 2907*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_RUNNING); 2908*7c478bd9Sstevel@tonic-gate case ZONE_STATE_SHUTTING_DOWN: 2909*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_SHUTTING_DOWN); 2910*7c478bd9Sstevel@tonic-gate case ZONE_STATE_DOWN: 2911*7c478bd9Sstevel@tonic-gate return (ZONE_STATE_STR_DOWN); 2912*7c478bd9Sstevel@tonic-gate default: 2913*7c478bd9Sstevel@tonic-gate return ("unknown"); 2914*7c478bd9Sstevel@tonic-gate } 2915*7c478bd9Sstevel@tonic-gate } 2916*7c478bd9Sstevel@tonic-gate 2917*7c478bd9Sstevel@tonic-gate /* 2918*7c478bd9Sstevel@tonic-gate * File-system convenience functions. 2919*7c478bd9Sstevel@tonic-gate */ 2920*7c478bd9Sstevel@tonic-gate boolean_t 2921*7c478bd9Sstevel@tonic-gate zonecfg_valid_fs_type(const char *type) 2922*7c478bd9Sstevel@tonic-gate { 2923*7c478bd9Sstevel@tonic-gate /* 2924*7c478bd9Sstevel@tonic-gate * We already know which FS types don't work. 2925*7c478bd9Sstevel@tonic-gate */ 2926*7c478bd9Sstevel@tonic-gate if (strcmp(type, "proc") == 0 || 2927*7c478bd9Sstevel@tonic-gate strcmp(type, "mntfs") == 0 || 2928*7c478bd9Sstevel@tonic-gate strcmp(type, "autofs") == 0 || 2929*7c478bd9Sstevel@tonic-gate strncmp(type, "nfs", sizeof ("nfs") - 1) == 0 || 2930*7c478bd9Sstevel@tonic-gate strcmp(type, "cachefs") == 0) 2931*7c478bd9Sstevel@tonic-gate return (B_FALSE); 2932*7c478bd9Sstevel@tonic-gate /* 2933*7c478bd9Sstevel@tonic-gate * The caller may do more detailed verification to make sure other 2934*7c478bd9Sstevel@tonic-gate * aspects of this filesystem type make sense. 2935*7c478bd9Sstevel@tonic-gate */ 2936*7c478bd9Sstevel@tonic-gate return (B_TRUE); 2937*7c478bd9Sstevel@tonic-gate } 2938*7c478bd9Sstevel@tonic-gate 2939*7c478bd9Sstevel@tonic-gate /* 2940*7c478bd9Sstevel@tonic-gate * Generally uninteresting rctl convenience functions. 2941*7c478bd9Sstevel@tonic-gate */ 2942*7c478bd9Sstevel@tonic-gate 2943*7c478bd9Sstevel@tonic-gate int 2944*7c478bd9Sstevel@tonic-gate zonecfg_construct_rctlblk(const struct zone_rctlvaltab *rctlval, 2945*7c478bd9Sstevel@tonic-gate rctlblk_t *rctlblk) 2946*7c478bd9Sstevel@tonic-gate { 2947*7c478bd9Sstevel@tonic-gate unsigned long long ull; 2948*7c478bd9Sstevel@tonic-gate char *endp; 2949*7c478bd9Sstevel@tonic-gate rctl_priv_t priv; 2950*7c478bd9Sstevel@tonic-gate rctl_qty_t limit; 2951*7c478bd9Sstevel@tonic-gate uint_t action; 2952*7c478bd9Sstevel@tonic-gate 2953*7c478bd9Sstevel@tonic-gate /* Get the privilege */ 2954*7c478bd9Sstevel@tonic-gate if (strcmp(rctlval->zone_rctlval_priv, "basic") == 0) { 2955*7c478bd9Sstevel@tonic-gate priv = RCPRIV_BASIC; 2956*7c478bd9Sstevel@tonic-gate } else if (strcmp(rctlval->zone_rctlval_priv, "privileged") == 0) { 2957*7c478bd9Sstevel@tonic-gate priv = RCPRIV_PRIVILEGED; 2958*7c478bd9Sstevel@tonic-gate } else { 2959*7c478bd9Sstevel@tonic-gate /* Invalid privilege */ 2960*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2961*7c478bd9Sstevel@tonic-gate } 2962*7c478bd9Sstevel@tonic-gate 2963*7c478bd9Sstevel@tonic-gate /* deal with negative input; strtoull(3c) doesn't do what we want */ 2964*7c478bd9Sstevel@tonic-gate if (rctlval->zone_rctlval_limit[0] == '-') 2965*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2966*7c478bd9Sstevel@tonic-gate /* Get the limit */ 2967*7c478bd9Sstevel@tonic-gate errno = 0; 2968*7c478bd9Sstevel@tonic-gate ull = strtoull(rctlval->zone_rctlval_limit, &endp, 0); 2969*7c478bd9Sstevel@tonic-gate if (errno != 0 || *endp != '\0') { 2970*7c478bd9Sstevel@tonic-gate /* parse failed */ 2971*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2972*7c478bd9Sstevel@tonic-gate } 2973*7c478bd9Sstevel@tonic-gate limit = (rctl_qty_t)ull; 2974*7c478bd9Sstevel@tonic-gate 2975*7c478bd9Sstevel@tonic-gate /* Get the action */ 2976*7c478bd9Sstevel@tonic-gate if (strcmp(rctlval->zone_rctlval_action, "none") == 0) { 2977*7c478bd9Sstevel@tonic-gate action = RCTL_LOCAL_NOACTION; 2978*7c478bd9Sstevel@tonic-gate } else if (strcmp(rctlval->zone_rctlval_action, "signal") == 0) { 2979*7c478bd9Sstevel@tonic-gate action = RCTL_LOCAL_SIGNAL; 2980*7c478bd9Sstevel@tonic-gate } else if (strcmp(rctlval->zone_rctlval_action, "deny") == 0) { 2981*7c478bd9Sstevel@tonic-gate action = RCTL_LOCAL_DENY; 2982*7c478bd9Sstevel@tonic-gate } else { 2983*7c478bd9Sstevel@tonic-gate /* Invalid Action */ 2984*7c478bd9Sstevel@tonic-gate return (Z_INVAL); 2985*7c478bd9Sstevel@tonic-gate } 2986*7c478bd9Sstevel@tonic-gate rctlblk_set_local_action(rctlblk, action, 0); 2987*7c478bd9Sstevel@tonic-gate rctlblk_set_privilege(rctlblk, priv); 2988*7c478bd9Sstevel@tonic-gate rctlblk_set_value(rctlblk, limit); 2989*7c478bd9Sstevel@tonic-gate return (Z_OK); 2990*7c478bd9Sstevel@tonic-gate } 2991*7c478bd9Sstevel@tonic-gate 2992*7c478bd9Sstevel@tonic-gate static int 2993*7c478bd9Sstevel@tonic-gate rctl_check(const char *rctlname, void *arg) 2994*7c478bd9Sstevel@tonic-gate { 2995*7c478bd9Sstevel@tonic-gate const char *attrname = arg; 2996*7c478bd9Sstevel@tonic-gate 2997*7c478bd9Sstevel@tonic-gate /* 2998*7c478bd9Sstevel@tonic-gate * Returning 1 here is our signal to zonecfg_is_rctl() that it is 2999*7c478bd9Sstevel@tonic-gate * indeed an rctl name recognized by the system. 3000*7c478bd9Sstevel@tonic-gate */ 3001*7c478bd9Sstevel@tonic-gate return (strcmp(rctlname, attrname) == 0 ? 1 : 0); 3002*7c478bd9Sstevel@tonic-gate } 3003*7c478bd9Sstevel@tonic-gate 3004*7c478bd9Sstevel@tonic-gate boolean_t 3005*7c478bd9Sstevel@tonic-gate zonecfg_is_rctl(const char *name) 3006*7c478bd9Sstevel@tonic-gate { 3007*7c478bd9Sstevel@tonic-gate return (rctl_walk(rctl_check, (void *)name) == 1); 3008*7c478bd9Sstevel@tonic-gate } 3009*7c478bd9Sstevel@tonic-gate 3010*7c478bd9Sstevel@tonic-gate boolean_t 3011*7c478bd9Sstevel@tonic-gate zonecfg_valid_rctlname(const char *name) 3012*7c478bd9Sstevel@tonic-gate { 3013*7c478bd9Sstevel@tonic-gate const char *c; 3014*7c478bd9Sstevel@tonic-gate 3015*7c478bd9Sstevel@tonic-gate if (strncmp(name, "zone.", sizeof ("zone.") - 1) != 0) 3016*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3017*7c478bd9Sstevel@tonic-gate if (strlen(name) == sizeof ("zone.") - 1) 3018*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3019*7c478bd9Sstevel@tonic-gate for (c = name + sizeof ("zone.") - 1; *c != '\0'; c++) { 3020*7c478bd9Sstevel@tonic-gate if (!isalpha(*c) && *c != '-') 3021*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3022*7c478bd9Sstevel@tonic-gate } 3023*7c478bd9Sstevel@tonic-gate return (B_TRUE); 3024*7c478bd9Sstevel@tonic-gate } 3025*7c478bd9Sstevel@tonic-gate 3026*7c478bd9Sstevel@tonic-gate boolean_t 3027*7c478bd9Sstevel@tonic-gate zonecfg_valid_rctlblk(const rctlblk_t *rctlblk) 3028*7c478bd9Sstevel@tonic-gate { 3029*7c478bd9Sstevel@tonic-gate rctl_priv_t priv = rctlblk_get_privilege((rctlblk_t *)rctlblk); 3030*7c478bd9Sstevel@tonic-gate uint_t action = rctlblk_get_local_action((rctlblk_t *)rctlblk, NULL); 3031*7c478bd9Sstevel@tonic-gate 3032*7c478bd9Sstevel@tonic-gate if (priv != RCPRIV_PRIVILEGED) 3033*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3034*7c478bd9Sstevel@tonic-gate if (action != RCTL_LOCAL_NOACTION && action != RCTL_LOCAL_DENY) 3035*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3036*7c478bd9Sstevel@tonic-gate return (B_TRUE); 3037*7c478bd9Sstevel@tonic-gate } 3038*7c478bd9Sstevel@tonic-gate 3039*7c478bd9Sstevel@tonic-gate boolean_t 3040*7c478bd9Sstevel@tonic-gate zonecfg_valid_rctl(const char *name, const rctlblk_t *rctlblk) 3041*7c478bd9Sstevel@tonic-gate { 3042*7c478bd9Sstevel@tonic-gate rctlblk_t *current, *next; 3043*7c478bd9Sstevel@tonic-gate rctl_qty_t limit = rctlblk_get_value((rctlblk_t *)rctlblk); 3044*7c478bd9Sstevel@tonic-gate uint_t action = rctlblk_get_local_action((rctlblk_t *)rctlblk, NULL); 3045*7c478bd9Sstevel@tonic-gate uint_t global_flags; 3046*7c478bd9Sstevel@tonic-gate 3047*7c478bd9Sstevel@tonic-gate if (!zonecfg_valid_rctlblk(rctlblk)) 3048*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3049*7c478bd9Sstevel@tonic-gate if (!zonecfg_valid_rctlname(name)) 3050*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3051*7c478bd9Sstevel@tonic-gate 3052*7c478bd9Sstevel@tonic-gate current = alloca(rctlblk_size()); 3053*7c478bd9Sstevel@tonic-gate if (getrctl(name, NULL, current, RCTL_FIRST) != 0) 3054*7c478bd9Sstevel@tonic-gate return (B_TRUE); /* not an rctl on this system */ 3055*7c478bd9Sstevel@tonic-gate /* 3056*7c478bd9Sstevel@tonic-gate * Make sure the proposed value isn't greater than the current system 3057*7c478bd9Sstevel@tonic-gate * value. 3058*7c478bd9Sstevel@tonic-gate */ 3059*7c478bd9Sstevel@tonic-gate next = alloca(rctlblk_size()); 3060*7c478bd9Sstevel@tonic-gate while (rctlblk_get_privilege(current) != RCPRIV_SYSTEM) { 3061*7c478bd9Sstevel@tonic-gate rctlblk_t *tmp; 3062*7c478bd9Sstevel@tonic-gate 3063*7c478bd9Sstevel@tonic-gate if (getrctl(name, current, next, RCTL_NEXT) != 0) 3064*7c478bd9Sstevel@tonic-gate return (B_FALSE); /* shouldn't happen */ 3065*7c478bd9Sstevel@tonic-gate tmp = current; 3066*7c478bd9Sstevel@tonic-gate current = next; 3067*7c478bd9Sstevel@tonic-gate next = tmp; 3068*7c478bd9Sstevel@tonic-gate } 3069*7c478bd9Sstevel@tonic-gate if (limit > rctlblk_get_value(current)) 3070*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3071*7c478bd9Sstevel@tonic-gate 3072*7c478bd9Sstevel@tonic-gate /* 3073*7c478bd9Sstevel@tonic-gate * Make sure the proposed action is allowed. 3074*7c478bd9Sstevel@tonic-gate */ 3075*7c478bd9Sstevel@tonic-gate global_flags = rctlblk_get_global_flags(current); 3076*7c478bd9Sstevel@tonic-gate if ((global_flags & RCTL_GLOBAL_DENY_NEVER) && 3077*7c478bd9Sstevel@tonic-gate action == RCTL_LOCAL_DENY) 3078*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3079*7c478bd9Sstevel@tonic-gate if ((global_flags & RCTL_GLOBAL_DENY_ALWAYS) && 3080*7c478bd9Sstevel@tonic-gate action == RCTL_LOCAL_NOACTION) 3081*7c478bd9Sstevel@tonic-gate return (B_FALSE); 3082*7c478bd9Sstevel@tonic-gate 3083*7c478bd9Sstevel@tonic-gate return (B_TRUE); 3084*7c478bd9Sstevel@tonic-gate } 3085