/* * Gets a blob property value. * Caller is responsible to have enough memory allocated. */ int smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname, void *v, size_t sz) { int ret = SMBD_SMF_OK; scf_value_t *value = NULL; scf_property_t *prop = NULL; if (handle == NULL) return (SMBD_SMF_SYSTEM_ERR); value = scf_value_create(handle->scf_handle); prop = scf_property_create(handle->scf_handle); if ((prop) && (value) && (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { if (scf_property_get_value(prop, value) == 0) { if (scf_value_get_opaque(value, (char *)v, sz) != sz) { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } if (value != NULL) scf_value_destroy(value); if (prop != NULL) scf_property_destroy(prop); return (ret); }
/* * Gets string property value.upto sz size. * Caller is responsible to have enough memory allocated. */ int smb_smf_get_string_property(smb_scfhandle_t *handle, char *propname, char *valstr, size_t sz) { int ret = SMBD_SMF_OK; scf_value_t *value; scf_property_t *prop; if (handle == NULL) return (SMBD_SMF_SYSTEM_ERR); value = scf_value_create(handle->scf_handle); prop = scf_property_create(handle->scf_handle); if (value && prop && (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { if (scf_property_get_value(prop, value) == 0) { if (scf_value_get_astring(value, valstr, sz) < 0) { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } } else { ret = SMBD_SMF_SYSTEM_ERR; } if (value != NULL) scf_value_destroy(value); if (prop != NULL) scf_property_destroy(prop); return (ret); }
/* * Sets boolean property value. * Caller is responsible to have enough memory allocated. */ int smb_smf_get_boolean_property(smb_scfhandle_t *handle, char *propname, uint8_t *valbool) { int ret = SMBC_SMF_OK; scf_value_t *value = NULL; scf_property_t *prop = NULL; if (handle == NULL) { return (SMBC_SMF_SYSTEM_ERR); } value = scf_value_create(handle->scf_handle); prop = scf_property_create(handle->scf_handle); if ((prop) && (value) && (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { if (scf_property_get_value(prop, value) == 0) { if (scf_value_get_boolean(value, valbool) != 0) { ret = SMBC_SMF_SYSTEM_ERR; } } else { ret = SMBC_SMF_SYSTEM_ERR; } } else { ret = SMBC_SMF_SYSTEM_ERR; } if (value != NULL) scf_value_destroy(value); if (prop != NULL) scf_property_destroy(prop); return (ret); }
/* In Solaris 11 the audit daemon has been moved to SMF. In the process they simply dropped getacna() from the API, since it read from a now non-existent config file. This function re-implements getacna() to read from the SMF repository instead. */ int getacna(char *auditstring, int len) { scf_handle_t *handle = NULL; scf_property_t *property = NULL; scf_value_t *value = NULL; int ret = 0; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) return -2; /* The man page for getacna on Solaris 10 states we should return -2 in case of error and set errno to indicate the error. We don't bother with errno here, though, since the only use of this function below doesn't check for errors anyway. */ ret = scf_handle_bind(handle); if (ret == -1) return -2; property = scf_property_create(handle); if (property == NULL) return -2; ret = scf_handle_decode_fmri(handle, "svc:/system/auditd:default/:properties/preselection/naflags", NULL, NULL, NULL, NULL, property, 0); if (ret == -1) return -2; value = scf_value_create(handle); if (value == NULL) return -2; ret = scf_property_get_value(property, value); if (ret == -1) return -2; ret = scf_value_get_astring(value, auditstring, len); if (ret == -1) return -2; scf_value_destroy(value); scf_property_destroy(property); scf_handle_destroy(handle); return 0; }
static int pg_get_prop_value(const scf_propertygroup_t *pg, const char *pname, scf_value_t *v) { if (pg == NULL || pname == NULL || v == NULL) return (-1); if (scf_pg_get_property(pg, pname, scratch_prop) == -1 || scf_property_get_value(scratch_prop, v) == -1) { switch (scf_error()) { case SCF_ERROR_NOT_FOUND: case SCF_ERROR_DELETED: break; default: syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_property failed for %s: %s\n", pname, scf_strerror(scf_error())); } return (-1); } return (0); }
static void kbd_defaults(int kbd) { scf_handle_t *h = NULL; scf_snapshot_t *snap = NULL; scf_instance_t *inst = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; int layout_num; char *val_layout = NULL, *val_abort = NULL; uint8_t val_click; int64_t val_delay, val_rate; int64_t val_kbd_beeper, val_console_beeper; if ((h = scf_handle_create(SCF_VERSION)) == NULL || scf_handle_bind(h) != 0 || (inst = scf_instance_create(h)) == NULL || (snap = scf_snapshot_create(h)) == NULL || (pg = scf_pg_create(h)) == NULL || (prop = scf_property_create(h)) == NULL || (val = scf_value_create(h)) == NULL) { goto out; } if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { goto out; } if (scf_instance_get_snapshot(inst, "running", snap) != 0) { scf_snapshot_destroy(snap); snap = NULL; } if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) { goto out; } if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) { (void) fprintf(stderr, "Can not alloc memory for keyboard properties\n"); goto out; } if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_boolean(val, &val_click) == -1) { (void) fprintf(stderr, "Can not get KEYCLICK\n"); } if (val_click == 1) (void) click("on", kbd); else if (val_click == 0) (void) click("off", kbd); else (void) fprintf(stderr, BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click); if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n"); } if (*val_abort != '\0') { /* * ABORT must equal "enable", "disable" or "alternate" */ if ((strcmp(val_abort, "enable") == 0) || (strcmp(val_abort, "alternate") == 0) || (strcmp(val_abort, "disable") == 0)) (void) abort_enable(val_abort, kbd); else (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_KEYBOARD_ABORT, val_abort); } if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_delay) == -1) { (void) fprintf(stderr, "Can not get RPTDELAY\n"); } if (val_delay > 0) (void) set_rptdelay(val_delay, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay); if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_rate) == -1) { (void) fprintf(stderr, "Can not get RPTRATE\n"); } if (val_rate > 0) (void) set_rptrate(val_rate, kbd); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate); if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) { (void) fprintf(stderr, "Can not get LAYOUT\n"); } if (*val_layout != '\0') { /* * LAYOUT must be one of the layouts supported in kbd_layouts */ if (get_layouts() != 0) goto out; if ((layout_num = get_layout_number(val_layout)) == -1) { (void) fprintf(stderr, BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout); goto out; } (void) set_layout(kbd, layout_num); } if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_kbd_beeper) == -1) { (void) fprintf(stderr, "Can not get FREQ\n"); } if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper); if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 || scf_property_get_value(prop, val) != 0 || scf_value_get_integer(val, &val_console_beeper) == -1) { (void) fprintf(stderr, "Can not get CONSFREQ\n"); } if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX) (void) set_beep_freq(kbd, "console", val_console_beeper); else (void) fprintf(stderr, BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper); out: if (val_layout != NULL) free(val_layout); if (val_abort != NULL) free(val_abort); if (snap != NULL) scf_snapshot_destroy(snap); scf_value_destroy(val); scf_property_destroy(prop); scf_pg_destroy(pg); scf_instance_destroy(inst); scf_handle_destroy(h); }
/* * Returns a zone ID of Solaris when the TZ value is "localtime". * First, it tries scf. If scf fails, it looks for the same file as * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/. */ static char * getSolarisDefaultZoneID() { char *tz = NULL; struct stat statbuf; size_t size; char *buf; int fd; /* scf specific variables */ scf_handle_t *h = NULL; scf_snapshot_t *snap = NULL; scf_instance_t *inst = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *val = NULL; if ((h = scf_handle_create(SCF_VERSION)) != NULL && scf_handle_bind(h) == 0 && (inst = scf_instance_create(h)) != NULL && (snap = scf_snapshot_create(h)) != NULL && (pg = scf_pg_create(h)) != NULL && (prop = scf_property_create(h)) != NULL && (val = scf_value_create(h)) != NULL && scf_handle_decode_fmri(h, TIMEZONE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) == 0 && scf_instance_get_snapshot(inst, "running", snap) == 0 && scf_instance_get_pg_composed(inst, snap, TIMEZONE_PG, pg) == 0 && scf_pg_get_property(pg, LOCALTIME_PROP, prop) == 0 && scf_property_get_value(prop, val) == 0) { ssize_t len; /* Gets the length of the zone ID string */ len = scf_value_get_astring(val, NULL, 0); if (len != -1) { tz = malloc(++len); /* +1 for a null byte */ if (tz != NULL && scf_value_get_astring(val, tz, len) != -1) { cleanupScf(h, snap, inst, pg, prop, val, NULL); return tz; } } } cleanupScf(h, snap, inst, pg, prop, val, tz); if (stat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) { return NULL; } size = (size_t) statbuf.st_size; buf = malloc(size); if (buf == NULL) { return NULL; } if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) { free((void *) buf); return NULL; } if (read(fd, buf, size) != (ssize_t) size) { (void) close(fd); free((void *) buf); return NULL; } (void) close(fd); tz = findZoneinfoFile(buf, size, ZONEINFO_DIR); free((void *) buf); return tz; }
/* * Inputs: * lpg is the property group to look up * lprop is the property within that group to look up * Outputs: * res is a pointer to an scf_resources_t. This is an internal * structure that holds all the handles needed to get a specific * property from the running snapshot; on a successful return it * contains the scf_value_t that should be passed to the desired * scf_value_get_foo() function, and must be freed after use by * calling release_scf_resources(). On a failure return, any * resources that may have been assigned to res are released, so * the caller does not need to do any cleanup in the failure case. * Returns: * 0 on success * -1 on failure */ static int get_property_value(const char *lpg, const char *lprop, scf_resources_t *res) { res->sr_inst = NULL; res->sr_snap = NULL; res->sr_pg = NULL; res->sr_prop = NULL; res->sr_val = NULL; if ((res->sr_handle = scf_handle_create(SCF_VERSION)) == NULL) { syslog(LOG_ERR, "scf_handle_create() failed: %s", scf_strerror(scf_error())); return (-1); } if (scf_handle_bind(res->sr_handle) != 0) { scf_handle_destroy(res->sr_handle); syslog(LOG_ERR, "scf_handle_destroy() failed: %s", scf_strerror(scf_error())); return (-1); } if ((res->sr_inst = scf_instance_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_instance_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_handle_decode_fmri(res->sr_handle, OUR_FMRI, NULL, NULL, res->sr_inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { syslog(LOG_ERR, "scf_handle_decode_fmri() failed: %s", scf_strerror(scf_error())); goto failure; } if ((res->sr_snap = scf_snapshot_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_snapshot_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_instance_get_snapshot(res->sr_inst, "running", res->sr_snap) != 0) { syslog(LOG_ERR, "scf_instance_get_snapshot() failed: %s", scf_strerror(scf_error())); goto failure; } if ((res->sr_pg = scf_pg_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_pg_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_instance_get_pg_composed(res->sr_inst, res->sr_snap, lpg, res->sr_pg) != 0) { syslog(LOG_ERR, "scf_instance_get_pg_composed(%s) failed: %s", lpg, scf_strerror(scf_error())); goto failure; } if ((res->sr_prop = scf_property_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_property_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_pg_get_property(res->sr_pg, lprop, res->sr_prop) != 0) { syslog(LOG_ERR, "scf_pg_get_property(%s) failed: %s", lprop, scf_strerror(scf_error())); goto failure; } if ((res->sr_val = scf_value_create(res->sr_handle)) == NULL) { syslog(LOG_ERR, "scf_value_create() failed: %s", scf_strerror(scf_error())); goto failure; } if (scf_property_get_value(res->sr_prop, res->sr_val) != 0) { syslog(LOG_ERR, "scf_property_get_value() failed: %s", scf_strerror(scf_error())); goto failure; } return (0); failure: release_scf_resources(res); return (-1); }
Status osDaemonIsEnabled( int inQuiet ) { Status isEnabled = sStatusNotEnabled; scf_handle_t * theHandle = scf_handle_create( SCF_VERSION ); if (inQuiet == 0) { writeInitialMessage( sOpIsEnabled ); } if ( theHandle != 0 ) { if ( scf_handle_bind( theHandle ) == 0 ) { scf_instance_t * theInstance = scf_instance_create( theHandle ); if ( theInstance != 0 ) { if ( scf_handle_decode_fmri( theHandle, sInstanceName, 0, 0, theInstance, 0, 0, SCF_DECODE_FMRI_EXACT ) != -1 ) { scf_handle_t * theInstanceHandle = scf_instance_handle( theInstance ); if ( theInstanceHandle != 0 ) { uint8_t theEnabled; scf_propertygroup_t * theGroup = scf_pg_create( theInstanceHandle ); scf_property_t * theProp = scf_property_create( theInstanceHandle ); scf_value_t * theValue = scf_value_create( theInstanceHandle ); if ( theGroup != 0 && theProp != 0 && theValue != 0 ) { if ( scf_instance_get_pg( theInstance, SCF_PG_GENERAL, theGroup ) == 0 && scf_pg_get_property( theGroup, SCF_PROPERTY_ENABLED, theProp ) == 0 && scf_property_get_value( theProp, theValue ) == 0 && scf_value_get_boolean( theValue, &theEnabled ) == 0 ) { isEnabled = theEnabled == 1 ? sStatusEnabled : sStatusNotEnabled; } } scf_pg_destroy( theGroup ); scf_property_destroy( theProp ); scf_value_destroy( theValue ); } } scf_instance_destroy( theInstance ); } } scf_handle_destroy( theHandle ); } if (inQuiet == 0) { writeFinalMessage( sOpIsEnabled, isEnabled ); } return isEnabled; }
/* * mgmt_get_param() get parameter of a specific LUN from scf * Args: * node - the node which parameters will be stored in mem * target_name - the local target name * lun - the LUN number * See also : mgmt_param_save2scf() */ Boolean_t mgmt_get_param(tgt_node_t **node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char pname[64]; char pgname[64]; char valuebuf[MAXPATHLEN]; tgt_node_t *n; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); snprintf(pgname, sizeof (pgname), "param_%s_%d", target_name, lun); (void) pthread_mutex_lock(&scf_param_mutex); if (scf_service_get_pg(h->t_service, pgname, h->t_pg) == -1) { goto error; } *node = tgt_node_alloc(XML_ELEMENT_PARAMS, String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } status = True; error: (void) pthread_mutex_unlock(&scf_param_mutex); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }
/* * mgmt_get_main_config() loads main configuration * from scf into a node tree. * Main configuration includes: admin/target/tpgt/initiator info. * admin info is stored in "iscsitgt" property group * target info is stored in "target_<name>" property group * initiator info is stored in "initiator_<name>" property group * tpgt info is stored in "tpgt_<number>" property group */ Boolean_t mgmt_get_main_config(tgt_node_t **node) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; scf_iter_t *iter_v = NULL; scf_iter_t *iter_pv = NULL; char pname[32]; char valuebuf[MAXPATHLEN]; char passcode[32]; unsigned int outlen; tgt_node_t *n; tgt_node_t *pn; tgt_node_t *vn; Boolean_t status = False; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); (void) pthread_mutex_lock(&scf_conf_mutex); /* Basic Information is stored in iscsitgt pg */ if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == -1) { goto error; } *node = NULL; *node = tgt_node_alloc("main_config", String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } /* * targets/initiators/tpgt information is * stored as type "configuration" in scf * each target's param is stored as type "parameter" */ if (scf_iter_service_pgs_typed(iter, h->t_service, "configuration") == -1) { goto error; } while (scf_iter_next_pg(iter, h->t_pg) > 0) { char *iname; scf_pg_get_name(h->t_pg, pname, sizeof (pname)); iname = strchr(pname, '_'); if (iname == NULL) { /* the pg found here is not a tgt/initiator/tpgt */ continue; } *iname = '\0'; iname++; /* * now pname is "target" or "initiator" or "tpgt" * meanwhile iname is the actual name of the item */ n = tgt_node_alloc(pname, String, iname); if (n == NULL) goto error; iter_v = scf_iter_create(h->t_handle); if (scf_iter_pg_properties(iter_v, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter_v, prop) > 0) { /* there may be many values in one property */ char *vname; scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; vname = strstr(pname, "-list"); if (vname == NULL) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); pn = tgt_node_alloc(pname, String, valuebuf); if (pn == NULL) goto error; tgt_node_add(n, pn); } else { pn = tgt_node_alloc(pname, String, NULL); if (pn == NULL) goto error; tgt_node_add(n, pn); *vname = '\0'; iter_pv = scf_iter_create(h->t_handle); scf_iter_property_values(iter_pv, prop); while (scf_iter_next_value(iter_pv, value) > 0) { scf_value_get_as_string(value, valuebuf, MAXPATHLEN); vn = tgt_node_alloc(pname, String, valuebuf); if (vn == NULL) goto error; tgt_node_add(pn, vn); } scf_iter_destroy(iter_pv); iter_pv = NULL; } } tgt_node_add(*node, n); scf_iter_destroy(iter_v); iter_v = NULL; } /* chap-secrets are stored in "passwords" pgroup as "application" */ if (scf_service_get_pg(h->t_service, "passwords", h->t_pg) == 0) { if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { scf_property_get_value(prop, value); scf_value_get_as_string(value, valuebuf, MAXPATHLEN); scf_property_get_name(prop, pname, sizeof (pname)); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; /* max length of decoded passwd is 16B */ sasl_decode64(valuebuf, strlen(valuebuf), passcode, sizeof (passcode), &outlen); if (strcmp(pname, "radius") == 0) { pn = tgt_node_alloc(XML_ELEMENT_RAD_SECRET, String, passcode); tgt_node_add(*node, pn); } else if (strcmp(pname, "main") == 0) { pn = tgt_node_alloc(XML_ELEMENT_CHAPSECRET, String, passcode); tgt_node_add(*node, pn); } else { /* find corresponding initiator */ n = NULL; while (n = tgt_node_next_child(*node, XML_ELEMENT_INIT, n)) { if (strcmp(pname + 2, n->x_value) != 0) continue; pn = tgt_node_alloc( XML_ELEMENT_CHAPSECRET, String, passcode); tgt_node_add(n, pn); } } } } status = True; error: if ((status != True) && (*node != NULL)) tgt_node_free(*node); (void) pthread_mutex_unlock(&scf_conf_mutex); if (iter_pv != NULL) scf_iter_destroy(iter_pv); if (iter_v != NULL) scf_iter_destroy(iter_v); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }
int fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf, char *instance, scf_type_t sctype, char *fmri, int *bufsz) { fs_smfhandle_t *phandle = NULL; scf_handle_t *handle; scf_propertygroup_t *pg; scf_property_t *prop; scf_value_t *val; scf_instance_t *inst; int ret = 0, len = 0, length; int64_t valint = 0; char srv[MAXPATHLEN], *p, *svcname; const char *pgname; uint8_t bval; /* * The SVC names we are using currently are already * appended by default. Fix this for instances project. */ snprintf(srv, MAXPATHLEN, "%s", fmri); p = strstr(fmri, ":default"); if (p == NULL) { strcat(srv, ":"); if (instance == NULL) instance = "default"; if (strlen(srv) + strlen(instance) > MAXPATHLEN) goto out; strncat(srv, instance, strlen(instance)); } svcname = srv; phandle = fs_smf_init(fmri, instance); if (phandle == NULL) return (SMF_SYSTEM_ERR); handle = phandle->fs_handle; pg = phandle->fs_pg; inst = phandle->fs_instance; prop = phandle->fs_property; val = phandle->fs_value; if (handle == NULL || pg == NULL || prop == NULL || val == NULL || inst == NULL) { return (SMF_SYSTEM_ERR); } if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope, phandle->fs_service, inst, NULL, NULL, 0) != 0) { ret = scf_error(); goto out; } if (fstype == AUTOFS_SMF) pgname = AUTOFS_PROPS_PGNAME; else pgname = NFS_PROPS_PGNAME; if (scf_instance_get_pg(inst, pgname, pg) != -1) { if (scf_pg_get_property(pg, prop_name, prop) != SCF_SUCCESS) { ret = scf_error(); goto out; } if (scf_property_get_value(prop, val) != SCF_SUCCESS) { ret = scf_error(); goto out; } switch (sctype) { case SCF_TYPE_ASTRING: len = scf_value_get_astring(val, cbuf, *bufsz); if (len < 0 || len > *bufsz) { ret = scf_error(); goto out; } ret = 0; *bufsz = len; break; case SCF_TYPE_INTEGER: if (scf_value_get_integer(val, &valint) != 0) { ret = scf_error(); goto out; } length = snprintf(cbuf, *bufsz, "%lld", valint); if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } ret = 0; break; case SCF_TYPE_BOOLEAN: if (scf_value_get_boolean(val, &bval) != 0) { ret = scf_error(); goto out; } if (bval == 1) { length = snprintf(cbuf, *bufsz, "%s", "true"); } else { length = snprintf(cbuf, *bufsz, "%s", "false"); } if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } break; } } else { ret = scf_error(); } if ((ret != 0) && scf_error() != SCF_ERROR_NONE) { /* * This is a workaround for the NFS service manifests not * containing the proper properties in local zones. * * When in a local zone and the property doesn't exist on an NFS * service (most likely nfs/server or nfs/client), don't print * the error. The caller will still see the correct error code, * but a user creating a delegated dataset or mounting an NFS * share won't see this spurious error. */ if (getzoneid() == GLOBAL_ZONEID || scf_error() != SCF_ERROR_NOT_FOUND) { fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); } } out: fs_smf_fini(phandle); return (ret); }
int fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf, char *instance, scf_type_t sctype, char *fmri, int *bufsz) { fs_smfhandle_t *phandle = NULL; scf_handle_t *handle; scf_propertygroup_t *pg; scf_property_t *prop; scf_value_t *val; scf_instance_t *inst; int ret = 0, len = 0, length; int64_t valint = 0; char srv[MAXPATHLEN], *p, *svcname; const char *pgname; uint8_t bval; /* * The SVC names we are using currently are already * appended by default. Fix this for instances project. */ snprintf(srv, MAXPATHLEN, "%s", fmri); p = strstr(fmri, ":default"); if (p == NULL) { strcat(srv, ":"); if (instance == NULL) instance = "default"; if (strlen(srv) + strlen(instance) > MAXPATHLEN) goto out; strncat(srv, instance, strlen(instance)); } svcname = srv; phandle = fs_smf_init(fmri, instance); if (phandle == NULL) return (SMF_SYSTEM_ERR); handle = phandle->fs_handle; pg = phandle->fs_pg; inst = phandle->fs_instance; prop = phandle->fs_property; val = phandle->fs_value; if (handle == NULL || pg == NULL || prop == NULL || val == NULL || inst == NULL) { return (SMF_SYSTEM_ERR); } if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope, phandle->fs_service, inst, NULL, NULL, 0) != 0) { ret = scf_error(); goto out; } if (fstype == AUTOFS_SMF) pgname = AUTOFS_PROPS_PGNAME; else pgname = NFS_PROPS_PGNAME; if (scf_instance_get_pg(inst, pgname, pg) != -1) { if (scf_pg_get_property(pg, prop_name, prop) != SCF_SUCCESS) { ret = scf_error(); goto out; } if (scf_property_get_value(prop, val) != SCF_SUCCESS) { ret = scf_error(); goto out; } switch (sctype) { case SCF_TYPE_ASTRING: len = scf_value_get_astring(val, cbuf, *bufsz); if (len < 0 || len > *bufsz) { ret = scf_error(); goto out; } ret = 0; *bufsz = len; break; case SCF_TYPE_INTEGER: if (scf_value_get_integer(val, &valint) != 0) { ret = scf_error(); goto out; } length = snprintf(cbuf, *bufsz, "%lld", valint); if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } ret = 0; break; case SCF_TYPE_BOOLEAN: if (scf_value_get_boolean(val, &bval) != 0) { ret = scf_error(); goto out; } if (bval == 1) { length = snprintf(cbuf, *bufsz, "%s", "true"); } else { length = snprintf(cbuf, *bufsz, "%s", "false"); } if (length < 0 || length > *bufsz) { ret = SA_BAD_VALUE; goto out; } break; } } else { ret = scf_error(); } if ((ret != 0) && scf_error() != SCF_ERROR_NONE) fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); out: fs_smf_fini(phandle); return (ret); }
void read_scf_proto_cfg(const char *proto, scf_cfg_t *cfg) { scf_handle_t *handle = NULL; scf_scope_t *sc = NULL; scf_service_t *svc = NULL; scf_propertygroup_t *pg = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *value_iter = NULL; uint64_t val; char *str; size_t slen; int i; handle = scf_handle_create(SCF_VERSION); sc = scf_scope_create(handle); svc = scf_service_create(handle); pg = scf_pg_create(handle); prop = scf_property_create(handle); value = scf_value_create(handle); value_iter = scf_iter_create(handle); if (handle == NULL || sc == NULL || svc == NULL || pg == NULL || prop == NULL || value == NULL || value_iter == NULL) { DMSG(D_OP, "%s: unable to create smf(5) handles.", proto); goto done; } if (scf_handle_bind(handle) != 0) { DMSG(D_OP, "%s: unable to bind smf(5) handle: %s", proto, scf_strerror(scf_error())); goto done; } if (scf_handle_decode_fmri(handle, fmri, sc, svc, NULL, NULL, NULL, 0) != 0) { DMSG(D_OP, "%s: unable to decode fmri '%s': %s", fmri, scf_strerror(scf_error())); goto done; } if (scf_service_get_pg(svc, proto, pg) != 0 && scf_error() != SCF_ERROR_NOT_FOUND) { DMSG(D_OP, "%s: unable to read '%s' property group: %s", proto, proto, scf_strerror(scf_error())); goto done; } for (i = 0; cfg[i].name != NULL; i++) { scf_cfg_t *c = &cfg[i]; if (scf_pg_get_property(pg, c->name, prop) != 0) { if (scf_error() != SCF_ERROR_NOT_FOUND) DMSG(D_OP, "%s: unable to read %s/%s from " "smf: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (scf_property_is_type(prop, c->type) != 0) { scf_type_t type; if (scf_error() != SCF_ERROR_TYPE_MISMATCH) { DMSG(D_OP, "%s: unable to validate " "type of '%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (scf_property_type(prop, &type) != 0) { DMSG(D_OP, "%s: unable to obtain " "type of '%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } DMSG(D_OP, "%s: property '%s/%s' has an unexpected " "type:\n" " expected type: %s\n" " actual type: %s\n", proto, proto, c->name, scf_type_to_string(c->type), scf_type_to_string(type)); continue; } if (scf_property_get_value(prop, value) != 0) { if (scf_error() != SCF_ERROR_NOT_SET) DMSG(D_OP, "%s: unable to get value of " "'%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } switch (c->type) { case SCF_TYPE_COUNT: if (scf_value_get_count(value, &val) != 0) { DMSG(D_OP, "%s: unable to read value of " "'%s/%s' smf property: %s", proto, proto, c->name, scf_strerror(scf_error())); continue; } if (val > c->max) { DMSG(D_OP, "%s: value of '%s/%s' smf property " "(%'llu) is out of range (0 - %'zu).", proto, proto, c->name, val, c->max); continue; } *((uint32_t *)c->val) = (uint32_t)val; break; case SCF_TYPE_ASTRING: { char **valp = (char **)c->val; ssize_t len; slen = c->max + 1; if ((str = malloc(slen)) == NULL) { /* XXX message */ continue; } if ((len = scf_value_get_astring(value, str, slen)) >= slen) DMSG(D_OP, "%s: length of '%s/%s' " "(%'zd bytes) exceeds maximum " "allowable length (%zu bytes). The string" " will be truncated.", proto, proto, c->name, len, c->max); free(*valp); *valp = str; break; } default: VERIFY(0); } } done: scf_iter_destroy(value_iter); scf_value_destroy(value); scf_property_destroy(prop); scf_pg_destroy(pg); scf_service_destroy(svc); scf_scope_destroy(sc); scf_handle_destroy(handle); }
/* * mgmt_get_param() get parameter of a specific LUN from scf * Args: * node - the node which parameters will be stored in mem * target_name - the local target name * lun - the LUN number * See also : mgmt_param_save2scf() */ Boolean_t mgmt_get_param(tgt_node_t **node, char *target_name, int lun) { targ_scf_t *h = NULL; scf_property_t *prop = NULL; scf_value_t *value = NULL; scf_iter_t *iter = NULL; char *pname = NULL; char *expgname = NULL; char *pgname = NULL; char *valuebuf = NULL; ssize_t max_name_len; ssize_t expg_max_name_len; ssize_t max_value_len; tgt_node_t *n; Boolean_t status = False; /* Set NULL as default output value */ *node = NULL; h = mgmt_handle_init(); if (h == NULL) return (status); prop = scf_property_create(h->t_handle); value = scf_value_create(h->t_handle); iter = scf_iter_create(h->t_handle); if ((alloc_scf_name(&max_name_len, (void *)&pname) == NULL) || (alloc_scf_name(&max_name_len, (void *)&pgname) == NULL) || (alloc_scf_value(&max_value_len, (void *)&valuebuf) == NULL)) { goto error; } /* * Allocate memory for an "expanded" (or "decoded") Property Group * name. */ expg_max_name_len = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) * PG_FACTOR + 1; if ((expgname = malloc(expg_max_name_len)) == NULL) { goto error; } (void) snprintf(pgname, max_name_len, "param_%s_%d", target_name, lun); pgname_encode(pgname, expgname, max_name_len); (void) pthread_mutex_lock(&scf_param_mutex); if (scf_service_get_pg(h->t_service, expgname, h->t_pg) == -1) { goto error; } *node = tgt_node_alloc(XML_ELEMENT_PARAMS, String, NULL); if (*node == NULL) goto error; if (scf_iter_pg_properties(iter, h->t_pg) == -1) { goto error; } while (scf_iter_next_property(iter, prop) > 0) { (void) scf_property_get_value(prop, value); (void) scf_value_get_as_string(value, valuebuf, max_value_len); (void) scf_property_get_name(prop, pname, max_name_len); /* avoid load auth to incore data */ if (strcmp(pname, ISCSI_READ_AUTHNAME) == 0 || strcmp(pname, ISCSI_MODIFY_AUTHNAME) == 0 || strcmp(pname, ISCSI_VALUE_AUTHNAME) == 0) continue; n = tgt_node_alloc(pname, String, valuebuf); if (n == NULL) goto error; /* put version info into root node's attr */ if (strcmp(pname, XML_ELEMENT_VERS) == 0) { tgt_node_add_attr(*node, n); } else { /* add other basic info into root node */ tgt_node_add(*node, n); } } status = True; error: (void) pthread_mutex_unlock(&scf_param_mutex); free(valuebuf); free(expgname); free(pgname); free(pname); scf_iter_destroy(iter); scf_value_destroy(value); scf_property_destroy(prop); mgmt_handle_fini(h); return (status); }