Print this page
smf: switch to a tri-state for process-security properties true=on,false=off,nil=default
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libscf/common/highlevel.c
+++ new/usr/src/lib/libscf/common/highlevel.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 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26
27 27 /*
28 28 * This file contains high level functions used by multiple utilities.
29 29 */
30 30
31 31 #include "libscf_impl.h"
32 32
33 33 #include <assert.h>
34 34 #include <libuutil.h>
35 35 #include <string.h>
36 +#include <strings.h>
36 37 #include <stdlib.h>
37 38 #include <sys/systeminfo.h>
38 39 #include <sys/uadmin.h>
39 40 #include <sys/utsname.h>
40 41 #include <sys/secflags.h>
41 42
42 43 #ifdef __x86
43 44 #include <smbios.h>
44 45
45 46 /*
46 47 * Check whether the platform is on the fastreboot_blacklist.
47 48 * Return 1 if the platform has been blacklisted, 0 otherwise.
48 49 */
49 50 static int
50 51 scf_is_fb_blacklisted(void)
51 52 {
52 53 smbios_hdl_t *shp;
53 54 smbios_system_t sys;
54 55 smbios_info_t info;
55 56
56 57 id_t id;
57 58 int err;
58 59 int i;
59 60
60 61 scf_simple_prop_t *prop = NULL;
61 62 ssize_t numvals;
62 63 char *platform_name;
63 64
64 65 int blacklisted = 0;
65 66
66 67 /*
67 68 * If there's no SMBIOS, assume it's blacklisted.
68 69 */
69 70 if ((shp = smbios_open(NULL, SMB_VERSION, 0, &err)) == NULL)
70 71 return (1);
71 72
72 73 /*
73 74 * If we can't read system info, assume it's blacklisted.
74 75 */
75 76 if ((id = smbios_info_system(shp, &sys)) == SMB_ERR ||
76 77 smbios_info_common(shp, id, &info) == SMB_ERR) {
77 78 blacklisted = 1;
78 79 goto fb_out;
79 80 }
80 81
81 82 /*
82 83 * If we can't read the "platforms" property from property group
83 84 * BOOT_CONFIG_PG_FBBLACKLIST, assume no platforms have
84 85 * been blacklisted.
85 86 */
86 87 if ((prop = scf_simple_prop_get(NULL, FMRI_BOOT_CONFIG,
87 88 BOOT_CONFIG_PG_FBBLACKLIST, "platforms")) == NULL)
88 89 goto fb_out;
89 90
90 91 numvals = scf_simple_prop_numvalues(prop);
91 92
92 93 for (i = 0; i < numvals; i++) {
93 94 platform_name = scf_simple_prop_next_astring(prop);
94 95 if (platform_name == NULL)
95 96 break;
96 97 if (strcmp(platform_name, info.smbi_product) == 0) {
97 98 blacklisted = 1;
98 99 break;
99 100 }
100 101 }
101 102
102 103 fb_out:
103 104 smbios_close(shp);
104 105 scf_simple_prop_free(prop);
105 106
106 107 return (blacklisted);
107 108 }
108 109
109 110 /*
110 111 * Add or get a property group given an FMRI.
111 112 * Return SCF_SUCCESS on success, SCF_FAILED on failure.
112 113 */
113 114 static int
114 115 scf_fmri_pg_get_or_add(const char *fmri, const char *pgname,
115 116 const char *pgtype, uint32_t pgflags, int add)
116 117 {
117 118 scf_handle_t *handle = NULL;
118 119 scf_instance_t *inst = NULL;
119 120 int rc = SCF_FAILED;
120 121 int error;
121 122
122 123 if ((handle = scf_handle_create(SCF_VERSION)) == NULL ||
123 124 scf_handle_bind(handle) != 0 ||
124 125 (inst = scf_instance_create(handle)) == NULL ||
125 126 scf_handle_decode_fmri(handle, fmri, NULL, NULL,
126 127 inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) != SCF_SUCCESS)
127 128 goto scferror;
128 129
129 130 if (add) {
130 131 rc = scf_instance_add_pg(inst, pgname, pgtype, pgflags, NULL);
131 132 /*
132 133 * If the property group already exists, return SCF_SUCCESS.
133 134 */
134 135 if (rc != SCF_SUCCESS && scf_error() == SCF_ERROR_EXISTS)
135 136 rc = SCF_SUCCESS;
136 137 } else {
137 138 rc = scf_instance_get_pg(inst, pgname, NULL);
138 139 }
139 140
140 141 scferror:
141 142 if (rc != SCF_SUCCESS)
142 143 error = scf_error();
143 144
144 145 scf_instance_destroy(inst);
145 146 if (handle)
146 147 (void) scf_handle_unbind(handle);
147 148 scf_handle_destroy(handle);
148 149
149 150 if (rc != SCF_SUCCESS)
150 151 (void) scf_set_error(error);
151 152
152 153 return (rc);
153 154 }
154 155 #endif /* __x86 */
155 156
156 157 /*
157 158 * Get config properties from svc:/system/boot-config:default.
158 159 * It prints errors with uu_warn().
159 160 */
160 161 void
161 162 scf_get_boot_config(uint8_t *boot_config)
162 163 {
163 164 uint64_t ret = 0;
164 165
165 166 assert(boot_config);
166 167 *boot_config = 0;
167 168
168 169 {
169 170 /*
170 171 * Property vector for BOOT_CONFIG_PG_PARAMS property group.
171 172 */
172 173 scf_propvec_t ua_boot_config[] = {
173 174 { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
174 175 UA_FASTREBOOT_DEFAULT },
175 176 { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
176 177 UA_FASTREBOOT_ONPANIC },
177 178 { NULL }
178 179 };
179 180 scf_propvec_t *prop;
180 181
181 182 for (prop = ua_boot_config; prop->pv_prop != NULL; prop++)
182 183 prop->pv_ptr = &ret;
183 184 prop = NULL;
184 185 if (scf_read_propvec(FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_PARAMS,
185 186 B_TRUE, ua_boot_config, &prop) != SCF_FAILED) {
186 187
187 188 #ifdef __x86
188 189 /*
189 190 * Unset both flags if the platform has been
190 191 * blacklisted.
191 192 */
192 193 if (scf_is_fb_blacklisted())
193 194 return;
194 195 #endif /* __x86 */
195 196 *boot_config = (uint8_t)ret;
196 197 return;
197 198 }
198 199 #if defined(FASTREBOOT_DEBUG)
199 200 if (prop != NULL) {
200 201 (void) uu_warn("Service %s property '%s/%s' "
201 202 "not found.\n", FMRI_BOOT_CONFIG,
202 203 BOOT_CONFIG_PG_PARAMS, prop->pv_prop);
203 204 } else {
204 205 (void) uu_warn("Unable to read service %s "
205 206 "property '%s': %s\n", FMRI_BOOT_CONFIG,
206 207 BOOT_CONFIG_PG_PARAMS, scf_strerror(scf_error()));
207 208 }
208 209 #endif /* FASTREBOOT_DEBUG */
209 210 }
210 211 }
211 212
212 213 /*
213 214 * Get or set properties in non-persistent "config_ovr" property group
214 215 * in svc:/system/boot-config:default.
215 216 * It prints errors with uu_warn().
216 217 */
217 218 /*ARGSUSED*/
218 219 static int
219 220 scf_getset_boot_config_ovr(int set, uint8_t *boot_config_ovr)
220 221 {
221 222 int rc = SCF_SUCCESS;
222 223
223 224 assert(boot_config_ovr);
224 225
225 226 #ifndef __x86
226 227 return (rc);
227 228 #else
228 229 {
229 230 /*
230 231 * Property vector for BOOT_CONFIG_PG_OVR property group.
231 232 */
232 233 scf_propvec_t ua_boot_config_ovr[] = {
233 234 { FASTREBOOT_DEFAULT, NULL, SCF_TYPE_BOOLEAN, NULL,
234 235 UA_FASTREBOOT_DEFAULT },
235 236 { FASTREBOOT_ONPANIC, NULL, SCF_TYPE_BOOLEAN, NULL,
236 237 UA_FASTREBOOT_ONPANIC },
237 238 { NULL }
238 239 };
239 240 scf_propvec_t *prop;
240 241
241 242 rc = scf_fmri_pg_get_or_add(FMRI_BOOT_CONFIG,
242 243 BOOT_CONFIG_PG_OVR, SCF_GROUP_APPLICATION,
243 244 SCF_PG_FLAG_NONPERSISTENT, set);
244 245
245 246 if (rc != SCF_SUCCESS) {
246 247 #if defined(FASTREBOOT_DEBUG)
247 248 if (set)
248 249 (void) uu_warn("Unable to add service %s "
249 250 "property group '%s'\n",
250 251 FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR);
251 252 #endif /* FASTREBOOT_DEBUG */
252 253 return (rc);
253 254 }
254 255
255 256 for (prop = ua_boot_config_ovr; prop->pv_prop != NULL; prop++)
256 257 prop->pv_ptr = boot_config_ovr;
257 258 prop = NULL;
258 259
259 260 if (set)
260 261 rc = scf_write_propvec(FMRI_BOOT_CONFIG,
261 262 BOOT_CONFIG_PG_OVR, ua_boot_config_ovr, &prop);
262 263 else
263 264 rc = scf_read_propvec(FMRI_BOOT_CONFIG,
264 265 BOOT_CONFIG_PG_OVR, B_FALSE, ua_boot_config_ovr,
265 266 &prop);
266 267
267 268 #if defined(FASTREBOOT_DEBUG)
268 269 if (rc != SCF_SUCCESS) {
269 270 if (prop != NULL) {
270 271 (void) uu_warn("Service %s property '%s/%s' "
271 272 "not found.\n", FMRI_BOOT_CONFIG,
272 273 BOOT_CONFIG_PG_OVR, prop->pv_prop);
273 274 } else {
274 275 (void) uu_warn("Unable to %s service %s "
275 276 "property '%s': %s\n", set ? "set" : "get",
276 277 FMRI_BOOT_CONFIG, BOOT_CONFIG_PG_OVR,
277 278 scf_strerror(scf_error()));
278 279 }
279 280 }
280 281 #endif /* FASTREBOOT_DEBUG */
281 282
282 283 if (set)
283 284 (void) smf_refresh_instance(FMRI_BOOT_CONFIG);
284 285
285 286 return (rc);
286 287
287 288 }
288 289 #endif /* __x86 */
289 290 }
290 291
291 292 /*
292 293 * Get values of properties in non-persistent "config_ovr" property group.
293 294 */
294 295 void
295 296 scf_get_boot_config_ovr(uint8_t *boot_config_ovr)
296 297 {
297 298 (void) scf_getset_boot_config_ovr(B_FALSE, boot_config_ovr);
298 299 }
299 300
300 301 /*
301 302 * Set value of "config_ovr/fastreboot_default".
302 303 */
303 304 int
304 305 scf_fastreboot_default_set_transient(boolean_t value)
305 306 {
306 307 uint8_t boot_config_ovr = 0;
307 308
308 309 if (value == B_TRUE)
309 310 boot_config_ovr = UA_FASTREBOOT_DEFAULT | UA_FASTREBOOT_ONPANIC;
310 311
311 312 return (scf_getset_boot_config_ovr(B_TRUE, &boot_config_ovr));
312 313 }
313 314
314 315 /*
315 316 * Check whether Fast Reboot is the default operating mode.
316 317 * Return 0 if
317 318 * 1. the platform is xVM
318 319 * or
319 320 * 2. svc:/system/boot-config:default service doesn't exist,
320 321 * or
321 322 * 3. property "config/fastreboot_default" doesn't exist,
322 323 * or
323 324 * 4. value of property "config/fastreboot_default" is set to "false"
324 325 * and "config_ovr/fastreboot_default" is not set to "true",
325 326 * or
326 327 * 5. the platform has been blacklisted.
327 328 * or
328 329 * 6. value of property "config_ovr/fastreboot_default" is set to "false".
329 330 * Return non-zero otherwise.
330 331 */
331 332 int
332 333 scf_is_fastboot_default(void)
333 334 {
334 335 uint8_t boot_config = 0, boot_config_ovr;
335 336 char procbuf[SYS_NMLN];
336 337
337 338 /*
338 339 * If we are on xVM, do not fast reboot by default.
339 340 */
340 341 if (sysinfo(SI_PLATFORM, procbuf, sizeof (procbuf)) == -1 ||
341 342 strcmp(procbuf, "i86xpv") == 0)
342 343 return (0);
343 344
344 345 /*
345 346 * Get property values from "config" property group
346 347 */
347 348 scf_get_boot_config(&boot_config);
348 349
349 350 /*
350 351 * Get property values from non-persistent "config_ovr" property group
351 352 */
352 353 boot_config_ovr = boot_config;
353 354 scf_get_boot_config_ovr(&boot_config_ovr);
354 355
355 356 return (boot_config & boot_config_ovr & UA_FASTREBOOT_DEFAULT);
↓ open down ↓ |
310 lines elided |
↑ open up ↑ |
356 357 }
357 358
358 359 /*
359 360 * Read the default security-flags from system/process-security and return a
360 361 * secflagset_t suitable for psecflags(2)
361 362 *
362 363 * Unfortunately, this symbol must _exist_ in the native build, for the sake
363 364 * of the mapfile, even though we don't ever use it, and it will never work.
364 365 */
365 366 struct group_desc {
366 - secflagset_t *set;
367 + secflagdelta_t *delta;
367 368 char *fmri;
368 369 };
369 370
370 371 int
371 -scf_default_secflags(scf_handle_t *hndl, psecflags_t *flags)
372 +scf_default_secflags(scf_handle_t *hndl, scf_secflags_t *flags)
372 373 {
373 374 #if !defined(NATIVE_BUILD)
374 375 scf_property_t *prop;
375 376 scf_value_t *val;
376 377 const char *flagname;
377 378 int flag;
378 379 struct group_desc *g;
379 380 struct group_desc groups[] = {
380 381 {NULL, "svc:/system/process-security/"
381 382 ":properties/default"},
382 383 {NULL, "svc:/system/process-security/"
383 384 ":properties/lower"},
384 385 {NULL, "svc:/system/process-security/"
385 386 ":properties/upper"},
386 387 {NULL, NULL}
387 388 };
388 389
389 - groups[0].set = &flags->psf_inherit;
390 - groups[1].set = &flags->psf_lower;
391 - groups[2].set = &flags->psf_upper;
390 + bzero(flags, sizeof (*flags));
392 391
393 - /* Ensure sane defaults */
394 - psecflags_default(flags);
392 + groups[0].delta = &flags->ss_default;
393 + groups[1].delta = &flags->ss_lower;
394 + groups[2].delta = &flags->ss_upper;
395 395
396 - for (g = groups; g->set != NULL; g++) {
396 + for (g = groups; g->delta != NULL; g++) {
397 397 for (flag = 0; (flagname = secflag_to_str(flag)) != NULL;
398 398 flag++) {
399 399 char *pfmri;
400 400 uint8_t flagval = 0;
401 401
402 402 if ((val = scf_value_create(hndl)) == NULL)
403 403 return (-1);
404 404
405 405 if ((prop = scf_property_create(hndl)) == NULL) {
406 406 scf_value_destroy(val);
407 407 return (-1);
408 408 }
409 409
410 410 if ((pfmri = uu_msprintf("%s/%s", g->fmri,
411 411 flagname)) == NULL)
412 412 uu_die("Allocation failure\n");
413 413
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
414 414 if (scf_handle_decode_fmri(hndl, pfmri,
415 415 NULL, NULL, NULL, NULL, prop, NULL) != 0)
416 416 goto next;
417 417
418 418 if (scf_property_get_value(prop, val) != 0)
419 419 goto next;
420 420
421 421 (void) scf_value_get_boolean(val, &flagval);
422 422
423 423 if (flagval != 0)
424 - secflag_set(g->set, flag);
424 + secflag_set(&g->delta->psd_add, flag);
425 425 else
426 - secflag_clear(g->set, flag);
426 + secflag_set(&g->delta->psd_rem, flag);
427 427
428 428 next:
429 429 uu_free(pfmri);
430 430 scf_value_destroy(val);
431 431 scf_property_destroy(prop);
432 432 }
433 433 }
434 434
435 - if (!psecflags_validate(flags))
436 - return (-1);
437 -
438 435 return (0);
439 436 #else
440 437 assert(0);
441 438 abort();
442 439 #endif /* !NATIVE_BUILD */
443 440 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX