17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*074e084fSml93401 * Common Development and Distribution License (the "License"). 6*074e084fSml93401 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*074e084fSml93401 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/acctctl.h> 307c478bd9Sstevel@tonic-gate #include <unistd.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <errno.h> 347c478bd9Sstevel@tonic-gate #include <limits.h> 35*074e084fSml93401 #include <libscf.h> 36*074e084fSml93401 #include <pwd.h> 37*074e084fSml93401 #include <auth_attr.h> 38*074e084fSml93401 #include <nss_dbdefs.h> 39*074e084fSml93401 #include <secdb.h> 40*074e084fSml93401 #include <priv.h> 41*074e084fSml93401 #include <zone.h> 427c478bd9Sstevel@tonic-gate 437c478bd9Sstevel@tonic-gate #include "aconf.h" 447c478bd9Sstevel@tonic-gate #include "utils.h" 457c478bd9Sstevel@tonic-gate #include "res.h" 467c478bd9Sstevel@tonic-gate 47*074e084fSml93401 #define FMRI_FLOW_ACCT "svc:/system/extended-accounting:flow" 48*074e084fSml93401 #define FMRI_PROC_ACCT "svc:/system/extended-accounting:process" 49*074e084fSml93401 #define FMRI_TASK_ACCT "svc:/system/extended-accounting:task" 507c478bd9Sstevel@tonic-gate 51*074e084fSml93401 #define NELEM(x) (sizeof (x)) / (sizeof (x[0])) 527c478bd9Sstevel@tonic-gate 53*074e084fSml93401 typedef struct props { 54*074e084fSml93401 char *propname; 55*074e084fSml93401 int proptype; 56*074e084fSml93401 scf_transaction_entry_t *entry; 57*074e084fSml93401 scf_value_t *value; 58*074e084fSml93401 struct props *next; 59*074e084fSml93401 } props_t; 607c478bd9Sstevel@tonic-gate 61*074e084fSml93401 static void aconf_print_type(acctconf_t *, FILE *, int); 62*074e084fSml93401 static int aconf_get_bool(const char *, const char *, uint8_t *); 63*074e084fSml93401 static int aconf_get_string(const char *, const char *, char *, size_t); 64*074e084fSml93401 static props_t *aconf_prop(const char *, int); 65*074e084fSml93401 static int aconf_fmri2type(const char *); 66*074e084fSml93401 67*074e084fSml93401 static scf_handle_t *handle = NULL; 68*074e084fSml93401 static scf_instance_t *inst = NULL; 69*074e084fSml93401 static props_t *props = NULL; 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate void 72*074e084fSml93401 aconf_init(acctconf_t *acp, int type) 737c478bd9Sstevel@tonic-gate { 747c478bd9Sstevel@tonic-gate void *buf; 75*074e084fSml93401 char *tracked; 76*074e084fSml93401 char *untracked; 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate if ((buf = malloc(AC_BUFSIZE)) == NULL) 797c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n")); 807c478bd9Sstevel@tonic-gate 81*074e084fSml93401 if (acctctl(type | AC_STATE_GET, &acp->state, 82*074e084fSml93401 sizeof (acp->state)) == -1) 83*074e084fSml93401 die(gettext("cannot get %s accounting state\n"), 84*074e084fSml93401 ac_type_name(type)); 857c478bd9Sstevel@tonic-gate 86*074e084fSml93401 (void) memset(acp->file, 0, sizeof (acp->file)); 87*074e084fSml93401 if (acctctl(type | AC_FILE_GET, acp->file, sizeof (acp->file)) == -1) { 88*074e084fSml93401 if (errno == ENOTACTIVE) 89*074e084fSml93401 (void) strlcpy(acp->file, AC_STR_NONE, 90*074e084fSml93401 sizeof (acp->file)); 917c478bd9Sstevel@tonic-gate else 92*074e084fSml93401 die(gettext("cannot get %s accounting file name"), 93*074e084fSml93401 ac_type_name(type)); 94*074e084fSml93401 } 95*074e084fSml93401 (void) memset(buf, 0, AC_BUFSIZE); 96*074e084fSml93401 if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) 97*074e084fSml93401 die(gettext("cannot obtain the list of enabled resources\n")); 98*074e084fSml93401 99*074e084fSml93401 tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type); 100*074e084fSml93401 untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type); 101*074e084fSml93401 (void) strlcpy(acp->tracked, tracked, sizeof (acp->tracked)); 102*074e084fSml93401 (void) strlcpy(acp->untracked, untracked, sizeof (acp->untracked)); 103*074e084fSml93401 free(tracked); 104*074e084fSml93401 free(untracked); 105*074e084fSml93401 free(buf); 106*074e084fSml93401 } 107*074e084fSml93401 108*074e084fSml93401 /* 109*074e084fSml93401 * SMF start method: configure extended accounting from properties stored in 110*074e084fSml93401 * the repository. Any errors encountered while retrieving properties from 111*074e084fSml93401 * the repository, such as missing properties or properties of the wrong type, 112*074e084fSml93401 * are fatal as they indicate severe damage to the service (all required 113*074e084fSml93401 * properties are delivered in the service manifest and should thus always be 114*074e084fSml93401 * present). No attempts will be made to repair such damage; the service will 115*074e084fSml93401 * be forced into maintenance state by returning SMF_EXIT_ERR_CONFIG. For all 116*074e084fSml93401 * other errors we we try to configure as much as possible and return 117*074e084fSml93401 * SMF_EXIT_ERR_FATAL. 118*074e084fSml93401 */ 119*074e084fSml93401 int 120*074e084fSml93401 aconf_setup(const char *fmri) 121*074e084fSml93401 { 122*074e084fSml93401 char file[MAXPATHLEN]; 123*074e084fSml93401 char tracked[MAXRESLEN]; 124*074e084fSml93401 char untracked[MAXRESLEN]; 125*074e084fSml93401 void *buf; 126*074e084fSml93401 int type; 127*074e084fSml93401 int state; 128*074e084fSml93401 uint8_t b; 129*074e084fSml93401 int ret = SMF_EXIT_OK; 130*074e084fSml93401 131*074e084fSml93401 if ((type = aconf_fmri2type(fmri)) == -1) { 132*074e084fSml93401 warn(gettext("no accounting type for %s\n"), fmri); 133*074e084fSml93401 return (SMF_EXIT_ERR_FATAL); 134*074e084fSml93401 } 135*074e084fSml93401 136*074e084fSml93401 /* 137*074e084fSml93401 * Flow accounting is not available in non-global zones and 138*074e084fSml93401 * the service instance should therefore never be 'enabled' in 139*074e084fSml93401 * non-global zones. This is enforced by acctadm(1M), but there is 140*074e084fSml93401 * nothing that prevents someone from calling svcadm enable directly, 141*074e084fSml93401 * so we handle that case here by disabling the instance. 142*074e084fSml93401 */ 143*074e084fSml93401 if (type == AC_FLOW && getzoneid() != GLOBAL_ZONEID) { 144*074e084fSml93401 (void) smf_disable_instance(fmri, 0); 145*074e084fSml93401 warn(gettext("%s accounting cannot be configured in " 146*074e084fSml93401 "non-global zones\n"), ac_type_name(type)); 147*074e084fSml93401 return (SMF_EXIT_OK); 148*074e084fSml93401 } 149*074e084fSml93401 150*074e084fSml93401 if (aconf_scf_init(fmri) == -1) { 151*074e084fSml93401 warn(gettext("cannot connect to repository\n")); 152*074e084fSml93401 return (SMF_EXIT_ERR_FATAL); 153*074e084fSml93401 } 154*074e084fSml93401 if (aconf_get_string(AC_PGNAME, AC_PROP_TRACKED, tracked, 155*074e084fSml93401 sizeof (tracked)) == -1) { 156*074e084fSml93401 warn(gettext("cannot get %s property\n"), AC_PROP_TRACKED); 157*074e084fSml93401 ret = SMF_EXIT_ERR_CONFIG; 158*074e084fSml93401 goto out; 159*074e084fSml93401 } 160*074e084fSml93401 if (aconf_get_string(AC_PGNAME, AC_PROP_UNTRACKED, untracked, 161*074e084fSml93401 sizeof (untracked)) == -1) { 162*074e084fSml93401 warn(gettext("cannot get %s property\n"), AC_PROP_UNTRACKED); 163*074e084fSml93401 ret = SMF_EXIT_ERR_CONFIG; 164*074e084fSml93401 goto out; 165*074e084fSml93401 } 166*074e084fSml93401 if (aconf_get_string(AC_PGNAME, AC_PROP_FILE, file, 167*074e084fSml93401 sizeof (file)) == -1) { 168*074e084fSml93401 warn(gettext("cannot get %s property\n"), AC_PROP_FILE); 169*074e084fSml93401 ret = SMF_EXIT_ERR_CONFIG; 170*074e084fSml93401 goto out; 171*074e084fSml93401 } 172*074e084fSml93401 if (aconf_get_bool(AC_PGNAME, AC_PROP_STATE, &b) == -1) { 173*074e084fSml93401 warn(gettext("cannot get %s property\n"), AC_PROP_STATE); 174*074e084fSml93401 ret = SMF_EXIT_ERR_CONFIG; 175*074e084fSml93401 goto out; 176*074e084fSml93401 } 177*074e084fSml93401 state = (b ? AC_ON : AC_OFF); 178*074e084fSml93401 179*074e084fSml93401 if ((buf = malloc(AC_BUFSIZE)) == NULL) { 180*074e084fSml93401 warn(gettext("not enough memory\n")); 181*074e084fSml93401 ret = SMF_EXIT_ERR_FATAL; 182*074e084fSml93401 goto out; 183*074e084fSml93401 } 184*074e084fSml93401 (void) memset(buf, 0, AC_BUFSIZE); 185*074e084fSml93401 str2buf(buf, untracked, AC_OFF, type); 186*074e084fSml93401 str2buf(buf, tracked, AC_ON, type); 187*074e084fSml93401 188*074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 189*074e084fSml93401 if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) { 190*074e084fSml93401 warn(gettext("cannot enable/disable %s accounting resources"), 191*074e084fSml93401 ac_type_name(type)); 192*074e084fSml93401 ret = SMF_EXIT_ERR_FATAL; 193*074e084fSml93401 } 194*074e084fSml93401 free(buf); 195*074e084fSml93401 196*074e084fSml93401 if (strcmp(file, AC_STR_NONE) != 0) { 197*074e084fSml93401 if (open_exacct_file(file, type) == -1) 198*074e084fSml93401 ret = SMF_EXIT_ERR_FATAL; 199*074e084fSml93401 } else { 200*074e084fSml93401 if (acctctl(type | AC_FILE_SET, NULL, 0) == -1) { 201*074e084fSml93401 warn(gettext("cannot close %s accounting file"), 202*074e084fSml93401 ac_type_name(type)); 203*074e084fSml93401 ret = SMF_EXIT_ERR_FATAL; 204*074e084fSml93401 } 205*074e084fSml93401 } 206*074e084fSml93401 if (acctctl(type | AC_STATE_SET, &state, sizeof (state)) == -1) { 207*074e084fSml93401 warn(gettext("cannot %s %s accounting"), 208*074e084fSml93401 state == AC_ON ? gettext("enable") : gettext("disable"), 209*074e084fSml93401 ac_type_name(type)); 210*074e084fSml93401 ret = SMF_EXIT_ERR_FATAL; 211*074e084fSml93401 } 212*074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 213*074e084fSml93401 out: 214*074e084fSml93401 aconf_scf_fini(); 215*074e084fSml93401 return (ret); 216*074e084fSml93401 } 217*074e084fSml93401 218*074e084fSml93401 void 219*074e084fSml93401 aconf_print(FILE *fp, int types) 220*074e084fSml93401 { 221*074e084fSml93401 acctconf_t ac; 222*074e084fSml93401 int print_order[] = { AC_TASK, AC_PROC, AC_FLOW }; 223*074e084fSml93401 int i; 224*074e084fSml93401 225*074e084fSml93401 for (i = 0; i < NELEM(print_order); i++) { 226*074e084fSml93401 if (types & print_order[i]) { 227*074e084fSml93401 aconf_init(&ac, print_order[i]); 228*074e084fSml93401 aconf_print_type(&ac, fp, print_order[i]); 229*074e084fSml93401 } 230*074e084fSml93401 } 231*074e084fSml93401 } 232*074e084fSml93401 233*074e084fSml93401 static void 234*074e084fSml93401 aconf_print_type(acctconf_t *acp, FILE *fp, int type) 235*074e084fSml93401 { 236*074e084fSml93401 switch (type) { 237*074e084fSml93401 case AC_TASK: 238*074e084fSml93401 (void) fprintf(fp, 239*074e084fSml93401 gettext(" Task accounting: %s\n"), 240*074e084fSml93401 acp->state == AC_ON ? 241*074e084fSml93401 gettext("active") : gettext("inactive")); 242*074e084fSml93401 (void) fprintf(fp, 243*074e084fSml93401 gettext(" Task accounting file: %s\n"), 244*074e084fSml93401 acp->file); 245*074e084fSml93401 (void) fprintf(fp, 246*074e084fSml93401 gettext(" Tracked task resources: %s\n"), 247*074e084fSml93401 acp->tracked); 248*074e084fSml93401 (void) fprintf(fp, 249*074e084fSml93401 gettext(" Untracked task resources: %s\n"), 250*074e084fSml93401 acp->untracked); 251*074e084fSml93401 break; 252*074e084fSml93401 case AC_PROC: 253*074e084fSml93401 (void) fprintf(fp, 254*074e084fSml93401 gettext(" Process accounting: %s\n"), 255*074e084fSml93401 acp->state == AC_ON ? 256*074e084fSml93401 gettext("active") : gettext("inactive")); 257*074e084fSml93401 (void) fprintf(fp, 258*074e084fSml93401 gettext(" Process accounting file: %s\n"), 259*074e084fSml93401 acp->file); 260*074e084fSml93401 (void) fprintf(fp, 261*074e084fSml93401 gettext(" Tracked process resources: %s\n"), 262*074e084fSml93401 acp->tracked); 263*074e084fSml93401 (void) fprintf(fp, 264*074e084fSml93401 gettext("Untracked process resources: %s\n"), 265*074e084fSml93401 acp->untracked); 266*074e084fSml93401 break; 267*074e084fSml93401 case AC_FLOW: 268*074e084fSml93401 (void) fprintf(fp, 269*074e084fSml93401 gettext(" Flow accounting: %s\n"), 270*074e084fSml93401 acp->state == AC_ON ? 271*074e084fSml93401 gettext("active") : gettext("inactive")); 272*074e084fSml93401 (void) fprintf(fp, 273*074e084fSml93401 gettext(" Flow accounting file: %s\n"), 274*074e084fSml93401 acp->file); 275*074e084fSml93401 (void) fprintf(fp, 276*074e084fSml93401 gettext(" Tracked flow resources: %s\n"), 277*074e084fSml93401 acp->tracked); 278*074e084fSml93401 (void) fprintf(fp, 279*074e084fSml93401 gettext(" Untracked flow resources: %s\n"), 280*074e084fSml93401 acp->untracked); 281*074e084fSml93401 break; 282*074e084fSml93401 } 283*074e084fSml93401 } 284*074e084fSml93401 285*074e084fSml93401 /* 286*074e084fSml93401 * Modified properties are put on the 'props' linked list by aconf_set_string() 287*074e084fSml93401 * and aconf_set_bool(). Walk the list of modified properties and write them 288*074e084fSml93401 * to the repository. The list is deleted on exit. 289*074e084fSml93401 */ 290*074e084fSml93401 int 291*074e084fSml93401 aconf_save(void) 292*074e084fSml93401 { 293*074e084fSml93401 scf_propertygroup_t *pg; 294*074e084fSml93401 scf_transaction_t *tx; 295*074e084fSml93401 props_t *p; 296*074e084fSml93401 props_t *q; 297*074e084fSml93401 int tx_result; 298*074e084fSml93401 299*074e084fSml93401 if (props == NULL) 3007c478bd9Sstevel@tonic-gate return (0); 301*074e084fSml93401 302*074e084fSml93401 if ((pg = scf_pg_create(handle)) == NULL || 303*074e084fSml93401 scf_instance_get_pg(inst, AC_PGNAME, pg) == -1 || 304*074e084fSml93401 (tx = scf_transaction_create(handle)) == NULL) 305*074e084fSml93401 goto out; 306*074e084fSml93401 307*074e084fSml93401 do { 308*074e084fSml93401 if (scf_pg_update(pg) == -1 || 309*074e084fSml93401 scf_transaction_start(tx, pg) == -1) 310*074e084fSml93401 goto out; 311*074e084fSml93401 312*074e084fSml93401 for (p = props; p != NULL; p = p->next) { 313*074e084fSml93401 if (scf_transaction_property_change(tx, p->entry, 314*074e084fSml93401 p->propname, p->proptype) == -1) 315*074e084fSml93401 goto out; 316*074e084fSml93401 (void) scf_entry_add_value(p->entry, p->value); 317*074e084fSml93401 } 318*074e084fSml93401 tx_result = scf_transaction_commit(tx); 319*074e084fSml93401 scf_transaction_reset(tx); 320*074e084fSml93401 } while (tx_result == 0); 321*074e084fSml93401 322*074e084fSml93401 out: 323*074e084fSml93401 p = props; 324*074e084fSml93401 while (p != NULL) { 325*074e084fSml93401 scf_value_destroy(p->value); 326*074e084fSml93401 scf_entry_destroy(p->entry); 327*074e084fSml93401 free(p->propname); 328*074e084fSml93401 q = p->next; 329*074e084fSml93401 free(p); 330*074e084fSml93401 p = q; 331*074e084fSml93401 } 332*074e084fSml93401 props = NULL; 333*074e084fSml93401 scf_transaction_destroy(tx); 334*074e084fSml93401 scf_pg_destroy(pg); 335*074e084fSml93401 return ((tx_result == 1) ? 0 : -1); 336*074e084fSml93401 } 337*074e084fSml93401 338*074e084fSml93401 boolean_t 339*074e084fSml93401 aconf_have_smf_auths(void) 340*074e084fSml93401 { 341*074e084fSml93401 char auth[NSS_BUFLEN_AUTHATTR]; 342*074e084fSml93401 struct passwd *pw; 343*074e084fSml93401 344*074e084fSml93401 if ((pw = getpwuid(getuid())) == NULL) 345*074e084fSml93401 return (B_FALSE); 346*074e084fSml93401 347*074e084fSml93401 if (aconf_get_string("general", "action_authorization", auth, 348*074e084fSml93401 sizeof (auth)) == -1 || chkauthattr(auth, pw->pw_name) == 0) 349*074e084fSml93401 return (B_FALSE); 350*074e084fSml93401 351*074e084fSml93401 if (aconf_get_string("general", "value_authorization", auth, 352*074e084fSml93401 sizeof (auth)) == -1 || chkauthattr(auth, pw->pw_name) == 0) 353*074e084fSml93401 return (B_FALSE); 354*074e084fSml93401 355*074e084fSml93401 if (aconf_get_string("config", "value_authorization", auth, 356*074e084fSml93401 sizeof (auth)) == -1 || chkauthattr(auth, pw->pw_name) == 0) 357*074e084fSml93401 return (B_FALSE); 358*074e084fSml93401 359*074e084fSml93401 return (B_TRUE); 360*074e084fSml93401 } 361*074e084fSml93401 362*074e084fSml93401 const char * 363*074e084fSml93401 aconf_type2fmri(int type) 364*074e084fSml93401 { 365*074e084fSml93401 switch (type) { 366*074e084fSml93401 case AC_PROC: 367*074e084fSml93401 return (FMRI_PROC_ACCT); 368*074e084fSml93401 case AC_TASK: 369*074e084fSml93401 return (FMRI_TASK_ACCT); 370*074e084fSml93401 case AC_FLOW: 371*074e084fSml93401 return (FMRI_FLOW_ACCT); 372*074e084fSml93401 default: 373*074e084fSml93401 die(gettext("invalid type %d\n"), type); 374*074e084fSml93401 } 375*074e084fSml93401 /* NOTREACHED */ 376*074e084fSml93401 return (NULL); 377*074e084fSml93401 } 378*074e084fSml93401 379*074e084fSml93401 static int 380*074e084fSml93401 aconf_fmri2type(const char *fmri) 381*074e084fSml93401 { 382*074e084fSml93401 if (strcmp(fmri, FMRI_PROC_ACCT) == 0) 383*074e084fSml93401 return (AC_PROC); 384*074e084fSml93401 else if (strcmp(fmri, FMRI_TASK_ACCT) == 0) 385*074e084fSml93401 return (AC_TASK); 386*074e084fSml93401 else if (strcmp(fmri, FMRI_FLOW_ACCT) == 0) 387*074e084fSml93401 return (AC_FLOW); 388*074e084fSml93401 else 389*074e084fSml93401 return (-1); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate int 393*074e084fSml93401 aconf_scf_init(const char *fmri) 3947c478bd9Sstevel@tonic-gate { 395*074e084fSml93401 if ((handle = scf_handle_create(SCF_VERSION)) == NULL || 396*074e084fSml93401 scf_handle_bind(handle) == -1 || 397*074e084fSml93401 (inst = scf_instance_create(handle)) == NULL || 398*074e084fSml93401 scf_handle_decode_fmri(handle, fmri, NULL, NULL, inst, NULL, NULL, 399*074e084fSml93401 SCF_DECODE_FMRI_EXACT) == -1) { 400*074e084fSml93401 aconf_scf_fini(); 4017c478bd9Sstevel@tonic-gate return (-1); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate return (0); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate void 407*074e084fSml93401 aconf_scf_fini(void) 4087c478bd9Sstevel@tonic-gate { 409*074e084fSml93401 scf_instance_destroy(inst); 410*074e084fSml93401 (void) scf_handle_unbind(handle); 411*074e084fSml93401 scf_handle_destroy(handle); 4127c478bd9Sstevel@tonic-gate } 413*074e084fSml93401 414*074e084fSml93401 static int 415*074e084fSml93401 aconf_get_string(const char *pgname, const char *propname, char *buf, 416*074e084fSml93401 size_t len) 417*074e084fSml93401 { 418*074e084fSml93401 scf_propertygroup_t *pg; 419*074e084fSml93401 scf_property_t *prop; 420*074e084fSml93401 scf_value_t *value; 421*074e084fSml93401 int ret = 0; 422*074e084fSml93401 423*074e084fSml93401 if ((pg = scf_pg_create(handle)) == NULL) 424*074e084fSml93401 return (-1); 425*074e084fSml93401 426*074e084fSml93401 if (scf_instance_get_pg_composed(inst, NULL, pgname, pg) == -1) { 427*074e084fSml93401 scf_pg_destroy(pg); 428*074e084fSml93401 return (-1); 4297c478bd9Sstevel@tonic-gate } 430*074e084fSml93401 431*074e084fSml93401 if ((prop = scf_property_create(handle)) == NULL || 432*074e084fSml93401 (value = scf_value_create(handle)) == NULL || 433*074e084fSml93401 scf_pg_get_property(pg, propname, prop) == -1 || 434*074e084fSml93401 scf_property_get_value(prop, value) == -1 || 435*074e084fSml93401 scf_value_get_astring(value, buf, len) == -1) 436*074e084fSml93401 ret = -1; 437*074e084fSml93401 438*074e084fSml93401 scf_value_destroy(value); 439*074e084fSml93401 scf_property_destroy(prop); 440*074e084fSml93401 scf_pg_destroy(pg); 441*074e084fSml93401 return (ret); 4427c478bd9Sstevel@tonic-gate } 443*074e084fSml93401 444*074e084fSml93401 static int 445*074e084fSml93401 aconf_get_bool(const char *pgname, const char *propname, uint8_t *rval) 446*074e084fSml93401 { 447*074e084fSml93401 scf_propertygroup_t *pg; 448*074e084fSml93401 scf_property_t *prop; 449*074e084fSml93401 scf_value_t *value; 450*074e084fSml93401 int ret = 0; 451*074e084fSml93401 452*074e084fSml93401 if ((pg = scf_pg_create(handle)) == NULL) 453*074e084fSml93401 return (-1); 454*074e084fSml93401 455*074e084fSml93401 if (scf_instance_get_pg_composed(inst, NULL, pgname, pg) == -1) { 456*074e084fSml93401 scf_pg_destroy(pg); 457*074e084fSml93401 return (-1); 458*074e084fSml93401 } 459*074e084fSml93401 460*074e084fSml93401 if ((prop = scf_property_create(handle)) == NULL || 461*074e084fSml93401 (value = scf_value_create(handle)) == NULL || 462*074e084fSml93401 scf_pg_get_property(pg, propname, prop) == -1 || 463*074e084fSml93401 scf_property_get_value(prop, value) == -1 || 464*074e084fSml93401 scf_value_get_boolean(value, rval) == -1) 465*074e084fSml93401 ret = -1; 466*074e084fSml93401 467*074e084fSml93401 scf_value_destroy(value); 468*074e084fSml93401 scf_property_destroy(prop); 469*074e084fSml93401 scf_pg_destroy(pg); 470*074e084fSml93401 return (ret); 4717c478bd9Sstevel@tonic-gate } 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate int 474*074e084fSml93401 aconf_set_string(const char *propname, const char *value) 4757c478bd9Sstevel@tonic-gate { 476*074e084fSml93401 props_t *p; 4777c478bd9Sstevel@tonic-gate 478*074e084fSml93401 if ((p = aconf_prop(propname, SCF_TYPE_ASTRING)) == NULL) 4797c478bd9Sstevel@tonic-gate return (-1); 480*074e084fSml93401 481*074e084fSml93401 if (scf_value_set_astring(p->value, value) == -1) 4827c478bd9Sstevel@tonic-gate return (-1); 4837c478bd9Sstevel@tonic-gate return (0); 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate int 487*074e084fSml93401 aconf_set_bool(const char *propname, boolean_t value) 4887c478bd9Sstevel@tonic-gate { 489*074e084fSml93401 props_t *p; 490*074e084fSml93401 491*074e084fSml93401 if ((p = aconf_prop(propname, SCF_TYPE_BOOLEAN)) == NULL) 4927c478bd9Sstevel@tonic-gate return (-1); 493*074e084fSml93401 494*074e084fSml93401 scf_value_set_boolean(p->value, value); 4957c478bd9Sstevel@tonic-gate return (0); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 498*074e084fSml93401 static props_t * 499*074e084fSml93401 aconf_prop(const char *propname, int proptype) 5007c478bd9Sstevel@tonic-gate { 501*074e084fSml93401 props_t *p; 5027c478bd9Sstevel@tonic-gate 503*074e084fSml93401 if ((p = malloc(sizeof (props_t))) != NULL) { 504*074e084fSml93401 if ((p->propname = strdup(propname)) == NULL) { 505*074e084fSml93401 free(p); 506*074e084fSml93401 return (NULL); 5077c478bd9Sstevel@tonic-gate } 508*074e084fSml93401 if ((p->entry = scf_entry_create(handle)) == NULL) { 509*074e084fSml93401 free(p->propname); 510*074e084fSml93401 free(p); 511*074e084fSml93401 return (NULL); 5127c478bd9Sstevel@tonic-gate } 513*074e084fSml93401 if ((p->value = scf_value_create(handle)) == NULL) { 514*074e084fSml93401 scf_entry_destroy(p->entry); 515*074e084fSml93401 free(p->propname); 516*074e084fSml93401 free(p); 517*074e084fSml93401 return (NULL); 5187c478bd9Sstevel@tonic-gate } 519*074e084fSml93401 p->proptype = proptype; 520*074e084fSml93401 p->next = props; 521*074e084fSml93401 props = p; 5227c478bd9Sstevel@tonic-gate } 523*074e084fSml93401 return (p); 5247c478bd9Sstevel@tonic-gate } 525