19acbbeafSnn35248 /*
29acbbeafSnn35248 * CDDL HEADER START
39acbbeafSnn35248 *
49acbbeafSnn35248 * The contents of this file are subject to the terms of the
59acbbeafSnn35248 * Common Development and Distribution License (the "License").
69acbbeafSnn35248 * You may not use this file except in compliance with the License.
79acbbeafSnn35248 *
89acbbeafSnn35248 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99acbbeafSnn35248 * or http://www.opensolaris.org/os/licensing.
109acbbeafSnn35248 * See the License for the specific language governing permissions
119acbbeafSnn35248 * and limitations under the License.
129acbbeafSnn35248 *
139acbbeafSnn35248 * When distributing Covered Code, include this CDDL HEADER in each
149acbbeafSnn35248 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159acbbeafSnn35248 * If applicable, add the following below this CDDL HEADER, with the
169acbbeafSnn35248 * fields enclosed by brackets "[]" replaced with your own identifying
179acbbeafSnn35248 * information: Portions Copyright [yyyy] [name of copyright owner]
189acbbeafSnn35248 *
199acbbeafSnn35248 * CDDL HEADER END
209acbbeafSnn35248 */
219acbbeafSnn35248
229acbbeafSnn35248 /*
23a20ee416SGlenn Faden * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24*bafd1f14SJerry Jelinek * Copyright (c) 2011, Joyent, Inc. All rights reserved.
253c7284bdSAlexander Eremin * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
269acbbeafSnn35248 */
279acbbeafSnn35248
289acbbeafSnn35248 #include <assert.h>
299acbbeafSnn35248 #include <dirent.h>
309acbbeafSnn35248 #include <errno.h>
319acbbeafSnn35248 #include <fnmatch.h>
329acbbeafSnn35248 #include <signal.h>
339acbbeafSnn35248 #include <stdlib.h>
349acbbeafSnn35248 #include <unistd.h>
359acbbeafSnn35248 #include <strings.h>
369acbbeafSnn35248 #include <synch.h>
379acbbeafSnn35248 #include <sys/brand.h>
389acbbeafSnn35248 #include <sys/fcntl.h>
399acbbeafSnn35248 #include <sys/param.h>
409acbbeafSnn35248 #include <sys/stat.h>
419acbbeafSnn35248 #include <sys/systeminfo.h>
429acbbeafSnn35248 #include <sys/types.h>
439acbbeafSnn35248 #include <thread.h>
449acbbeafSnn35248 #include <zone.h>
459acbbeafSnn35248
469acbbeafSnn35248 #include <libbrand_impl.h>
479acbbeafSnn35248 #include <libbrand.h>
489acbbeafSnn35248
49ff17c8bfSgjelinek #define DTD_ELEM_ATTACH ((const xmlChar *) "attach")
509acbbeafSnn35248 #define DTD_ELEM_BOOT ((const xmlChar *) "boot")
519acbbeafSnn35248 #define DTD_ELEM_BRAND ((const xmlChar *) "brand")
52ff17c8bfSgjelinek #define DTD_ELEM_CLONE ((const xmlChar *) "clone")
539acbbeafSnn35248 #define DTD_ELEM_COMMENT ((const xmlChar *) "comment")
54ff17c8bfSgjelinek #define DTD_ELEM_DETACH ((const xmlChar *) "detach")
559acbbeafSnn35248 #define DTD_ELEM_DEVICE ((const xmlChar *) "device")
569acbbeafSnn35248 #define DTD_ELEM_GLOBAL_MOUNT ((const xmlChar *) "global_mount")
579acbbeafSnn35248 #define DTD_ELEM_HALT ((const xmlChar *) "halt")
589acbbeafSnn35248 #define DTD_ELEM_INITNAME ((const xmlChar *) "initname")
599acbbeafSnn35248 #define DTD_ELEM_INSTALL ((const xmlChar *) "install")
609acbbeafSnn35248 #define DTD_ELEM_INSTALLOPTS ((const xmlChar *) "installopts")
619acbbeafSnn35248 #define DTD_ELEM_LOGIN_CMD ((const xmlChar *) "login_cmd")
62cb8a054bSGlenn Faden #define DTD_ELEM_FORCELOGIN_CMD ((const xmlChar *) "forcedlogin_cmd")
639acbbeafSnn35248 #define DTD_ELEM_MODNAME ((const xmlChar *) "modname")
649acbbeafSnn35248 #define DTD_ELEM_MOUNT ((const xmlChar *) "mount")
65*bafd1f14SJerry Jelinek #define DTD_ELEM_RESTARTINIT ((const xmlChar *) "restartinit")
6637774979Sgjelinek #define DTD_ELEM_POSTATTACH ((const xmlChar *) "postattach")
679acbbeafSnn35248 #define DTD_ELEM_POSTCLONE ((const xmlChar *) "postclone")
681100f00dSgjelinek #define DTD_ELEM_POSTINSTALL ((const xmlChar *) "postinstall")
69ff17c8bfSgjelinek #define DTD_ELEM_POSTSNAP ((const xmlChar *) "postsnap")
70c5cd6260S #define DTD_ELEM_POSTSTATECHG ((const xmlChar *) "poststatechange")
7137774979Sgjelinek #define DTD_ELEM_PREDETACH ((const xmlChar *) "predetach")
72ff17c8bfSgjelinek #define DTD_ELEM_PRESNAP ((const xmlChar *) "presnap")
73c5cd6260S #define DTD_ELEM_PRESTATECHG ((const xmlChar *) "prestatechange")
7437774979Sgjelinek #define DTD_ELEM_PREUNINSTALL ((const xmlChar *) "preuninstall")
759acbbeafSnn35248 #define DTD_ELEM_PRIVILEGE ((const xmlChar *) "privilege")
76c5cd6260S #define DTD_ELEM_QUERY ((const xmlChar *) "query")
773c7284bdSAlexander Eremin #define DTD_ELEM_SHUTDOWN ((const xmlChar *) "shutdown")
789acbbeafSnn35248 #define DTD_ELEM_SYMLINK ((const xmlChar *) "symlink")
79fbbfbc6eSjv227347 #define DTD_ELEM_SYSBOOT ((const xmlChar *) "sysboot")
80ff17c8bfSgjelinek #define DTD_ELEM_UNINSTALL ((const xmlChar *) "uninstall")
81858a4b99Ssl108498 #define DTD_ELEM_USER_CMD ((const xmlChar *) "user_cmd")
82ff17c8bfSgjelinek #define DTD_ELEM_VALIDSNAP ((const xmlChar *) "validatesnap")
839acbbeafSnn35248 #define DTD_ELEM_VERIFY_CFG ((const xmlChar *) "verify_cfg")
849acbbeafSnn35248 #define DTD_ELEM_VERIFY_ADM ((const xmlChar *) "verify_adm")
859acbbeafSnn35248
86f4b3ec61Sdh155122 #define DTD_ATTR_ALLOWEXCL ((const xmlChar *) "allow-exclusive-ip")
879acbbeafSnn35248 #define DTD_ATTR_ARCH ((const xmlChar *) "arch")
889acbbeafSnn35248 #define DTD_ATTR_DIRECTORY ((const xmlChar *) "directory")
89f4b3ec61Sdh155122 #define DTD_ATTR_IPTYPE ((const xmlChar *) "ip-type")
909acbbeafSnn35248 #define DTD_ATTR_MATCH ((const xmlChar *) "match")
919acbbeafSnn35248 #define DTD_ATTR_MODE ((const xmlChar *) "mode")
929acbbeafSnn35248 #define DTD_ATTR_NAME ((const xmlChar *) "name")
939acbbeafSnn35248 #define DTD_ATTR_OPT ((const xmlChar *) "opt")
949acbbeafSnn35248 #define DTD_ATTR_PATH ((const xmlChar *) "path")
959acbbeafSnn35248 #define DTD_ATTR_SET ((const xmlChar *) "set")
969acbbeafSnn35248 #define DTD_ATTR_SOURCE ((const xmlChar *) "source")
979acbbeafSnn35248 #define DTD_ATTR_SPECIAL ((const xmlChar *) "special")
989acbbeafSnn35248 #define DTD_ATTR_TARGET ((const xmlChar *) "target")
999acbbeafSnn35248 #define DTD_ATTR_TYPE ((const xmlChar *) "type")
1009acbbeafSnn35248
101f4b3ec61Sdh155122 #define DTD_ENTITY_TRUE "true"
102f4b3ec61Sdh155122
1039acbbeafSnn35248 static volatile boolean_t libbrand_initialized = B_FALSE;
1049acbbeafSnn35248 static char i_curr_arch[MAXNAMELEN];
1059acbbeafSnn35248 static char i_curr_zone[ZONENAME_MAX];
1069acbbeafSnn35248
1079acbbeafSnn35248 /*ARGSUSED*/
1089acbbeafSnn35248 static void
brand_error_func(void * ctx,const char * msg,...)1099acbbeafSnn35248 brand_error_func(void *ctx, const char *msg, ...)
1109acbbeafSnn35248 {
1119acbbeafSnn35248 /*
1129acbbeafSnn35248 * Ignore error messages from libxml
1139acbbeafSnn35248 */
1149acbbeafSnn35248 }
1159acbbeafSnn35248
1169acbbeafSnn35248 static boolean_t
libbrand_initialize()1179acbbeafSnn35248 libbrand_initialize()
1189acbbeafSnn35248 {
1199acbbeafSnn35248 static mutex_t initialize_lock = DEFAULTMUTEX;
1209acbbeafSnn35248
1219acbbeafSnn35248 (void) mutex_lock(&initialize_lock);
1229acbbeafSnn35248
1239acbbeafSnn35248 if (libbrand_initialized) {
1249acbbeafSnn35248 (void) mutex_unlock(&initialize_lock);
1259acbbeafSnn35248 return (B_TRUE);
1269acbbeafSnn35248 }
1279acbbeafSnn35248
1289acbbeafSnn35248 if (sysinfo(SI_ARCHITECTURE, i_curr_arch, sizeof (i_curr_arch)) < 0) {
1299acbbeafSnn35248 (void) mutex_unlock(&initialize_lock);
1309acbbeafSnn35248 return (B_FALSE);
1319acbbeafSnn35248 }
1329acbbeafSnn35248
1339acbbeafSnn35248 if (getzonenamebyid(getzoneid(), i_curr_zone,
1349acbbeafSnn35248 sizeof (i_curr_zone)) < 0) {
1359acbbeafSnn35248 (void) mutex_unlock(&initialize_lock);
1369acbbeafSnn35248 return (B_FALSE);
1379acbbeafSnn35248 }
1389acbbeafSnn35248
1399acbbeafSnn35248 /*
1409acbbeafSnn35248 * Note that here we're initializing per-process libxml2
1419acbbeafSnn35248 * state. By doing so we're implicitly assuming that
1429acbbeafSnn35248 * no other code in this process is also trying to
1439acbbeafSnn35248 * use libxml2. But in most case we know this not to
1449acbbeafSnn35248 * be true since we're almost always used in conjunction
1459acbbeafSnn35248 * with libzonecfg, which also uses libxml2. Lucky for
1469acbbeafSnn35248 * us, libzonecfg initializes libxml2 to essentially
1479acbbeafSnn35248 * the same defaults as we're using below.
1489acbbeafSnn35248 */
1495ad42b1bSSurya Prakki (void) xmlLineNumbersDefault(1);
1509acbbeafSnn35248 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1519acbbeafSnn35248 xmlDoValidityCheckingDefaultValue = 1;
1529acbbeafSnn35248 (void) xmlKeepBlanksDefault(0);
1539acbbeafSnn35248 xmlGetWarningsDefaultValue = 0;
1549acbbeafSnn35248 xmlSetGenericErrorFunc(NULL, brand_error_func);
1559acbbeafSnn35248
1569acbbeafSnn35248 libbrand_initialized = B_TRUE;
1579acbbeafSnn35248 (void) mutex_unlock(&initialize_lock);
1589acbbeafSnn35248 return (B_TRUE);
1599acbbeafSnn35248 }
1609acbbeafSnn35248
1619acbbeafSnn35248 static const char *
get_curr_arch(void)1629acbbeafSnn35248 get_curr_arch(void)
1639acbbeafSnn35248 {
1649acbbeafSnn35248 if (!libbrand_initialize())
1659acbbeafSnn35248 return (NULL);
1669acbbeafSnn35248
1679acbbeafSnn35248 return (i_curr_arch);
1689acbbeafSnn35248 }
1699acbbeafSnn35248
1709acbbeafSnn35248 static const char *
get_curr_zone(void)1719acbbeafSnn35248 get_curr_zone(void)
1729acbbeafSnn35248 {
1739acbbeafSnn35248 if (!libbrand_initialize())
1749acbbeafSnn35248 return (NULL);
1759acbbeafSnn35248
1769acbbeafSnn35248 return (i_curr_zone);
1779acbbeafSnn35248 }
1789acbbeafSnn35248
1799acbbeafSnn35248 /*
1809acbbeafSnn35248 * Internal function to open an XML file
1819acbbeafSnn35248 *
1829acbbeafSnn35248 * Returns the XML doc pointer, or NULL on failure. It will validate the
1839acbbeafSnn35248 * document, as well as removing any comments from the document structure.
1849acbbeafSnn35248 */
1859acbbeafSnn35248 static xmlDocPtr
open_xml_file(const char * file)1869acbbeafSnn35248 open_xml_file(const char *file)
1879acbbeafSnn35248 {
1889acbbeafSnn35248 xmlDocPtr doc;
1899acbbeafSnn35248 xmlValidCtxtPtr cvp;
1909acbbeafSnn35248 int valid;
1919acbbeafSnn35248
1929acbbeafSnn35248 if (!libbrand_initialize())
1939acbbeafSnn35248 return (NULL);
1949acbbeafSnn35248
1959acbbeafSnn35248 /*
1969acbbeafSnn35248 * Parse the file
1979acbbeafSnn35248 */
1989acbbeafSnn35248 if ((doc = xmlParseFile(file)) == NULL)
1999acbbeafSnn35248 return (NULL);
2009acbbeafSnn35248
2019acbbeafSnn35248 /*
2029acbbeafSnn35248 * Validate the file
2039acbbeafSnn35248 */
2049acbbeafSnn35248 if ((cvp = xmlNewValidCtxt()) == NULL) {
2059acbbeafSnn35248 xmlFreeDoc(doc);
2069acbbeafSnn35248 return (NULL);
2079acbbeafSnn35248 }
2089acbbeafSnn35248 cvp->error = brand_error_func;
2099acbbeafSnn35248 cvp->warning = brand_error_func;
2109acbbeafSnn35248 valid = xmlValidateDocument(cvp, doc);
2119acbbeafSnn35248 xmlFreeValidCtxt(cvp);
2129acbbeafSnn35248 if (valid == 0) {
2139acbbeafSnn35248 xmlFreeDoc(doc);
2149acbbeafSnn35248 return (NULL);
2159acbbeafSnn35248 }
2169acbbeafSnn35248
2179acbbeafSnn35248 return (doc);
2189acbbeafSnn35248 }
2199acbbeafSnn35248 /*
2209acbbeafSnn35248 * Open a handle to the named brand.
2219acbbeafSnn35248 *
2229acbbeafSnn35248 * Returns a handle to the named brand, which is used for all subsequent brand
2239acbbeafSnn35248 * interaction, or NULL if unable to open or initialize the brand.
2249acbbeafSnn35248 */
225123807fbSedp brand_handle_t
brand_open(const char * name)2269acbbeafSnn35248 brand_open(const char *name)
2279acbbeafSnn35248 {
228123807fbSedp struct brand_handle *bhp;
2299acbbeafSnn35248 char path[MAXPATHLEN];
2309acbbeafSnn35248 xmlNodePtr node;
2319acbbeafSnn35248 xmlChar *property;
2329acbbeafSnn35248 struct stat statbuf;
2339acbbeafSnn35248
2349acbbeafSnn35248 /*
2359acbbeafSnn35248 * Make sure brand name isn't too long
2369acbbeafSnn35248 */
2379acbbeafSnn35248 if (strlen(name) >= MAXNAMELEN)
2389acbbeafSnn35248 return (NULL);
2399acbbeafSnn35248
2409acbbeafSnn35248 /*
2419acbbeafSnn35248 * Check that the brand exists
2429acbbeafSnn35248 */
2439acbbeafSnn35248 (void) snprintf(path, sizeof (path), "%s/%s", BRAND_DIR, name);
2449acbbeafSnn35248
2459acbbeafSnn35248 if (stat(path, &statbuf) != 0)
2469acbbeafSnn35248 return (NULL);
2479acbbeafSnn35248
2489acbbeafSnn35248 /*
2499acbbeafSnn35248 * Allocate brand handle
2509acbbeafSnn35248 */
251123807fbSedp if ((bhp = malloc(sizeof (struct brand_handle))) == NULL)
2529acbbeafSnn35248 return (NULL);
253123807fbSedp bzero(bhp, sizeof (struct brand_handle));
2549acbbeafSnn35248
2559acbbeafSnn35248 (void) strcpy(bhp->bh_name, name);
2569acbbeafSnn35248
2579acbbeafSnn35248 /*
2589acbbeafSnn35248 * Open the configuration file
2599acbbeafSnn35248 */
2609acbbeafSnn35248 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
2619acbbeafSnn35248 BRAND_CONFIG);
2629acbbeafSnn35248 if ((bhp->bh_config = open_xml_file(path)) == NULL) {
263123807fbSedp brand_close((brand_handle_t)bhp);
2649acbbeafSnn35248 return (NULL);
2659acbbeafSnn35248 }
2669acbbeafSnn35248
2679acbbeafSnn35248 /*
2689acbbeafSnn35248 * Verify that the name of the brand matches the directory in which it
2699acbbeafSnn35248 * is installed.
2709acbbeafSnn35248 */
2719acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL) {
272123807fbSedp brand_close((brand_handle_t)bhp);
2739acbbeafSnn35248 return (NULL);
2749acbbeafSnn35248 }
2759acbbeafSnn35248
2769acbbeafSnn35248 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0) {
277123807fbSedp brand_close((brand_handle_t)bhp);
2789acbbeafSnn35248 return (NULL);
2799acbbeafSnn35248 }
2809acbbeafSnn35248
2819acbbeafSnn35248 if ((property = xmlGetProp(node, DTD_ATTR_NAME)) == NULL) {
282123807fbSedp brand_close((brand_handle_t)bhp);
2839acbbeafSnn35248 return (NULL);
2849acbbeafSnn35248 }
2859acbbeafSnn35248
2869acbbeafSnn35248 if (strcmp((char *)property, name) != 0) {
2879acbbeafSnn35248 xmlFree(property);
288123807fbSedp brand_close((brand_handle_t)bhp);
2899acbbeafSnn35248 return (NULL);
2909acbbeafSnn35248 }
2919acbbeafSnn35248 xmlFree(property);
2929acbbeafSnn35248
2939acbbeafSnn35248 /*
2949acbbeafSnn35248 * Open handle to platform configuration file.
2959acbbeafSnn35248 */
2969acbbeafSnn35248 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
2979acbbeafSnn35248 BRAND_PLATFORM);
2989acbbeafSnn35248 if ((bhp->bh_platform = open_xml_file(path)) == NULL) {
299123807fbSedp brand_close((brand_handle_t)bhp);
3009acbbeafSnn35248 return (NULL);
3019acbbeafSnn35248 }
3029acbbeafSnn35248
303123807fbSedp return ((brand_handle_t)bhp);
3049acbbeafSnn35248 }
3059acbbeafSnn35248
3069acbbeafSnn35248 /*
3079acbbeafSnn35248 * Closes the given brand handle
3089acbbeafSnn35248 */
3099acbbeafSnn35248 void
brand_close(brand_handle_t bh)310123807fbSedp brand_close(brand_handle_t bh)
3119acbbeafSnn35248 {
312123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
3139acbbeafSnn35248 if (bhp->bh_platform != NULL)
3149acbbeafSnn35248 xmlFreeDoc(bhp->bh_platform);
3159acbbeafSnn35248 if (bhp->bh_config != NULL)
3169acbbeafSnn35248 xmlFreeDoc(bhp->bh_config);
3179acbbeafSnn35248 free(bhp);
3189acbbeafSnn35248 }
3199acbbeafSnn35248
3209acbbeafSnn35248 static int
i_substitute_tokens(const char * sbuf,char * dbuf,int dbuf_size,const char * zonename,const char * zonepath,const char * username,const char * curr_zone)3219acbbeafSnn35248 i_substitute_tokens(const char *sbuf, char *dbuf, int dbuf_size,
322ff17c8bfSgjelinek const char *zonename, const char *zonepath, const char *username,
323ff17c8bfSgjelinek const char *curr_zone)
3249acbbeafSnn35248 {
325ff17c8bfSgjelinek int dst, src;
3269acbbeafSnn35248
3279acbbeafSnn35248 /*
3289acbbeafSnn35248 * Walk through the characters, substituting values as needed.
3299acbbeafSnn35248 */
3309acbbeafSnn35248 dbuf[0] = '\0';
3319acbbeafSnn35248 dst = 0;
3329acbbeafSnn35248 for (src = 0; src < strlen((char *)sbuf) && dst < dbuf_size; src++) {
3339acbbeafSnn35248 if (sbuf[src] != '%') {
3349acbbeafSnn35248 dbuf[dst++] = sbuf[src];
3359acbbeafSnn35248 continue;
3369acbbeafSnn35248 }
3379acbbeafSnn35248
3389acbbeafSnn35248 switch (sbuf[++src]) {
3399acbbeafSnn35248 case '%':
3409acbbeafSnn35248 dst += strlcpy(dbuf + dst, "%", dbuf_size - dst);
3419acbbeafSnn35248 break;
3429acbbeafSnn35248 case 'R':
343ff17c8bfSgjelinek if (zonepath == NULL)
3449acbbeafSnn35248 break;
345ff17c8bfSgjelinek dst += strlcpy(dbuf + dst, zonepath, dbuf_size - dst);
3469acbbeafSnn35248 break;
3479acbbeafSnn35248 case 'u':
3489acbbeafSnn35248 if (username == NULL)
3499acbbeafSnn35248 break;
3509acbbeafSnn35248 dst += strlcpy(dbuf + dst, username, dbuf_size - dst);
3519acbbeafSnn35248 break;
3529acbbeafSnn35248 case 'Z':
3539acbbeafSnn35248 if (curr_zone == NULL)
3549acbbeafSnn35248 break;
3559acbbeafSnn35248 /* name of the zone we're running in */
3569acbbeafSnn35248 dst += strlcpy(dbuf + dst, curr_zone, dbuf_size - dst);
3579acbbeafSnn35248 break;
3589acbbeafSnn35248 case 'z':
3599acbbeafSnn35248 /* name of the zone we're operating on */
3609acbbeafSnn35248 if (zonename == NULL)
3619acbbeafSnn35248 break;
3629acbbeafSnn35248 dst += strlcpy(dbuf + dst, zonename, dbuf_size - dst);
3639acbbeafSnn35248 break;
3649acbbeafSnn35248 }
3659acbbeafSnn35248 }
3669acbbeafSnn35248
3679acbbeafSnn35248 if (dst >= dbuf_size)
3689acbbeafSnn35248 return (-1);
3699acbbeafSnn35248
3709acbbeafSnn35248 dbuf[dst] = '\0';
3719acbbeafSnn35248 return (0);
3729acbbeafSnn35248 }
3739acbbeafSnn35248
3749acbbeafSnn35248 /*
3759acbbeafSnn35248 * Retrieve the given tag from the brand.
3769acbbeafSnn35248 * Perform the following substitutions as necessary:
3779acbbeafSnn35248 *
3789acbbeafSnn35248 * %% %
3799acbbeafSnn35248 * %u Username
3809acbbeafSnn35248 * %z Name of target zone
3819acbbeafSnn35248 * %Z Name of current zone
382ff17c8bfSgjelinek * %R Zonepath of zone
3839acbbeafSnn35248 *
3849acbbeafSnn35248 * Returns 0 on success, -1 on failure.
3859acbbeafSnn35248 */
3869acbbeafSnn35248 static int
brand_get_value(struct brand_handle * bhp,const char * zonename,const char * zonepath,const char * username,const char * curr_zone,char * buf,size_t len,const xmlChar * tagname,boolean_t substitute,boolean_t optional)387123807fbSedp brand_get_value(struct brand_handle *bhp, const char *zonename,
388ff17c8bfSgjelinek const char *zonepath, const char *username, const char *curr_zone,
389ff17c8bfSgjelinek char *buf, size_t len, const xmlChar *tagname,
3909acbbeafSnn35248 boolean_t substitute, boolean_t optional)
3919acbbeafSnn35248 {
3929acbbeafSnn35248 xmlNodePtr node;
3939acbbeafSnn35248 xmlChar *content;
3949acbbeafSnn35248 int err = 0;
3959acbbeafSnn35248
3969acbbeafSnn35248 /*
3979acbbeafSnn35248 * Retrieve the specified value from the XML doc
3989acbbeafSnn35248 */
3999acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
4009acbbeafSnn35248 return (-1);
4019acbbeafSnn35248
4029acbbeafSnn35248 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0)
4039acbbeafSnn35248 return (-1);
4049acbbeafSnn35248
4059acbbeafSnn35248 for (node = node->xmlChildrenNode; node != NULL;
4069acbbeafSnn35248 node = node->next) {
4079acbbeafSnn35248 if (xmlStrcmp(node->name, tagname) == 0)
4089acbbeafSnn35248 break;
4099acbbeafSnn35248 }
4109acbbeafSnn35248
411db52f3aeSgjelinek if (node == NULL) {
412db52f3aeSgjelinek if (optional) {
413db52f3aeSgjelinek buf[0] = '\0';
414db52f3aeSgjelinek return (0);
415db52f3aeSgjelinek } else {
4169acbbeafSnn35248 return (-1);
417db52f3aeSgjelinek }
418db52f3aeSgjelinek }
4199acbbeafSnn35248
4209acbbeafSnn35248 if ((content = xmlNodeGetContent(node)) == NULL)
4219acbbeafSnn35248 return (-1);
4229acbbeafSnn35248
4239acbbeafSnn35248 if (strlen((char *)content) == 0) {
4249acbbeafSnn35248 /*
4259acbbeafSnn35248 * If the entry in the config file is empty, check to see
4269acbbeafSnn35248 * whether this is an optional field. If so, we return the
4279acbbeafSnn35248 * empty buffer. If not, we return an error.
4289acbbeafSnn35248 */
4299acbbeafSnn35248 if (optional) {
4309acbbeafSnn35248 buf[0] = '\0';
4319acbbeafSnn35248 } else {
4329acbbeafSnn35248 err = -1;
4339acbbeafSnn35248 }
4349acbbeafSnn35248 } else {
4359acbbeafSnn35248 /* Substitute token values as needed. */
4369acbbeafSnn35248 if (substitute) {
4379acbbeafSnn35248 if (i_substitute_tokens((char *)content, buf, len,
438ff17c8bfSgjelinek zonename, zonepath, username, curr_zone) != 0)
4399acbbeafSnn35248 err = -1;
4409acbbeafSnn35248 } else {
4419acbbeafSnn35248 if (strlcpy(buf, (char *)content, len) >= len)
4429acbbeafSnn35248 err = -1;
4439acbbeafSnn35248 }
4449acbbeafSnn35248 }
4459acbbeafSnn35248
4469acbbeafSnn35248 xmlFree(content);
4479acbbeafSnn35248
4489acbbeafSnn35248 return (err);
4499acbbeafSnn35248 }
4509acbbeafSnn35248
4519acbbeafSnn35248 int
brand_get_attach(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)452ff17c8bfSgjelinek brand_get_attach(brand_handle_t bh, const char *zonename,
453ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
4549acbbeafSnn35248 {
455123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
456ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
457ff17c8bfSgjelinek buf, len, DTD_ELEM_ATTACH, B_TRUE, B_TRUE));
458ff17c8bfSgjelinek }
459ff17c8bfSgjelinek
460ff17c8bfSgjelinek int
brand_get_boot(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)461ff17c8bfSgjelinek brand_get_boot(brand_handle_t bh, const char *zonename,
462ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
463ff17c8bfSgjelinek {
464ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
465ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
466ff17c8bfSgjelinek buf, len, DTD_ELEM_BOOT, B_TRUE, B_TRUE));
4679acbbeafSnn35248 }
4689acbbeafSnn35248
4699acbbeafSnn35248 int
brand_get_brandname(brand_handle_t bh,char * buf,size_t len)470123807fbSedp brand_get_brandname(brand_handle_t bh, char *buf, size_t len)
4719acbbeafSnn35248 {
472123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
4739acbbeafSnn35248 if (len <= strlen(bhp->bh_name))
4749acbbeafSnn35248 return (-1);
4759acbbeafSnn35248
4769acbbeafSnn35248 (void) strcpy(buf, bhp->bh_name);
4779acbbeafSnn35248
4789acbbeafSnn35248 return (0);
4799acbbeafSnn35248 }
4809acbbeafSnn35248
4819acbbeafSnn35248 int
brand_get_clone(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)482ff17c8bfSgjelinek brand_get_clone(brand_handle_t bh, const char *zonename,
483ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
4849acbbeafSnn35248 {
485123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
486ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
487ff17c8bfSgjelinek buf, len, DTD_ELEM_CLONE, B_TRUE, B_TRUE));
488ff17c8bfSgjelinek }
489ff17c8bfSgjelinek
490ff17c8bfSgjelinek int
brand_get_detach(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)491ff17c8bfSgjelinek brand_get_detach(brand_handle_t bh, const char *zonename,
492ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
493ff17c8bfSgjelinek {
494ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
495ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
496ff17c8bfSgjelinek buf, len, DTD_ELEM_DETACH, B_TRUE, B_TRUE));
497ff17c8bfSgjelinek }
498ff17c8bfSgjelinek
499ff17c8bfSgjelinek int
brand_get_halt(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)500ff17c8bfSgjelinek brand_get_halt(brand_handle_t bh, const char *zonename,
501ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
502ff17c8bfSgjelinek {
503ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
504ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
505ff17c8bfSgjelinek buf, len, DTD_ELEM_HALT, B_TRUE, B_TRUE));
5069acbbeafSnn35248 }
5079acbbeafSnn35248
5089acbbeafSnn35248 int
brand_get_shutdown(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)5093c7284bdSAlexander Eremin brand_get_shutdown(brand_handle_t bh, const char *zonename,
5103c7284bdSAlexander Eremin const char *zonepath, char *buf, size_t len)
5113c7284bdSAlexander Eremin {
5123c7284bdSAlexander Eremin struct brand_handle *bhp = (struct brand_handle *)bh;
5133c7284bdSAlexander Eremin return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
5143c7284bdSAlexander Eremin buf, len, DTD_ELEM_SHUTDOWN, B_TRUE, B_TRUE));
5153c7284bdSAlexander Eremin }
5163c7284bdSAlexander Eremin
5173c7284bdSAlexander Eremin int
brand_get_initname(brand_handle_t bh,char * buf,size_t len)518123807fbSedp brand_get_initname(brand_handle_t bh, char *buf, size_t len)
5199acbbeafSnn35248 {
520123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
5219acbbeafSnn35248 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
522ff17c8bfSgjelinek buf, len, DTD_ELEM_INITNAME, B_FALSE, B_FALSE));
5239acbbeafSnn35248 }
5249acbbeafSnn35248
525*bafd1f14SJerry Jelinek boolean_t
brand_restartinit(brand_handle_t bh)526*bafd1f14SJerry Jelinek brand_restartinit(brand_handle_t bh)
527*bafd1f14SJerry Jelinek {
528*bafd1f14SJerry Jelinek struct brand_handle *bhp = (struct brand_handle *)bh;
529*bafd1f14SJerry Jelinek char val[80];
530*bafd1f14SJerry Jelinek
531*bafd1f14SJerry Jelinek if (brand_get_value(bhp, NULL, NULL, NULL, NULL,
532*bafd1f14SJerry Jelinek val, sizeof (val), DTD_ELEM_RESTARTINIT, B_FALSE, B_FALSE) != 0)
533*bafd1f14SJerry Jelinek return (B_TRUE);
534*bafd1f14SJerry Jelinek
535*bafd1f14SJerry Jelinek if (strcmp(val, "false") == 0)
536*bafd1f14SJerry Jelinek return (B_FALSE);
537*bafd1f14SJerry Jelinek return (B_TRUE);
538*bafd1f14SJerry Jelinek }
539*bafd1f14SJerry Jelinek
5409acbbeafSnn35248 int
brand_get_login_cmd(brand_handle_t bh,const char * username,char * buf,size_t len)541123807fbSedp brand_get_login_cmd(brand_handle_t bh, const char *username,
5429acbbeafSnn35248 char *buf, size_t len)
5439acbbeafSnn35248 {
544123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
5459acbbeafSnn35248 const char *curr_zone = get_curr_zone();
5469acbbeafSnn35248 return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
547ff17c8bfSgjelinek buf, len, DTD_ELEM_LOGIN_CMD, B_TRUE, B_FALSE));
5489acbbeafSnn35248 }
5499acbbeafSnn35248
5509acbbeafSnn35248 int
brand_get_forcedlogin_cmd(brand_handle_t bh,const char * username,char * buf,size_t len)551cb8a054bSGlenn Faden brand_get_forcedlogin_cmd(brand_handle_t bh, const char *username,
552cb8a054bSGlenn Faden char *buf, size_t len)
553cb8a054bSGlenn Faden {
554cb8a054bSGlenn Faden struct brand_handle *bhp = (struct brand_handle *)bh;
555cb8a054bSGlenn Faden const char *curr_zone = get_curr_zone();
556cb8a054bSGlenn Faden return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
557cb8a054bSGlenn Faden buf, len, DTD_ELEM_FORCELOGIN_CMD, B_TRUE, B_FALSE));
558cb8a054bSGlenn Faden }
559cb8a054bSGlenn Faden
560cb8a054bSGlenn Faden int
brand_get_user_cmd(brand_handle_t bh,const char * username,char * buf,size_t len)561858a4b99Ssl108498 brand_get_user_cmd(brand_handle_t bh, const char *username,
562858a4b99Ssl108498 char *buf, size_t len)
563858a4b99Ssl108498 {
564858a4b99Ssl108498 struct brand_handle *bhp = (struct brand_handle *)bh;
565858a4b99Ssl108498
566858a4b99Ssl108498 return (brand_get_value(bhp, NULL, NULL, username, NULL,
567ff17c8bfSgjelinek buf, len, DTD_ELEM_USER_CMD, B_TRUE, B_FALSE));
568858a4b99Ssl108498 }
569858a4b99Ssl108498
570858a4b99Ssl108498 int
brand_get_install(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)571123807fbSedp brand_get_install(brand_handle_t bh, const char *zonename,
572ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
5739acbbeafSnn35248 {
574123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
575ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
576ff17c8bfSgjelinek buf, len, DTD_ELEM_INSTALL, B_TRUE, B_FALSE));
5779acbbeafSnn35248 }
5789acbbeafSnn35248
5799acbbeafSnn35248 int
brand_get_installopts(brand_handle_t bh,char * buf,size_t len)580123807fbSedp brand_get_installopts(brand_handle_t bh, char *buf, size_t len)
5819acbbeafSnn35248 {
582123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
5839acbbeafSnn35248 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
584ff17c8bfSgjelinek buf, len, DTD_ELEM_INSTALLOPTS, B_FALSE, B_TRUE));
5859acbbeafSnn35248 }
5869acbbeafSnn35248
5879acbbeafSnn35248 int
brand_get_modname(brand_handle_t bh,char * buf,size_t len)588123807fbSedp brand_get_modname(brand_handle_t bh, char *buf, size_t len)
5899acbbeafSnn35248 {
590123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
5919acbbeafSnn35248 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
592ff17c8bfSgjelinek buf, len, DTD_ELEM_MODNAME, B_FALSE, B_TRUE));
5939acbbeafSnn35248 }
5949acbbeafSnn35248
5959acbbeafSnn35248 int
brand_get_postattach(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)59637774979Sgjelinek brand_get_postattach(brand_handle_t bh, const char *zonename,
597ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
59837774979Sgjelinek {
59937774979Sgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
600ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
601ff17c8bfSgjelinek buf, len, DTD_ELEM_POSTATTACH, B_TRUE, B_TRUE));
60237774979Sgjelinek }
60337774979Sgjelinek
60437774979Sgjelinek int
brand_get_postclone(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)605123807fbSedp brand_get_postclone(brand_handle_t bh, const char *zonename,
606ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
6079acbbeafSnn35248 {
608123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
609ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
610ff17c8bfSgjelinek buf, len, DTD_ELEM_POSTCLONE, B_TRUE, B_TRUE));
6119acbbeafSnn35248 }
6129acbbeafSnn35248
6139acbbeafSnn35248 int
brand_get_postinstall(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)6141100f00dSgjelinek brand_get_postinstall(brand_handle_t bh, const char *zonename,
615ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
6161100f00dSgjelinek {
6171100f00dSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
618ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
619ff17c8bfSgjelinek buf, len, DTD_ELEM_POSTINSTALL, B_TRUE, B_TRUE));
620ff17c8bfSgjelinek }
621ff17c8bfSgjelinek
622ff17c8bfSgjelinek int
brand_get_postsnap(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)623ff17c8bfSgjelinek brand_get_postsnap(brand_handle_t bh, const char *zonename,
624ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
625ff17c8bfSgjelinek {
626ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
627ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
628ff17c8bfSgjelinek buf, len, DTD_ELEM_POSTSNAP, B_TRUE, B_TRUE));
6291100f00dSgjelinek }
6301100f00dSgjelinek
6311100f00dSgjelinek int
brand_get_poststatechange(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)632c5cd6260S brand_get_poststatechange(brand_handle_t bh, const char *zonename,
633c5cd6260S const char *zonepath, char *buf, size_t len)
634c5cd6260S {
635c5cd6260S struct brand_handle *bhp = (struct brand_handle *)bh;
636c5cd6260S return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
637c5cd6260S buf, len, DTD_ELEM_POSTSTATECHG, B_TRUE, B_TRUE));
638c5cd6260S }
639c5cd6260S
640c5cd6260S int
brand_get_predetach(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)64137774979Sgjelinek brand_get_predetach(brand_handle_t bh, const char *zonename,
642ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
64337774979Sgjelinek {
64437774979Sgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
645ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
646ff17c8bfSgjelinek buf, len, DTD_ELEM_PREDETACH, B_TRUE, B_TRUE));
647ff17c8bfSgjelinek }
648ff17c8bfSgjelinek
649ff17c8bfSgjelinek int
brand_get_presnap(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)650ff17c8bfSgjelinek brand_get_presnap(brand_handle_t bh, const char *zonename,
651ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
652ff17c8bfSgjelinek {
653ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
654ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
655ff17c8bfSgjelinek buf, len, DTD_ELEM_PRESNAP, B_TRUE, B_TRUE));
65637774979Sgjelinek }
65737774979Sgjelinek
65837774979Sgjelinek int
brand_get_prestatechange(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)659c5cd6260S brand_get_prestatechange(brand_handle_t bh, const char *zonename,
660c5cd6260S const char *zonepath, char *buf, size_t len)
661c5cd6260S {
662c5cd6260S struct brand_handle *bhp = (struct brand_handle *)bh;
663c5cd6260S return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
664c5cd6260S buf, len, DTD_ELEM_PRESTATECHG, B_TRUE, B_TRUE));
665c5cd6260S }
666c5cd6260S
667c5cd6260S int
brand_get_preuninstall(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)66837774979Sgjelinek brand_get_preuninstall(brand_handle_t bh, const char *zonename,
669ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
67037774979Sgjelinek {
67137774979Sgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
672ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
673ff17c8bfSgjelinek buf, len, DTD_ELEM_PREUNINSTALL, B_TRUE, B_TRUE));
674ff17c8bfSgjelinek }
675ff17c8bfSgjelinek
676ff17c8bfSgjelinek int
brand_get_query(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)677c5cd6260S brand_get_query(brand_handle_t bh, const char *zonename,
678c5cd6260S const char *zonepath, char *buf, size_t len)
679c5cd6260S {
680c5cd6260S struct brand_handle *bhp = (struct brand_handle *)bh;
681c5cd6260S return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
682c5cd6260S buf, len, DTD_ELEM_QUERY, B_TRUE, B_TRUE));
683c5cd6260S }
684c5cd6260S
685c5cd6260S int
brand_get_uninstall(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)686ff17c8bfSgjelinek brand_get_uninstall(brand_handle_t bh, const char *zonename,
687ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
688ff17c8bfSgjelinek {
689ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
690ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
691ff17c8bfSgjelinek buf, len, DTD_ELEM_UNINSTALL, B_TRUE, B_TRUE));
692ff17c8bfSgjelinek }
693ff17c8bfSgjelinek
694ff17c8bfSgjelinek int
brand_get_validatesnap(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)695ff17c8bfSgjelinek brand_get_validatesnap(brand_handle_t bh, const char *zonename,
696ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
697ff17c8bfSgjelinek {
698ff17c8bfSgjelinek struct brand_handle *bhp = (struct brand_handle *)bh;
699ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
700ff17c8bfSgjelinek buf, len, DTD_ELEM_VALIDSNAP, B_TRUE, B_TRUE));
70137774979Sgjelinek }
70237774979Sgjelinek
70337774979Sgjelinek int
brand_get_verify_cfg(brand_handle_t bh,char * buf,size_t len)704123807fbSedp brand_get_verify_cfg(brand_handle_t bh, char *buf, size_t len)
7059acbbeafSnn35248 {
706123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
7079acbbeafSnn35248 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
708ff17c8bfSgjelinek buf, len, DTD_ELEM_VERIFY_CFG, B_FALSE, B_TRUE));
7099acbbeafSnn35248 }
7109acbbeafSnn35248
7119acbbeafSnn35248 int
brand_get_verify_adm(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)712123807fbSedp brand_get_verify_adm(brand_handle_t bh, const char *zonename,
713ff17c8bfSgjelinek const char *zonepath, char *buf, size_t len)
7149acbbeafSnn35248 {
715123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
716ff17c8bfSgjelinek return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
717ff17c8bfSgjelinek buf, len, DTD_ELEM_VERIFY_ADM, B_TRUE, B_TRUE));
7189acbbeafSnn35248 }
7199acbbeafSnn35248
7209acbbeafSnn35248 int
brand_get_sysboot(brand_handle_t bh,const char * zonename,const char * zonepath,char * buf,size_t len)721fbbfbc6eSjv227347 brand_get_sysboot(brand_handle_t bh, const char *zonename,
722fbbfbc6eSjv227347 const char *zonepath, char *buf, size_t len)
723fbbfbc6eSjv227347 {
724fbbfbc6eSjv227347 struct brand_handle *bhp = (struct brand_handle *)bh;
725fbbfbc6eSjv227347 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
726fbbfbc6eSjv227347 buf, len, DTD_ELEM_SYSBOOT, B_TRUE, B_TRUE));
727fbbfbc6eSjv227347 }
728fbbfbc6eSjv227347
729f4b3ec61Sdh155122 boolean_t
brand_allow_exclusive_ip(brand_handle_t bh)730f4b3ec61Sdh155122 brand_allow_exclusive_ip(brand_handle_t bh)
731f4b3ec61Sdh155122 {
732f4b3ec61Sdh155122 struct brand_handle *bhp = (struct brand_handle *)bh;
733f4b3ec61Sdh155122 xmlNodePtr node;
734f4b3ec61Sdh155122 xmlChar *allow_excl;
735f4b3ec61Sdh155122 boolean_t ret;
736f4b3ec61Sdh155122
737f4b3ec61Sdh155122 assert(bhp != NULL);
738f4b3ec61Sdh155122
739f4b3ec61Sdh155122 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
740f4b3ec61Sdh155122 return (B_FALSE);
741f4b3ec61Sdh155122
742f4b3ec61Sdh155122 allow_excl = xmlGetProp(node, DTD_ATTR_ALLOWEXCL);
743f4b3ec61Sdh155122 if (allow_excl == NULL)
744f4b3ec61Sdh155122 return (B_FALSE);
745f4b3ec61Sdh155122
746f4b3ec61Sdh155122 /* Note: only return B_TRUE if it's "true" */
747f4b3ec61Sdh155122 if (strcmp((char *)allow_excl, DTD_ENTITY_TRUE) == 0)
748f4b3ec61Sdh155122 ret = B_TRUE;
749f4b3ec61Sdh155122 else
750f4b3ec61Sdh155122 ret = B_FALSE;
751f4b3ec61Sdh155122
752f4b3ec61Sdh155122 xmlFree(allow_excl);
753f4b3ec61Sdh155122
754f4b3ec61Sdh155122 return (ret);
755f4b3ec61Sdh155122 }
756f4b3ec61Sdh155122
7579acbbeafSnn35248 /*
7589acbbeafSnn35248 * Iterate over brand privileges
7599acbbeafSnn35248 *
7609acbbeafSnn35248 * Walks the brand config, searching for <privilege> elements, calling the
7619acbbeafSnn35248 * specified callback for each. Returns 0 on success, or -1 on failure.
7629acbbeafSnn35248 */
7639acbbeafSnn35248 int
brand_config_iter_privilege(brand_handle_t bh,int (* func)(void *,priv_iter_t *),void * data)764bf1d7e28Sdh155122 brand_config_iter_privilege(brand_handle_t bh,
765bf1d7e28Sdh155122 int (*func)(void *, priv_iter_t *), void *data)
7669acbbeafSnn35248 {
767123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
7689acbbeafSnn35248 xmlNodePtr node;
769bf1d7e28Sdh155122 xmlChar *name, *set, *iptype;
770bf1d7e28Sdh155122 priv_iter_t priv_iter;
7719acbbeafSnn35248 int ret;
7729acbbeafSnn35248
7739acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
7749acbbeafSnn35248 return (-1);
7759acbbeafSnn35248
7769acbbeafSnn35248 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
7779acbbeafSnn35248
7789acbbeafSnn35248 if (xmlStrcmp(node->name, DTD_ELEM_PRIVILEGE) != 0)
7799acbbeafSnn35248 continue;
7809acbbeafSnn35248
7819acbbeafSnn35248 name = xmlGetProp(node, DTD_ATTR_NAME);
7829acbbeafSnn35248 set = xmlGetProp(node, DTD_ATTR_SET);
783bf1d7e28Sdh155122 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
7849acbbeafSnn35248
785bf1d7e28Sdh155122 if (name == NULL || set == NULL || iptype == NULL) {
7869acbbeafSnn35248 if (name != NULL)
7879acbbeafSnn35248 xmlFree(name);
7889acbbeafSnn35248 if (set != NULL)
7899acbbeafSnn35248 xmlFree(set);
790bf1d7e28Sdh155122 if (iptype != NULL)
791bf1d7e28Sdh155122 xmlFree(iptype);
7929acbbeafSnn35248 return (-1);
7939acbbeafSnn35248 }
7949acbbeafSnn35248
795bf1d7e28Sdh155122 priv_iter.pi_name = (char *)name;
796bf1d7e28Sdh155122 priv_iter.pi_set = (char *)set;
797bf1d7e28Sdh155122 priv_iter.pi_iptype = (char *)iptype;
798bf1d7e28Sdh155122
799bf1d7e28Sdh155122 ret = func(data, &priv_iter);
8009acbbeafSnn35248
8019acbbeafSnn35248 xmlFree(name);
8029acbbeafSnn35248 xmlFree(set);
803bf1d7e28Sdh155122 xmlFree(iptype);
8049acbbeafSnn35248
8059acbbeafSnn35248 if (ret != 0)
8069acbbeafSnn35248 return (-1);
8079acbbeafSnn35248 }
8089acbbeafSnn35248
8099acbbeafSnn35248 return (0);
8109acbbeafSnn35248 }
8119acbbeafSnn35248
8129acbbeafSnn35248 static int
i_brand_platform_iter_mounts(struct brand_handle * bhp,const char * zonepath,int (* func)(void *,const char *,const char *,const char *,const char *),void * data,const xmlChar * mount_type)813ff17c8bfSgjelinek i_brand_platform_iter_mounts(struct brand_handle *bhp, const char *zonepath,
8149acbbeafSnn35248 int (*func)(void *, const char *, const char *, const char *,
8159acbbeafSnn35248 const char *), void *data, const xmlChar *mount_type)
8169acbbeafSnn35248 {
8179acbbeafSnn35248 xmlNodePtr node;
8189acbbeafSnn35248 xmlChar *special, *dir, *type, *opt;
8199acbbeafSnn35248 char special_exp[MAXPATHLEN];
8209acbbeafSnn35248 char opt_exp[MAXPATHLEN];
8219acbbeafSnn35248 int ret;
8229acbbeafSnn35248
8239acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
8249acbbeafSnn35248 return (-1);
8259acbbeafSnn35248
8269acbbeafSnn35248 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
8279acbbeafSnn35248
8289acbbeafSnn35248 if (xmlStrcmp(node->name, mount_type) != 0)
8299acbbeafSnn35248 continue;
8309acbbeafSnn35248
8319acbbeafSnn35248 special = xmlGetProp(node, DTD_ATTR_SPECIAL);
8329acbbeafSnn35248 dir = xmlGetProp(node, DTD_ATTR_DIRECTORY);
8339acbbeafSnn35248 type = xmlGetProp(node, DTD_ATTR_TYPE);
8349acbbeafSnn35248 opt = xmlGetProp(node, DTD_ATTR_OPT);
8359acbbeafSnn35248 if ((special == NULL) || (dir == NULL) || (type == NULL) ||
8369acbbeafSnn35248 (opt == NULL)) {
8379acbbeafSnn35248 ret = -1;
8389acbbeafSnn35248 goto next;
8399acbbeafSnn35248 }
8409acbbeafSnn35248
8419acbbeafSnn35248 /* Substitute token values as needed. */
8429acbbeafSnn35248 if ((ret = i_substitute_tokens((char *)special,
8439acbbeafSnn35248 special_exp, sizeof (special_exp),
844ff17c8bfSgjelinek NULL, zonepath, NULL, NULL)) != 0)
8459acbbeafSnn35248 goto next;
8469acbbeafSnn35248
8479acbbeafSnn35248 /* opt might not be defined */
8489acbbeafSnn35248 if (strlen((const char *)opt) == 0) {
8499acbbeafSnn35248 xmlFree(opt);
8509acbbeafSnn35248 opt = NULL;
8519acbbeafSnn35248 } else {
8529acbbeafSnn35248 if ((ret = i_substitute_tokens((char *)opt,
8539acbbeafSnn35248 opt_exp, sizeof (opt_exp),
854ff17c8bfSgjelinek NULL, zonepath, NULL, NULL)) != 0)
8559acbbeafSnn35248 goto next;
8569acbbeafSnn35248 }
8579acbbeafSnn35248
8589acbbeafSnn35248 ret = func(data, (char *)special_exp, (char *)dir,
8599acbbeafSnn35248 (char *)type, ((opt != NULL) ? opt_exp : NULL));
8609acbbeafSnn35248
8619acbbeafSnn35248 next:
8629acbbeafSnn35248 if (special != NULL)
8639acbbeafSnn35248 xmlFree(special);
8649acbbeafSnn35248 if (dir != NULL)
8659acbbeafSnn35248 xmlFree(dir);
8669acbbeafSnn35248 if (type != NULL)
8679acbbeafSnn35248 xmlFree(type);
8689acbbeafSnn35248 if (opt != NULL)
8699acbbeafSnn35248 xmlFree(opt);
8709acbbeafSnn35248 if (ret != 0)
8719acbbeafSnn35248 return (-1);
8729acbbeafSnn35248 }
8739acbbeafSnn35248 return (0);
8749acbbeafSnn35248 }
8759acbbeafSnn35248
8769acbbeafSnn35248
8779acbbeafSnn35248 /*
8789acbbeafSnn35248 * Iterate over global platform filesystems
8799acbbeafSnn35248 *
8809acbbeafSnn35248 * Walks the platform, searching for <global_mount> elements, calling the
8819acbbeafSnn35248 * specified callback for each. Returns 0 on success, or -1 on failure.
8829acbbeafSnn35248 *
8839acbbeafSnn35248 * Perform the following substitutions as necessary:
8849acbbeafSnn35248 *
885ff17c8bfSgjelinek * %R Zonepath of zone
8869acbbeafSnn35248 */
8879acbbeafSnn35248 int
brand_platform_iter_gmounts(brand_handle_t bh,const char * zonepath,int (* func)(void *,const char *,const char *,const char *,const char *),void * data)888ff17c8bfSgjelinek brand_platform_iter_gmounts(brand_handle_t bh, const char *zonepath,
8899acbbeafSnn35248 int (*func)(void *, const char *, const char *, const char *,
8909acbbeafSnn35248 const char *), void *data)
8919acbbeafSnn35248 {
892123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
893ff17c8bfSgjelinek return (i_brand_platform_iter_mounts(bhp, zonepath, func, data,
8949acbbeafSnn35248 DTD_ELEM_GLOBAL_MOUNT));
8959acbbeafSnn35248 }
8969acbbeafSnn35248
8979acbbeafSnn35248 /*
8989acbbeafSnn35248 * Iterate over non-global zone platform filesystems
8999acbbeafSnn35248 *
9009acbbeafSnn35248 * Walks the platform, searching for <mount> elements, calling the
9019acbbeafSnn35248 * specified callback for each. Returns 0 on success, or -1 on failure.
9029acbbeafSnn35248 */
9039acbbeafSnn35248 int
brand_platform_iter_mounts(brand_handle_t bh,int (* func)(void *,const char *,const char *,const char *,const char *),void * data)904123807fbSedp brand_platform_iter_mounts(brand_handle_t bh, int (*func)(void *,
9059acbbeafSnn35248 const char *, const char *, const char *, const char *), void *data)
9069acbbeafSnn35248 {
907123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
9089acbbeafSnn35248 return (i_brand_platform_iter_mounts(bhp, NULL, func, data,
9099acbbeafSnn35248 DTD_ELEM_MOUNT));
9109acbbeafSnn35248 }
9119acbbeafSnn35248
9129acbbeafSnn35248 /*
9139acbbeafSnn35248 * Iterate over platform symlinks
9149acbbeafSnn35248 *
9159acbbeafSnn35248 * Walks the platform, searching for <symlink> elements, calling the
9169acbbeafSnn35248 * specified callback for each. Returns 0 on success, or -1 on failure.
9179acbbeafSnn35248 */
9189acbbeafSnn35248 int
brand_platform_iter_link(brand_handle_t bh,int (* func)(void *,const char *,const char *),void * data)919123807fbSedp brand_platform_iter_link(brand_handle_t bh,
9209acbbeafSnn35248 int (*func)(void *, const char *, const char *), void *data)
9219acbbeafSnn35248 {
922123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
9239acbbeafSnn35248 xmlNodePtr node;
9249acbbeafSnn35248 xmlChar *source, *target;
9259acbbeafSnn35248 int ret;
9269acbbeafSnn35248
9279acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
9289acbbeafSnn35248 return (-1);
9299acbbeafSnn35248
9309acbbeafSnn35248 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
9319acbbeafSnn35248
9329acbbeafSnn35248 if (xmlStrcmp(node->name, DTD_ELEM_SYMLINK) != 0)
9339acbbeafSnn35248 continue;
9349acbbeafSnn35248
9359acbbeafSnn35248 source = xmlGetProp(node, DTD_ATTR_SOURCE);
9369acbbeafSnn35248 target = xmlGetProp(node, DTD_ATTR_TARGET);
9379acbbeafSnn35248
9389acbbeafSnn35248 if (source == NULL || target == NULL) {
9399acbbeafSnn35248 if (source != NULL)
9409acbbeafSnn35248 xmlFree(source);
9419acbbeafSnn35248 if (target != NULL)
9429acbbeafSnn35248 xmlFree(target);
9439acbbeafSnn35248 return (-1);
9449acbbeafSnn35248 }
9459acbbeafSnn35248
9469acbbeafSnn35248 ret = func(data, (char *)source, (char *)target);
9479acbbeafSnn35248
9489acbbeafSnn35248 xmlFree(source);
9499acbbeafSnn35248 xmlFree(target);
9509acbbeafSnn35248
9519acbbeafSnn35248 if (ret != 0)
9529acbbeafSnn35248 return (-1);
9539acbbeafSnn35248 }
9549acbbeafSnn35248
9559acbbeafSnn35248 return (0);
9569acbbeafSnn35248 }
9579acbbeafSnn35248
9589acbbeafSnn35248 /*
9599acbbeafSnn35248 * Iterate over platform devices
9609acbbeafSnn35248 *
9619acbbeafSnn35248 * Walks the platform, searching for <device> elements, calling the
9629acbbeafSnn35248 * specified callback for each. Returns 0 on success, or -1 on failure.
9639acbbeafSnn35248 */
9649acbbeafSnn35248 int
brand_platform_iter_devices(brand_handle_t bh,const char * zonename,int (* func)(void *,const char *,const char *),void * data,const char * curr_iptype)965123807fbSedp brand_platform_iter_devices(brand_handle_t bh, const char *zonename,
966f4b3ec61Sdh155122 int (*func)(void *, const char *, const char *), void *data,
967f4b3ec61Sdh155122 const char *curr_iptype)
9689acbbeafSnn35248 {
969123807fbSedp struct brand_handle *bhp = (struct brand_handle *)bh;
9709acbbeafSnn35248 const char *curr_arch = get_curr_arch();
9719acbbeafSnn35248 xmlNodePtr node;
972f4b3ec61Sdh155122 xmlChar *match, *name, *arch, *iptype;
9739acbbeafSnn35248 char match_exp[MAXPATHLEN];
9749acbbeafSnn35248 boolean_t err = B_FALSE;
9759acbbeafSnn35248 int ret = 0;
9769acbbeafSnn35248
9779acbbeafSnn35248
9789acbbeafSnn35248 assert(bhp != NULL);
9799acbbeafSnn35248 assert(zonename != NULL);
9809acbbeafSnn35248 assert(func != NULL);
981f4b3ec61Sdh155122 assert(curr_iptype != NULL);
9829acbbeafSnn35248
9839acbbeafSnn35248 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
9849acbbeafSnn35248 return (-1);
9859acbbeafSnn35248
9869acbbeafSnn35248 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
9879acbbeafSnn35248
9889acbbeafSnn35248 if (xmlStrcmp(node->name, DTD_ELEM_DEVICE) != 0)
9899acbbeafSnn35248 continue;
9909acbbeafSnn35248
9919acbbeafSnn35248 match = xmlGetProp(node, DTD_ATTR_MATCH);
9929acbbeafSnn35248 name = xmlGetProp(node, DTD_ATTR_NAME);
9939acbbeafSnn35248 arch = xmlGetProp(node, DTD_ATTR_ARCH);
994f4b3ec61Sdh155122 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
995f4b3ec61Sdh155122 if ((match == NULL) || (name == NULL) || (arch == NULL) ||
996f4b3ec61Sdh155122 (iptype == NULL)) {
9979acbbeafSnn35248 err = B_TRUE;
9989acbbeafSnn35248 goto next;
9999acbbeafSnn35248 }
10009acbbeafSnn35248
10019acbbeafSnn35248 /* check if the arch matches */
10029acbbeafSnn35248 if ((strcmp((char *)arch, "all") != 0) &&
10039acbbeafSnn35248 (strcmp((char *)arch, curr_arch) != 0))
10049acbbeafSnn35248 goto next;
10059acbbeafSnn35248
1006f4b3ec61Sdh155122 /* check if the iptype matches */
1007f4b3ec61Sdh155122 if ((strcmp((char *)iptype, "all") != 0) &&
1008f4b3ec61Sdh155122 (strcmp((char *)iptype, curr_iptype) != 0))
1009f4b3ec61Sdh155122 goto next;
1010f4b3ec61Sdh155122
10119acbbeafSnn35248 /* Substitute token values as needed. */
10129acbbeafSnn35248 if ((ret = i_substitute_tokens((char *)match,
10139acbbeafSnn35248 match_exp, sizeof (match_exp),
1014ff17c8bfSgjelinek zonename, NULL, NULL, NULL)) != 0) {
10159acbbeafSnn35248 err = B_TRUE;
10169acbbeafSnn35248 goto next;
10179acbbeafSnn35248 }
10189acbbeafSnn35248
10199acbbeafSnn35248 /* name might not be defined */
10209acbbeafSnn35248 if (strlen((const char *)name) == 0) {
10219acbbeafSnn35248 xmlFree(name);
10229acbbeafSnn35248 name = NULL;
10239acbbeafSnn35248 }
10249acbbeafSnn35248
10259acbbeafSnn35248 /* invoke the callback */
10269acbbeafSnn35248 ret = func(data, (const char *)match_exp, (const char *)name);
10279acbbeafSnn35248
10289acbbeafSnn35248 next:
10299acbbeafSnn35248 if (match != NULL)
10309acbbeafSnn35248 xmlFree(match);
10319acbbeafSnn35248 if (name != NULL)
10329acbbeafSnn35248 xmlFree(name);
10339acbbeafSnn35248 if (arch != NULL)
10349acbbeafSnn35248 xmlFree(arch);
1035f4b3ec61Sdh155122 if (iptype != NULL)
1036f4b3ec61Sdh155122 xmlFree(iptype);
10379acbbeafSnn35248 if (err)
10389acbbeafSnn35248 return (-1);
10399acbbeafSnn35248 if (ret != 0)
10409acbbeafSnn35248 return (-1);
10419acbbeafSnn35248 }
10429acbbeafSnn35248
10439acbbeafSnn35248 return (0);
10449acbbeafSnn35248 }
1045