Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libbrand/common/libbrand.c
+++ new/usr/src/lib/libbrand/common/libbrand.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2015, Joyent, Inc.
25 25 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27
28 28 #include <assert.h>
29 29 #include <dirent.h>
30 30 #include <errno.h>
31 31 #include <fnmatch.h>
32 32 #include <signal.h>
33 33 #include <stdlib.h>
34 34 #include <unistd.h>
35 35 #include <strings.h>
36 36 #include <synch.h>
37 37 #include <sys/brand.h>
38 38 #include <sys/fcntl.h>
39 39 #include <sys/param.h>
40 40 #include <sys/stat.h>
41 41 #include <sys/systeminfo.h>
42 42 #include <sys/types.h>
43 43 #include <thread.h>
44 44 #include <zone.h>
45 45
46 46 #include <libbrand_impl.h>
47 47 #include <libbrand.h>
48 48
49 49 #define DTD_ELEM_ATTACH ((const xmlChar *) "attach")
50 50 #define DTD_ELEM_BOOT ((const xmlChar *) "boot")
51 51 #define DTD_ELEM_BRAND ((const xmlChar *) "brand")
52 52 #define DTD_ELEM_CLONE ((const xmlChar *) "clone")
53 53 #define DTD_ELEM_COMMENT ((const xmlChar *) "comment")
54 54 #define DTD_ELEM_DETACH ((const xmlChar *) "detach")
55 55 #define DTD_ELEM_DEVICE ((const xmlChar *) "device")
56 56 #define DTD_ELEM_GLOBAL_MOUNT ((const xmlChar *) "global_mount")
57 57 #define DTD_ELEM_HALT ((const xmlChar *) "halt")
58 58 #define DTD_ELEM_INITNAME ((const xmlChar *) "initname")
59 59 #define DTD_ELEM_INSTALL ((const xmlChar *) "install")
60 60 #define DTD_ELEM_INSTALLOPTS ((const xmlChar *) "installopts")
61 61 #define DTD_ELEM_LOGIN_CMD ((const xmlChar *) "login_cmd")
62 62 #define DTD_ELEM_FORCELOGIN_CMD ((const xmlChar *) "forcedlogin_cmd")
63 63 #define DTD_ELEM_MODNAME ((const xmlChar *) "modname")
64 64 #define DTD_ELEM_MOUNT ((const xmlChar *) "mount")
65 65 #define DTD_ELEM_RESTARTINIT ((const xmlChar *) "restartinit")
66 66 #define DTD_ELEM_POSTATTACH ((const xmlChar *) "postattach")
67 67 #define DTD_ELEM_POSTCLONE ((const xmlChar *) "postclone")
68 68 #define DTD_ELEM_POSTINSTALL ((const xmlChar *) "postinstall")
69 69 #define DTD_ELEM_POSTSNAP ((const xmlChar *) "postsnap")
70 70 #define DTD_ELEM_POSTSTATECHG ((const xmlChar *) "poststatechange")
71 71 #define DTD_ELEM_PREDETACH ((const xmlChar *) "predetach")
72 72 #define DTD_ELEM_PRESNAP ((const xmlChar *) "presnap")
73 73 #define DTD_ELEM_PRESTATECHG ((const xmlChar *) "prestatechange")
74 74 #define DTD_ELEM_PREUNINSTALL ((const xmlChar *) "preuninstall")
75 75 #define DTD_ELEM_PRIVILEGE ((const xmlChar *) "privilege")
76 76 #define DTD_ELEM_QUERY ((const xmlChar *) "query")
77 77 #define DTD_ELEM_SHUTDOWN ((const xmlChar *) "shutdown")
78 78 #define DTD_ELEM_SYMLINK ((const xmlChar *) "symlink")
79 79 #define DTD_ELEM_SYSBOOT ((const xmlChar *) "sysboot")
80 80 #define DTD_ELEM_UNINSTALL ((const xmlChar *) "uninstall")
81 81 #define DTD_ELEM_USER_CMD ((const xmlChar *) "user_cmd")
82 82 #define DTD_ELEM_VALIDSNAP ((const xmlChar *) "validatesnap")
83 83 #define DTD_ELEM_VERIFY_CFG ((const xmlChar *) "verify_cfg")
84 84 #define DTD_ELEM_VERIFY_ADM ((const xmlChar *) "verify_adm")
85 85
86 86 #define DTD_ATTR_ALLOWEXCL ((const xmlChar *) "allow-exclusive-ip")
87 87 #define DTD_ATTR_ARCH ((const xmlChar *) "arch")
88 88 #define DTD_ATTR_DIRECTORY ((const xmlChar *) "directory")
89 89 #define DTD_ATTR_IPTYPE ((const xmlChar *) "ip-type")
90 90 #define DTD_ATTR_MATCH ((const xmlChar *) "match")
91 91 #define DTD_ATTR_MODE ((const xmlChar *) "mode")
92 92 #define DTD_ATTR_NAME ((const xmlChar *) "name")
93 93 #define DTD_ATTR_OPT ((const xmlChar *) "opt")
94 94 #define DTD_ATTR_PATH ((const xmlChar *) "path")
95 95 #define DTD_ATTR_SET ((const xmlChar *) "set")
96 96 #define DTD_ATTR_SOURCE ((const xmlChar *) "source")
97 97 #define DTD_ATTR_SPECIAL ((const xmlChar *) "special")
98 98 #define DTD_ATTR_TARGET ((const xmlChar *) "target")
99 99 #define DTD_ATTR_TYPE ((const xmlChar *) "type")
100 100
101 101 #define DTD_ENTITY_TRUE "true"
102 102
103 103 static volatile boolean_t libbrand_initialized = B_FALSE;
104 104 static char i_curr_arch[MAXNAMELEN];
105 105 static char i_curr_zone[ZONENAME_MAX];
106 106
107 107 /*ARGSUSED*/
108 108 static void
109 109 brand_error_func(void *ctx, const char *msg, ...)
110 110 {
111 111 /*
112 112 * Ignore error messages from libxml
113 113 */
114 114 }
115 115
116 116 static boolean_t
117 117 libbrand_initialize()
118 118 {
119 119 static mutex_t initialize_lock = DEFAULTMUTEX;
120 120
121 121 (void) mutex_lock(&initialize_lock);
122 122
123 123 if (libbrand_initialized) {
124 124 (void) mutex_unlock(&initialize_lock);
125 125 return (B_TRUE);
126 126 }
127 127
128 128 if (sysinfo(SI_ARCHITECTURE, i_curr_arch, sizeof (i_curr_arch)) < 0) {
129 129 (void) mutex_unlock(&initialize_lock);
130 130 return (B_FALSE);
131 131 }
132 132
133 133 if (getzonenamebyid(getzoneid(), i_curr_zone,
134 134 sizeof (i_curr_zone)) < 0) {
135 135 (void) mutex_unlock(&initialize_lock);
136 136 return (B_FALSE);
137 137 }
138 138
139 139 /*
140 140 * Note that here we're initializing per-process libxml2
141 141 * state. By doing so we're implicitly assuming that
142 142 * no other code in this process is also trying to
143 143 * use libxml2. But in most case we know this not to
144 144 * be true since we're almost always used in conjunction
145 145 * with libzonecfg, which also uses libxml2. Lucky for
146 146 * us, libzonecfg initializes libxml2 to essentially
147 147 * the same defaults as we're using below.
148 148 */
149 149 (void) xmlLineNumbersDefault(1);
150 150 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
151 151 xmlDoValidityCheckingDefaultValue = 1;
152 152 (void) xmlKeepBlanksDefault(0);
153 153 xmlGetWarningsDefaultValue = 0;
154 154 xmlSetGenericErrorFunc(NULL, brand_error_func);
155 155
156 156 libbrand_initialized = B_TRUE;
157 157 (void) mutex_unlock(&initialize_lock);
158 158 return (B_TRUE);
159 159 }
160 160
161 161 static const char *
162 162 get_curr_arch(void)
163 163 {
164 164 if (!libbrand_initialize())
165 165 return (NULL);
166 166
167 167 return (i_curr_arch);
168 168 }
169 169
170 170 static const char *
171 171 get_curr_zone(void)
172 172 {
173 173 if (!libbrand_initialize())
174 174 return (NULL);
175 175
176 176 return (i_curr_zone);
177 177 }
178 178
179 179 /*
180 180 * Internal function to open an XML file
181 181 *
182 182 * Returns the XML doc pointer, or NULL on failure. It will validate the
183 183 * document, as well as removing any comments from the document structure.
184 184 */
185 185 static xmlDocPtr
186 186 open_xml_file(const char *file)
187 187 {
188 188 xmlDocPtr doc;
189 189 xmlValidCtxtPtr cvp;
190 190 int valid;
191 191
192 192 if (!libbrand_initialize())
193 193 return (NULL);
194 194
195 195 /*
196 196 * Parse the file
197 197 */
198 198 if ((doc = xmlParseFile(file)) == NULL)
199 199 return (NULL);
200 200
201 201 /*
202 202 * Validate the file
203 203 */
204 204 if ((cvp = xmlNewValidCtxt()) == NULL) {
205 205 xmlFreeDoc(doc);
206 206 return (NULL);
207 207 }
208 208 cvp->error = brand_error_func;
209 209 cvp->warning = brand_error_func;
210 210 valid = xmlValidateDocument(cvp, doc);
211 211 xmlFreeValidCtxt(cvp);
212 212 if (valid == 0) {
213 213 xmlFreeDoc(doc);
214 214 return (NULL);
215 215 }
216 216
217 217 return (doc);
218 218 }
219 219 /*
220 220 * Open a handle to the named brand.
221 221 *
222 222 * Returns a handle to the named brand, which is used for all subsequent brand
223 223 * interaction, or NULL if unable to open or initialize the brand.
224 224 */
225 225 brand_handle_t
226 226 brand_open(const char *name)
227 227 {
228 228 struct brand_handle *bhp;
229 229 char path[MAXPATHLEN];
230 230 xmlNodePtr node;
231 231 xmlChar *property;
232 232 struct stat statbuf;
233 233
234 234 /*
235 235 * Make sure brand name isn't too long
236 236 */
237 237 if (strlen(name) >= MAXNAMELEN)
238 238 return (NULL);
239 239
240 240 /*
241 241 * Check that the brand exists
242 242 */
243 243 (void) snprintf(path, sizeof (path), "%s/%s", BRAND_DIR, name);
244 244
245 245 if (stat(path, &statbuf) != 0)
246 246 return (NULL);
247 247
248 248 /*
249 249 * Allocate brand handle
250 250 */
251 251 if ((bhp = malloc(sizeof (struct brand_handle))) == NULL)
252 252 return (NULL);
253 253 bzero(bhp, sizeof (struct brand_handle));
254 254
255 255 (void) strcpy(bhp->bh_name, name);
256 256
257 257 /*
258 258 * Open the configuration file
259 259 */
260 260 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
261 261 BRAND_CONFIG);
262 262 if ((bhp->bh_config = open_xml_file(path)) == NULL) {
263 263 brand_close((brand_handle_t)bhp);
264 264 return (NULL);
265 265 }
266 266
267 267 /*
268 268 * Verify that the name of the brand matches the directory in which it
269 269 * is installed.
270 270 */
271 271 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL) {
272 272 brand_close((brand_handle_t)bhp);
273 273 return (NULL);
274 274 }
275 275
276 276 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0) {
277 277 brand_close((brand_handle_t)bhp);
278 278 return (NULL);
279 279 }
280 280
281 281 if ((property = xmlGetProp(node, DTD_ATTR_NAME)) == NULL) {
282 282 brand_close((brand_handle_t)bhp);
283 283 return (NULL);
284 284 }
285 285
286 286 if (strcmp((char *)property, name) != 0) {
287 287 xmlFree(property);
288 288 brand_close((brand_handle_t)bhp);
289 289 return (NULL);
290 290 }
291 291 xmlFree(property);
292 292
293 293 /*
294 294 * Open handle to platform configuration file.
295 295 */
296 296 (void) snprintf(path, sizeof (path), "%s/%s/%s", BRAND_DIR, name,
297 297 BRAND_PLATFORM);
298 298 if ((bhp->bh_platform = open_xml_file(path)) == NULL) {
299 299 brand_close((brand_handle_t)bhp);
300 300 return (NULL);
301 301 }
302 302
303 303 return ((brand_handle_t)bhp);
304 304 }
305 305
306 306 /*
307 307 * Closes the given brand handle
308 308 */
309 309 void
310 310 brand_close(brand_handle_t bh)
311 311 {
312 312 struct brand_handle *bhp = (struct brand_handle *)bh;
313 313 if (bhp->bh_platform != NULL)
314 314 xmlFreeDoc(bhp->bh_platform);
315 315 if (bhp->bh_config != NULL)
|
↓ open down ↓ |
315 lines elided |
↑ open up ↑ |
316 316 xmlFreeDoc(bhp->bh_config);
317 317 free(bhp);
318 318 }
319 319
320 320 static int
321 321 i_substitute_tokens(const char *sbuf, char *dbuf, int dbuf_size,
322 322 const char *zonename, const char *zonepath, const char *username,
323 323 const char *curr_zone)
324 324 {
325 325 int dst, src;
326 - static char *env_pool = NULL;
327 326
328 327 /*
329 328 * Walk through the characters, substituting values as needed.
330 329 */
331 330 dbuf[0] = '\0';
332 331 dst = 0;
333 332 for (src = 0; src < strlen((char *)sbuf) && dst < dbuf_size; src++) {
334 333 if (sbuf[src] != '%') {
335 334 dbuf[dst++] = sbuf[src];
336 335 continue;
337 336 }
338 337
339 338 switch (sbuf[++src]) {
340 339 case '%':
341 340 dst += strlcpy(dbuf + dst, "%", dbuf_size - dst);
342 341 break;
343 - case 'P':
344 - if (env_pool == NULL)
345 - env_pool = getenv("_ZONEADMD_ZPOOL");
346 - if (env_pool == NULL)
347 - break;
348 - dst += strlcpy(dbuf + dst, env_pool, dbuf_size - dst);
349 - break;
350 342 case 'R':
351 343 if (zonepath == NULL)
352 344 break;
353 345 dst += strlcpy(dbuf + dst, zonepath, dbuf_size - dst);
354 346 break;
355 347 case 'u':
356 348 if (username == NULL)
357 349 break;
358 350 dst += strlcpy(dbuf + dst, username, dbuf_size - dst);
359 351 break;
360 352 case 'Z':
361 353 if (curr_zone == NULL)
362 354 break;
363 355 /* name of the zone we're running in */
364 356 dst += strlcpy(dbuf + dst, curr_zone, dbuf_size - dst);
365 357 break;
366 358 case 'z':
367 359 /* name of the zone we're operating on */
368 360 if (zonename == NULL)
369 361 break;
370 362 dst += strlcpy(dbuf + dst, zonename, dbuf_size - dst);
371 363 break;
372 364 }
373 365 }
374 366
375 367 if (dst >= dbuf_size)
376 368 return (-1);
377 369
378 370 dbuf[dst] = '\0';
379 371 return (0);
380 372 }
381 373
382 374 /*
383 375 * Retrieve the given tag from the brand.
384 376 * Perform the following substitutions as necessary:
385 377 *
386 378 * %% %
387 379 * %u Username
388 380 * %z Name of target zone
389 381 * %Z Name of current zone
390 382 * %R Zonepath of zone
391 383 *
392 384 * Returns 0 on success, -1 on failure.
393 385 */
394 386 static int
395 387 brand_get_value(struct brand_handle *bhp, const char *zonename,
396 388 const char *zonepath, const char *username, const char *curr_zone,
397 389 char *buf, size_t len, const xmlChar *tagname,
398 390 boolean_t substitute, boolean_t optional)
399 391 {
400 392 xmlNodePtr node;
401 393 xmlChar *content;
402 394 int err = 0;
403 395
404 396 /*
405 397 * Retrieve the specified value from the XML doc
406 398 */
407 399 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
408 400 return (-1);
409 401
410 402 if (xmlStrcmp(node->name, DTD_ELEM_BRAND) != 0)
411 403 return (-1);
412 404
413 405 for (node = node->xmlChildrenNode; node != NULL;
414 406 node = node->next) {
415 407 if (xmlStrcmp(node->name, tagname) == 0)
416 408 break;
417 409 }
418 410
419 411 if (node == NULL) {
420 412 if (optional) {
421 413 buf[0] = '\0';
422 414 return (0);
423 415 } else {
424 416 return (-1);
425 417 }
426 418 }
427 419
428 420 if ((content = xmlNodeGetContent(node)) == NULL)
429 421 return (-1);
430 422
431 423 if (strlen((char *)content) == 0) {
432 424 /*
433 425 * If the entry in the config file is empty, check to see
434 426 * whether this is an optional field. If so, we return the
435 427 * empty buffer. If not, we return an error.
436 428 */
437 429 if (optional) {
438 430 buf[0] = '\0';
439 431 } else {
440 432 err = -1;
441 433 }
442 434 } else {
443 435 /* Substitute token values as needed. */
444 436 if (substitute) {
445 437 if (i_substitute_tokens((char *)content, buf, len,
446 438 zonename, zonepath, username, curr_zone) != 0)
447 439 err = -1;
448 440 } else {
449 441 if (strlcpy(buf, (char *)content, len) >= len)
450 442 err = -1;
451 443 }
452 444 }
453 445
454 446 xmlFree(content);
455 447
456 448 return (err);
457 449 }
458 450
459 451 int
460 452 brand_get_attach(brand_handle_t bh, const char *zonename,
461 453 const char *zonepath, char *buf, size_t len)
462 454 {
463 455 struct brand_handle *bhp = (struct brand_handle *)bh;
464 456 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
465 457 buf, len, DTD_ELEM_ATTACH, B_TRUE, B_TRUE));
466 458 }
467 459
468 460 int
469 461 brand_get_boot(brand_handle_t bh, const char *zonename,
470 462 const char *zonepath, char *buf, size_t len)
471 463 {
472 464 struct brand_handle *bhp = (struct brand_handle *)bh;
473 465 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
474 466 buf, len, DTD_ELEM_BOOT, B_TRUE, B_TRUE));
475 467 }
476 468
477 469 int
478 470 brand_get_brandname(brand_handle_t bh, char *buf, size_t len)
479 471 {
480 472 struct brand_handle *bhp = (struct brand_handle *)bh;
481 473 if (len <= strlen(bhp->bh_name))
482 474 return (-1);
483 475
484 476 (void) strcpy(buf, bhp->bh_name);
485 477
486 478 return (0);
487 479 }
488 480
489 481 int
490 482 brand_get_clone(brand_handle_t bh, const char *zonename,
491 483 const char *zonepath, char *buf, size_t len)
492 484 {
493 485 struct brand_handle *bhp = (struct brand_handle *)bh;
494 486 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
495 487 buf, len, DTD_ELEM_CLONE, B_TRUE, B_TRUE));
496 488 }
497 489
498 490 int
499 491 brand_get_detach(brand_handle_t bh, const char *zonename,
500 492 const char *zonepath, char *buf, size_t len)
501 493 {
502 494 struct brand_handle *bhp = (struct brand_handle *)bh;
503 495 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
504 496 buf, len, DTD_ELEM_DETACH, B_TRUE, B_TRUE));
505 497 }
506 498
507 499 int
508 500 brand_get_halt(brand_handle_t bh, const char *zonename,
509 501 const char *zonepath, char *buf, size_t len)
510 502 {
511 503 struct brand_handle *bhp = (struct brand_handle *)bh;
512 504 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
513 505 buf, len, DTD_ELEM_HALT, B_TRUE, B_TRUE));
514 506 }
515 507
516 508 int
517 509 brand_get_shutdown(brand_handle_t bh, const char *zonename,
518 510 const char *zonepath, char *buf, size_t len)
519 511 {
520 512 struct brand_handle *bhp = (struct brand_handle *)bh;
521 513 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
522 514 buf, len, DTD_ELEM_SHUTDOWN, B_TRUE, B_TRUE));
523 515 }
524 516
525 517 int
526 518 brand_get_initname(brand_handle_t bh, char *buf, size_t len)
527 519 {
528 520 struct brand_handle *bhp = (struct brand_handle *)bh;
529 521 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
530 522 buf, len, DTD_ELEM_INITNAME, B_FALSE, B_FALSE));
531 523 }
532 524
533 525 boolean_t
534 526 brand_restartinit(brand_handle_t bh)
535 527 {
536 528 struct brand_handle *bhp = (struct brand_handle *)bh;
537 529 char val[80];
538 530
539 531 if (brand_get_value(bhp, NULL, NULL, NULL, NULL,
540 532 val, sizeof (val), DTD_ELEM_RESTARTINIT, B_FALSE, B_FALSE) != 0)
541 533 return (B_TRUE);
542 534
543 535 if (strcmp(val, "false") == 0)
544 536 return (B_FALSE);
545 537 return (B_TRUE);
546 538 }
547 539
548 540 int
549 541 brand_get_login_cmd(brand_handle_t bh, const char *username,
550 542 char *buf, size_t len)
551 543 {
552 544 struct brand_handle *bhp = (struct brand_handle *)bh;
553 545 const char *curr_zone = get_curr_zone();
554 546 return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
555 547 buf, len, DTD_ELEM_LOGIN_CMD, B_TRUE, B_FALSE));
556 548 }
557 549
558 550 int
559 551 brand_get_forcedlogin_cmd(brand_handle_t bh, const char *username,
560 552 char *buf, size_t len)
561 553 {
562 554 struct brand_handle *bhp = (struct brand_handle *)bh;
563 555 const char *curr_zone = get_curr_zone();
564 556 return (brand_get_value(bhp, NULL, NULL, username, curr_zone,
565 557 buf, len, DTD_ELEM_FORCELOGIN_CMD, B_TRUE, B_FALSE));
566 558 }
567 559
568 560 int
569 561 brand_get_user_cmd(brand_handle_t bh, const char *username,
570 562 char *buf, size_t len)
571 563 {
572 564 struct brand_handle *bhp = (struct brand_handle *)bh;
573 565
574 566 return (brand_get_value(bhp, NULL, NULL, username, NULL,
575 567 buf, len, DTD_ELEM_USER_CMD, B_TRUE, B_FALSE));
576 568 }
577 569
578 570 int
579 571 brand_get_install(brand_handle_t bh, const char *zonename,
580 572 const char *zonepath, char *buf, size_t len)
581 573 {
582 574 struct brand_handle *bhp = (struct brand_handle *)bh;
583 575 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
584 576 buf, len, DTD_ELEM_INSTALL, B_TRUE, B_FALSE));
585 577 }
586 578
587 579 int
588 580 brand_get_installopts(brand_handle_t bh, char *buf, size_t len)
589 581 {
590 582 struct brand_handle *bhp = (struct brand_handle *)bh;
591 583 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
592 584 buf, len, DTD_ELEM_INSTALLOPTS, B_FALSE, B_TRUE));
593 585 }
594 586
595 587 int
596 588 brand_get_modname(brand_handle_t bh, char *buf, size_t len)
597 589 {
598 590 struct brand_handle *bhp = (struct brand_handle *)bh;
599 591 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
600 592 buf, len, DTD_ELEM_MODNAME, B_FALSE, B_TRUE));
601 593 }
602 594
603 595 int
604 596 brand_get_postattach(brand_handle_t bh, const char *zonename,
605 597 const char *zonepath, char *buf, size_t len)
606 598 {
607 599 struct brand_handle *bhp = (struct brand_handle *)bh;
608 600 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
609 601 buf, len, DTD_ELEM_POSTATTACH, B_TRUE, B_TRUE));
610 602 }
611 603
612 604 int
613 605 brand_get_postclone(brand_handle_t bh, const char *zonename,
614 606 const char *zonepath, char *buf, size_t len)
615 607 {
616 608 struct brand_handle *bhp = (struct brand_handle *)bh;
617 609 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
618 610 buf, len, DTD_ELEM_POSTCLONE, B_TRUE, B_TRUE));
619 611 }
620 612
621 613 int
622 614 brand_get_postinstall(brand_handle_t bh, const char *zonename,
623 615 const char *zonepath, char *buf, size_t len)
624 616 {
625 617 struct brand_handle *bhp = (struct brand_handle *)bh;
626 618 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
627 619 buf, len, DTD_ELEM_POSTINSTALL, B_TRUE, B_TRUE));
628 620 }
629 621
630 622 int
631 623 brand_get_postsnap(brand_handle_t bh, const char *zonename,
632 624 const char *zonepath, char *buf, size_t len)
633 625 {
634 626 struct brand_handle *bhp = (struct brand_handle *)bh;
635 627 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
636 628 buf, len, DTD_ELEM_POSTSNAP, B_TRUE, B_TRUE));
637 629 }
638 630
639 631 int
640 632 brand_get_poststatechange(brand_handle_t bh, const char *zonename,
641 633 const char *zonepath, char *buf, size_t len)
642 634 {
643 635 struct brand_handle *bhp = (struct brand_handle *)bh;
644 636 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
645 637 buf, len, DTD_ELEM_POSTSTATECHG, B_TRUE, B_TRUE));
646 638 }
647 639
648 640 int
649 641 brand_get_predetach(brand_handle_t bh, const char *zonename,
650 642 const char *zonepath, char *buf, size_t len)
651 643 {
652 644 struct brand_handle *bhp = (struct brand_handle *)bh;
653 645 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
654 646 buf, len, DTD_ELEM_PREDETACH, B_TRUE, B_TRUE));
655 647 }
656 648
657 649 int
658 650 brand_get_presnap(brand_handle_t bh, const char *zonename,
659 651 const char *zonepath, char *buf, size_t len)
660 652 {
661 653 struct brand_handle *bhp = (struct brand_handle *)bh;
662 654 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
663 655 buf, len, DTD_ELEM_PRESNAP, B_TRUE, B_TRUE));
664 656 }
665 657
666 658 int
667 659 brand_get_prestatechange(brand_handle_t bh, const char *zonename,
668 660 const char *zonepath, char *buf, size_t len)
669 661 {
670 662 struct brand_handle *bhp = (struct brand_handle *)bh;
671 663 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
672 664 buf, len, DTD_ELEM_PRESTATECHG, B_TRUE, B_TRUE));
673 665 }
674 666
675 667 int
676 668 brand_get_preuninstall(brand_handle_t bh, const char *zonename,
677 669 const char *zonepath, char *buf, size_t len)
678 670 {
679 671 struct brand_handle *bhp = (struct brand_handle *)bh;
680 672 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
681 673 buf, len, DTD_ELEM_PREUNINSTALL, B_TRUE, B_TRUE));
682 674 }
683 675
684 676 int
685 677 brand_get_query(brand_handle_t bh, const char *zonename,
686 678 const char *zonepath, char *buf, size_t len)
687 679 {
688 680 struct brand_handle *bhp = (struct brand_handle *)bh;
689 681 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
690 682 buf, len, DTD_ELEM_QUERY, B_TRUE, B_TRUE));
691 683 }
692 684
693 685 int
694 686 brand_get_uninstall(brand_handle_t bh, const char *zonename,
695 687 const char *zonepath, char *buf, size_t len)
696 688 {
697 689 struct brand_handle *bhp = (struct brand_handle *)bh;
698 690 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
699 691 buf, len, DTD_ELEM_UNINSTALL, B_TRUE, B_TRUE));
700 692 }
701 693
702 694 int
703 695 brand_get_validatesnap(brand_handle_t bh, const char *zonename,
704 696 const char *zonepath, char *buf, size_t len)
705 697 {
706 698 struct brand_handle *bhp = (struct brand_handle *)bh;
707 699 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
708 700 buf, len, DTD_ELEM_VALIDSNAP, B_TRUE, B_TRUE));
709 701 }
710 702
711 703 int
712 704 brand_get_verify_cfg(brand_handle_t bh, char *buf, size_t len)
713 705 {
714 706 struct brand_handle *bhp = (struct brand_handle *)bh;
715 707 return (brand_get_value(bhp, NULL, NULL, NULL, NULL,
716 708 buf, len, DTD_ELEM_VERIFY_CFG, B_FALSE, B_TRUE));
717 709 }
718 710
719 711 int
720 712 brand_get_verify_adm(brand_handle_t bh, const char *zonename,
721 713 const char *zonepath, char *buf, size_t len)
722 714 {
723 715 struct brand_handle *bhp = (struct brand_handle *)bh;
724 716 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
725 717 buf, len, DTD_ELEM_VERIFY_ADM, B_TRUE, B_TRUE));
726 718 }
727 719
728 720 int
729 721 brand_get_sysboot(brand_handle_t bh, const char *zonename,
730 722 const char *zonepath, char *buf, size_t len)
731 723 {
732 724 struct brand_handle *bhp = (struct brand_handle *)bh;
733 725 return (brand_get_value(bhp, zonename, zonepath, NULL, NULL,
734 726 buf, len, DTD_ELEM_SYSBOOT, B_TRUE, B_TRUE));
735 727 }
736 728
737 729 boolean_t
738 730 brand_allow_exclusive_ip(brand_handle_t bh)
739 731 {
740 732 struct brand_handle *bhp = (struct brand_handle *)bh;
741 733 xmlNodePtr node;
742 734 xmlChar *allow_excl;
743 735 boolean_t ret;
744 736
745 737 assert(bhp != NULL);
746 738
747 739 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
748 740 return (B_FALSE);
749 741
750 742 allow_excl = xmlGetProp(node, DTD_ATTR_ALLOWEXCL);
751 743 if (allow_excl == NULL)
752 744 return (B_FALSE);
753 745
754 746 /* Note: only return B_TRUE if it's "true" */
755 747 if (strcmp((char *)allow_excl, DTD_ENTITY_TRUE) == 0)
756 748 ret = B_TRUE;
757 749 else
758 750 ret = B_FALSE;
759 751
760 752 xmlFree(allow_excl);
761 753
762 754 return (ret);
763 755 }
764 756
765 757 /*
766 758 * Iterate over brand privileges
767 759 *
768 760 * Walks the brand config, searching for <privilege> elements, calling the
769 761 * specified callback for each. Returns 0 on success, or -1 on failure.
770 762 */
771 763 int
772 764 brand_config_iter_privilege(brand_handle_t bh,
773 765 int (*func)(void *, priv_iter_t *), void *data)
774 766 {
775 767 struct brand_handle *bhp = (struct brand_handle *)bh;
776 768 xmlNodePtr node;
777 769 xmlChar *name, *set, *iptype;
778 770 priv_iter_t priv_iter;
779 771 int ret;
780 772
781 773 if ((node = xmlDocGetRootElement(bhp->bh_config)) == NULL)
782 774 return (-1);
783 775
784 776 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
785 777
786 778 if (xmlStrcmp(node->name, DTD_ELEM_PRIVILEGE) != 0)
787 779 continue;
788 780
789 781 name = xmlGetProp(node, DTD_ATTR_NAME);
790 782 set = xmlGetProp(node, DTD_ATTR_SET);
791 783 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
792 784
793 785 if (name == NULL || set == NULL || iptype == NULL) {
794 786 if (name != NULL)
795 787 xmlFree(name);
796 788 if (set != NULL)
797 789 xmlFree(set);
798 790 if (iptype != NULL)
799 791 xmlFree(iptype);
800 792 return (-1);
801 793 }
802 794
803 795 priv_iter.pi_name = (char *)name;
804 796 priv_iter.pi_set = (char *)set;
805 797 priv_iter.pi_iptype = (char *)iptype;
806 798
807 799 ret = func(data, &priv_iter);
808 800
809 801 xmlFree(name);
810 802 xmlFree(set);
811 803 xmlFree(iptype);
812 804
813 805 if (ret != 0)
814 806 return (-1);
815 807 }
816 808
817 809 return (0);
818 810 }
819 811
820 812 static int
821 813 i_brand_platform_iter_mounts(struct brand_handle *bhp, const char *zonename,
822 814 const char *zonepath, int (*func)(void *, const char *, const char *,
823 815 const char *, const char *), void *data, const xmlChar *mount_type)
824 816 {
825 817 xmlNodePtr node;
826 818 xmlChar *special, *dir, *type, *opt;
827 819 char special_exp[MAXPATHLEN];
828 820 char dir_exp[MAXPATHLEN];
829 821 char opt_exp[MAXPATHLEN];
830 822 int ret;
831 823
832 824 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
833 825 return (-1);
834 826
835 827 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
836 828
837 829 if (xmlStrcmp(node->name, mount_type) != 0)
838 830 continue;
839 831
840 832 special = xmlGetProp(node, DTD_ATTR_SPECIAL);
841 833 dir = xmlGetProp(node, DTD_ATTR_DIRECTORY);
842 834 type = xmlGetProp(node, DTD_ATTR_TYPE);
843 835 opt = xmlGetProp(node, DTD_ATTR_OPT);
844 836 if ((special == NULL) || (dir == NULL) || (type == NULL) ||
845 837 (opt == NULL)) {
846 838 ret = -1;
847 839 goto next;
848 840 }
849 841
850 842 /* Substitute token values as needed. */
851 843 if ((ret = i_substitute_tokens((char *)special,
852 844 special_exp, sizeof (special_exp),
853 845 zonename, zonepath, NULL, NULL)) != 0)
854 846 goto next;
855 847 if ((ret = i_substitute_tokens((char *)dir,
856 848 dir_exp, sizeof (dir_exp),
857 849 zonename, zonepath, NULL, NULL)) != 0)
858 850 goto next;
859 851
860 852 /* opt might not be defined */
861 853 if (strlen((const char *)opt) == 0) {
862 854 xmlFree(opt);
863 855 opt = NULL;
864 856 } else {
865 857 if ((ret = i_substitute_tokens((char *)opt,
866 858 opt_exp, sizeof (opt_exp),
867 859 zonename, zonepath, NULL, NULL)) != 0)
868 860 goto next;
869 861 }
870 862
871 863 ret = func(data, (char *)special_exp, (char *)dir_exp,
872 864 (char *)type, ((opt != NULL) ? opt_exp : NULL));
873 865
874 866 next:
875 867 if (special != NULL)
876 868 xmlFree(special);
877 869 if (dir != NULL)
878 870 xmlFree(dir);
879 871 if (type != NULL)
880 872 xmlFree(type);
881 873 if (opt != NULL)
882 874 xmlFree(opt);
883 875 if (ret != 0)
884 876 return (-1);
885 877 }
886 878 return (0);
887 879 }
888 880
889 881
890 882 /*
891 883 * Iterate over global platform filesystems
892 884 *
893 885 * Walks the platform, searching for <global_mount> elements, calling the
894 886 * specified callback for each. Returns 0 on success, or -1 on failure.
895 887 *
896 888 * Perform the following substitutions as necessary:
897 889 *
898 890 * %R Zonepath of zone
899 891 */
900 892 int
901 893 brand_platform_iter_gmounts(brand_handle_t bh, const char *zonename,
902 894 const char *zonepath, int (*func)(void *, const char *, const char *,
903 895 const char *, const char *), void *data)
904 896 {
905 897 struct brand_handle *bhp = (struct brand_handle *)bh;
906 898 return (i_brand_platform_iter_mounts(bhp, zonename, zonepath, func,
907 899 data, DTD_ELEM_GLOBAL_MOUNT));
908 900 }
909 901
910 902 /*
911 903 * Iterate over non-global zone platform filesystems
912 904 *
913 905 * Walks the platform, searching for <mount> elements, calling the
914 906 * specified callback for each. Returns 0 on success, or -1 on failure.
915 907 */
916 908 int
917 909 brand_platform_iter_mounts(brand_handle_t bh, int (*func)(void *,
918 910 const char *, const char *, const char *, const char *), void *data)
919 911 {
920 912 struct brand_handle *bhp = (struct brand_handle *)bh;
921 913 return (i_brand_platform_iter_mounts(bhp, NULL, NULL, func, data,
922 914 DTD_ELEM_MOUNT));
923 915 }
924 916
925 917 /*
926 918 * Iterate over platform symlinks
927 919 *
928 920 * Walks the platform, searching for <symlink> elements, calling the
929 921 * specified callback for each. Returns 0 on success, or -1 on failure.
930 922 */
931 923 int
932 924 brand_platform_iter_link(brand_handle_t bh,
933 925 int (*func)(void *, const char *, const char *), void *data)
934 926 {
935 927 struct brand_handle *bhp = (struct brand_handle *)bh;
936 928 xmlNodePtr node;
937 929 xmlChar *source, *target;
938 930 int ret;
939 931
940 932 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
941 933 return (-1);
942 934
943 935 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
944 936
945 937 if (xmlStrcmp(node->name, DTD_ELEM_SYMLINK) != 0)
946 938 continue;
947 939
948 940 source = xmlGetProp(node, DTD_ATTR_SOURCE);
949 941 target = xmlGetProp(node, DTD_ATTR_TARGET);
950 942
951 943 if (source == NULL || target == NULL) {
952 944 if (source != NULL)
953 945 xmlFree(source);
954 946 if (target != NULL)
955 947 xmlFree(target);
956 948 return (-1);
957 949 }
958 950
959 951 ret = func(data, (char *)source, (char *)target);
960 952
961 953 xmlFree(source);
962 954 xmlFree(target);
963 955
964 956 if (ret != 0)
965 957 return (-1);
966 958 }
967 959
968 960 return (0);
969 961 }
970 962
971 963 /*
972 964 * Iterate over platform devices
973 965 *
974 966 * Walks the platform, searching for <device> elements, calling the
975 967 * specified callback for each. Returns 0 on success, or -1 on failure.
976 968 */
977 969 int
978 970 brand_platform_iter_devices(brand_handle_t bh, const char *zonename,
979 971 int (*func)(void *, const char *, const char *), void *data,
980 972 const char *curr_iptype)
981 973 {
982 974 struct brand_handle *bhp = (struct brand_handle *)bh;
983 975 const char *curr_arch = get_curr_arch();
984 976 xmlNodePtr node;
985 977 xmlChar *match, *name, *arch, *iptype;
986 978 char match_exp[MAXPATHLEN];
987 979 boolean_t err = B_FALSE;
988 980 int ret = 0;
989 981
990 982
991 983 assert(bhp != NULL);
992 984 assert(zonename != NULL);
993 985 assert(func != NULL);
994 986 assert(curr_iptype != NULL);
995 987
996 988 if ((node = xmlDocGetRootElement(bhp->bh_platform)) == NULL)
997 989 return (-1);
998 990
999 991 for (node = node->xmlChildrenNode; node != NULL; node = node->next) {
1000 992
1001 993 if (xmlStrcmp(node->name, DTD_ELEM_DEVICE) != 0)
1002 994 continue;
1003 995
1004 996 match = xmlGetProp(node, DTD_ATTR_MATCH);
1005 997 name = xmlGetProp(node, DTD_ATTR_NAME);
1006 998 arch = xmlGetProp(node, DTD_ATTR_ARCH);
1007 999 iptype = xmlGetProp(node, DTD_ATTR_IPTYPE);
1008 1000 if ((match == NULL) || (name == NULL) || (arch == NULL) ||
1009 1001 (iptype == NULL)) {
1010 1002 err = B_TRUE;
1011 1003 goto next;
1012 1004 }
1013 1005
1014 1006 /* check if the arch matches */
1015 1007 if ((strcmp((char *)arch, "all") != 0) &&
1016 1008 (strcmp((char *)arch, curr_arch) != 0))
1017 1009 goto next;
1018 1010
1019 1011 /* check if the iptype matches */
1020 1012 if ((strcmp((char *)iptype, "all") != 0) &&
1021 1013 (strcmp((char *)iptype, curr_iptype) != 0))
1022 1014 goto next;
1023 1015
1024 1016 /* Substitute token values as needed. */
1025 1017 if ((ret = i_substitute_tokens((char *)match,
1026 1018 match_exp, sizeof (match_exp),
1027 1019 zonename, NULL, NULL, NULL)) != 0) {
1028 1020 err = B_TRUE;
1029 1021 goto next;
1030 1022 }
1031 1023
1032 1024 /* name might not be defined */
1033 1025 if (strlen((const char *)name) == 0) {
1034 1026 xmlFree(name);
1035 1027 name = NULL;
1036 1028 }
1037 1029
1038 1030 /* invoke the callback */
1039 1031 ret = func(data, (const char *)match_exp, (const char *)name);
1040 1032
1041 1033 next:
1042 1034 if (match != NULL)
1043 1035 xmlFree(match);
1044 1036 if (name != NULL)
1045 1037 xmlFree(name);
1046 1038 if (arch != NULL)
1047 1039 xmlFree(arch);
1048 1040 if (iptype != NULL)
1049 1041 xmlFree(iptype);
1050 1042 if (err)
1051 1043 return (-1);
1052 1044 if (ret != 0)
1053 1045 return (-1);
1054 1046 }
1055 1047
1056 1048 return (0);
1057 1049 }
|
↓ open down ↓ |
698 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX