/* * Manage allocating dynamic memory for a string that is stored in * the SCF database. * * scf_limit(3SCF) is called in order to compute the maximum length of * the type of string specified by the 'limit' argument. malloc() * is then called to allocate the memory. * * If the function returns True, then the by-reference arguments will * be updated to hold the length and address of the memory chunk. */ static Boolean_t alloc_scf_element(uint32_t limit, ssize_t *max_len, void **buf) { ssize_t max_name_len; void *name_buf; Boolean_t status = False; /* * Dynamically compute the maximum length of the specified type * of string so that our algorithms do not use an arbitrary, * statically-defined value. */ if ((max_name_len = scf_limit(limit)) >= 0) { /* * scf_limit's return value knows nothing about a C-string's * trailing NULL byte; increment the count to allow for it. */ max_name_len++; if ((name_buf = malloc(max_name_len)) != NULL) { *max_len = max_name_len; *buf = name_buf; status = True; } } return (status); }
int main() { if (daemonize_self() == 1) return (1); max_scf_fmri_size = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1; max_scf_name_size = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1; assert(max_scf_fmri_size > 0); assert(max_scf_name_size > 0); if ((h = scf_handle_create(SCF_VERSION)) == NULL) { syslog(LOG_ERR | LOG_DAEMON, "scf_handle_create failed: %s\n", scf_strerror(scf_error())); return (1); } repository_rebind(h); scratch_fmri = umem_alloc(max_scf_fmri_size, UMEM_DEFAULT); scratch_name = umem_alloc(max_scf_name_size, UMEM_DEFAULT); if (scratch_fmri == NULL || scratch_name == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Out of memory"); return (1); } inst = scf_instance_create(h); snap = scf_snapshot_create(h); scratch_pg = scf_pg_create(h); scratch_prop = scf_property_create(h); scratch_v = scf_value_create(h); if (inst == NULL || snap == NULL || scratch_pg == NULL || scratch_prop == NULL || scratch_v == NULL) { syslog(LOG_ERR | LOG_DAEMON, "Initialization failed: %s\n", scf_strerror(scf_error())); return (1); } return (repository_event_wait()); }
/* * put_prop_value_string takes an array of inetd_prop_t's, a name of an inetd * property, and a value. It duplicates the value into the property * in the array, and returns B_TRUE for success and B_FALSE for failure. It's * expected that the property exists in the searched array. */ boolean_t put_prop_value_string(inetd_prop_t *prop, const char *name, const char *value) { inetd_prop_t *p; if (strlen(value) >= scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) { errno = E2BIG; return (B_FALSE); } p = find_prop(prop, name, INET_TYPE_STRING); if ((p->ip_value.iv_string = strdup(value)) == NULL) return (B_FALSE); p->ip_error = IVE_VALID; return (B_TRUE); }
/* * Load the instance for fmri from the repository into memory. The * property groups that define the instances pg_patterns and prop_patterns * are also loaded. * * Returns 0 on success and non-zero on failure. */ int load_instance(const char *fmri, const char *name, entity_t **inst_ptr) { entity_t *e = NULL; scf_instance_t *inst; pgroup_t *ipg; int rc; char *type = NULL; ssize_t tsize; assert(inst_ptr != NULL); if ((inst = scf_instance_create(g_hndl)) == NULL) { switch (scf_error()) { case SCF_ERROR_NO_MEMORY: case SCF_ERROR_NO_RESOURCES: rc = EAGAIN; goto errout; default: bad_error("scf_instance_create", scf_error()); } } if (scf_handle_decode_fmri(g_hndl, fmri, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT|SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) { switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; goto errout; case SCF_ERROR_DELETED: case SCF_ERROR_NOT_FOUND: rc = ENOENT; goto errout; case SCF_ERROR_INVALID_ARGUMENT: rc = EINVAL; goto errout; case SCF_ERROR_CONSTRAINT_VIOLATED: rc = ENOTSUP; goto errout; default: bad_error("scf_handle_decode_fmri", scf_error()); } } if (scf_iter_instance_pgs_composed(load_pgiter, inst, NULL) != 0) { switch (scf_error()) { case SCF_ERROR_DELETED: rc = ECANCELED; goto errout; case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; goto errout; default: bad_error("scf_iter_instance_pgs_composed", scf_error()); } } tsize = scf_limit(SCF_LIMIT_MAX_PG_TYPE_LENGTH); type = uu_zalloc(tsize); if (type == NULL) { rc = ENOMEM; goto errout; } /* * Initialize our entity structure. */ e = internal_instance_new(name); if (e == NULL) { rc = ENOMEM; goto errout; } e->sc_fmri = uu_strdup(fmri); if (e->sc_fmri == NULL) { rc = ENOMEM; goto errout; } /* * Walk through the property group's of the instance and capture * the property groups that are of type * SCF_GROUP_TEMPLATE_PG_PATTERN and * SCF_GROUP_TEMPLATE_PROP_PATTERN. In other words grab the * pg_pattern and prop_pattern property groups. */ while ((rc = scf_iter_next_pg(load_pgiter, load_pgroup)) == 1) { if (scf_pg_get_type(load_pgroup, type, tsize) <= 0) { switch (scf_error()) { case SCF_ERROR_DELETED: rc = ENOENT; break; case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; break; default: bad_error("scf_pg_get_type", scf_error()); } goto errout; } if ((strcmp(type, SCF_GROUP_TEMPLATE_PG_PATTERN) != 0) && (strcmp(type, SCF_GROUP_TEMPLATE_PROP_PATTERN) != 0)) { continue; } if ((rc = load_pg(load_pgroup, &ipg, fmri, NULL)) != 0) { switch (rc) { case ECANCELED: case ECONNABORTED: case EACCES: case ENOMEM: break; default: bad_error("load_pg", rc); } goto errout; } if (internal_attach_pgroup(e, ipg) != 0) { rc = EBADF; goto errout; } } if (rc == -1) { /* Error in iteration. */ switch (scf_error()) { case SCF_ERROR_CONNECTION_BROKEN: rc = ECONNABORTED; break; case SCF_ERROR_DELETED: rc = ENOENT; break; case SCF_ERROR_NO_RESOURCES: rc = EAGAIN; break; default: bad_error("scf_iter_next_pg", scf_error()); } goto errout; } *inst_ptr = e; scf_instance_destroy(inst); return (0); errout: if (type != NULL) uu_free(type); if (inst != NULL) scf_instance_destroy(inst); if (e != NULL) internal_instance_free(e); return (rc); }
static int create_instance(scf_handle_t *handle, scf_service_t *svc, const char *instance_name, const char *kssl_entry, const char *command, const char *username, char *inaddr_any_name) { int status = FAILURE; char *buf; boolean_t errflag = B_FALSE; ssize_t max_fmri_len; scf_instance_t *instance; instance = scf_instance_create(handle); if (instance == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_instance_create failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_instance_create succeeded\n"); if (scf_service_get_instance(svc, inaddr_any_name, instance) == 0) { /* Let the caller deal with the duplicate instance */ status = INSTANCE_ANY_EXISTS; goto out; } if (scf_service_add_instance(svc, instance_name, instance) != 0) { if (scf_error() == SCF_ERROR_EXISTS) { /* Let the caller deal with the duplicate instance */ status = INSTANCE_OTHER_EXISTS; goto out; } errflag = B_TRUE; KSSL_DEBUG("scf_service_add_instance failed: %s\n", scf_strerror(scf_error())); goto out; } KSSL_DEBUG("scf_service_add_instance succeeded\n"); if ((add_pg_method(handle, instance, kssl_entry, "start", command, username) != SUCCESS) || (add_pg_method(handle, instance, kssl_entry, "refresh", command, username) != SUCCESS) || (add_pg_method(handle, instance, kssl_entry, "stop", "", username) != SUCCESS)) { scf_instance_destroy(instance); return (status); } /* enabling the instance */ max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((buf = malloc(max_fmri_len + 1)) == NULL) goto out; if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { KSSL_DEBUG("instance_fmri=%s\n", buf); if (smf_enable_instance(buf, 0) != 0) { errflag = B_TRUE; KSSL_DEBUG( "smf_enable_instance failed: %s\n", scf_strerror(scf_error())); goto out; } status = SUCCESS; } out: if (instance != NULL) scf_instance_destroy(instance); if (errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
int main(int argc, char *argv[]) { int c; scf_walk_callback callback; int flags; int err; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); return_code = UU_EXIT_OK; (void) uu_setpname(argv[0]); prop_pool = uu_list_pool_create("properties", sizeof (svcprop_prop_node_t), offsetof(svcprop_prop_node_t, spn_list_node), NULL, 0); if (prop_pool == NULL) uu_die("%s\n", uu_strerror(uu_error())); prop_list = uu_list_create(prop_pool, NULL, 0); hndl = scf_handle_create(SCF_VERSION); if (hndl == NULL) scfdie(); while ((c = getopt(argc, argv, "Ccfp:qs:tvwz:")) != -1) { switch (c) { case 'C': if (cflag || sflag || wait) usage(); /* Not with -c, -s or -w */ Cflag++; snapshot = NULL; break; case 'c': if (Cflag || sflag || wait) usage(); /* Not with -C, -s or -w */ cflag++; snapshot = NULL; break; case 'f': types = 1; fmris = 1; break; case 'p': add_prop(optarg); break; case 'q': quiet = 1; warn = quiet_warn; die = quiet_die; break; case 's': if (Cflag || cflag || wait) usage(); /* Not with -C, -c or -w */ snapshot = optarg; sflag++; break; case 't': types = 1; break; case 'v': verbose = 1; break; case 'w': if (Cflag || cflag || sflag) usage(); /* Not with -C, -c or -s */ wait = 1; break; case 'z': { scf_value_t *zone; scf_handle_t *h = hndl; if (getzoneid() != GLOBAL_ZONEID) uu_die(gettext("svcprop -z may only be used " "from the global zone\n")); if ((zone = scf_value_create(h)) == NULL) scfdie(); if (scf_value_set_astring(zone, optarg) != SCF_SUCCESS) scfdie(); if (scf_handle_decorate(h, "zone", zone) != SCF_SUCCESS) uu_die(gettext("invalid zone '%s'\n"), optarg); scf_value_destroy(zone); break; } case '?': switch (optopt) { case 'p': usage(); default: break; } /* FALLTHROUGH */ default: usage(); } } if (optind == argc) usage(); max_scf_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); max_scf_value_length = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); max_scf_fmri_length = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if (max_scf_name_length == -1 || max_scf_value_length == -1 || max_scf_fmri_length == -1) scfdie(); if (scf_handle_bind(hndl) == -1) die(gettext("Could not connect to configuration repository: " "%s.\n"), scf_strerror(scf_error())); flags = SCF_WALK_PROPERTY | SCF_WALK_SERVICE | SCF_WALK_EXPLICIT; if (wait) { if (uu_list_numnodes(prop_list) > 1) usage(); if (argc - optind > 1) usage(); callback = do_wait; } else { callback = process_fmri; flags |= SCF_WALK_MULTIPLE; } if ((err = scf_walk_fmri(hndl, argc - optind, argv + optind, flags, callback, NULL, &return_code, warn)) != 0) { warn(gettext("failed to iterate over instances: %s\n"), scf_strerror(err)); return_code = UU_EXIT_FATAL; } scf_handle_destroy(hndl); return (return_code); }
int delete_instance(const char *instance_name) { int status = FAILURE; char *buf; boolean_t errflag = B_FALSE; ssize_t max_fmri_len; scf_scope_t *scope; scf_service_t *svc; scf_handle_t *handle; scf_instance_t *instance; handle = scf_handle_create(SCF_VERSION); if (handle == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_create failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_create succeeded\n"); if (scf_handle_bind(handle) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_bind failed: %s\n", scf_strerror(scf_error())); goto out1; } KSSL_DEBUG("scf_handle_bind succeeded\n"); if ((scope = scf_scope_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_scope_create failed: %s\n", scf_strerror(scf_error())); goto out2; } KSSL_DEBUG("scf_scope_create succeeded\n"); if ((svc = scf_service_create(handle)) == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_service_create failed: %s\n", scf_strerror(scf_error())); goto out3; } KSSL_DEBUG("scf_service_create succeeded\n"); if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1) { errflag = B_TRUE; KSSL_DEBUG("scf_handle_get_scope failed: %s\n", scf_strerror(scf_error())); goto out4; } KSSL_DEBUG("scf_handle_get_scope succeeded\n"); if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum != SCF_ERROR_NOT_FOUND) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } goto out4; } else { KSSL_DEBUG("scf_scope_get_service succeeded\n"); } instance = scf_instance_create(handle); if (instance == NULL) { errflag = B_TRUE; KSSL_DEBUG("scf_instance_create failed: %s\n", scf_strerror(scf_error())); goto out4; } if (scf_service_get_instance(svc, instance_name, instance) != 0) { scf_error_t scf_errnum = scf_error(); if (scf_errnum == SCF_ERROR_NOT_FOUND) { status = SUCCESS; } else { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_scope_get_service failed: %s\n", scf_strerror(scf_errnum)); } scf_instance_destroy(instance); goto out4; } max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((buf = malloc(max_fmri_len + 1)) == NULL) goto out4; if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) { char *state; KSSL_DEBUG("instance_fmri=%s\n", buf); state = smf_get_state(buf); if (state) KSSL_DEBUG("state=%s\n", state); if (state && strcmp(state, "online") == 0) { if (smf_disable_instance(buf, 0) != 0) { errflag = B_TRUE; KSSL_DEBUG( "smf_disable_instance failed: %s\n", scf_strerror(scf_error())); } else { /* * Wait for some time till timeout to avoid * a race with scf_instance_delete() below. */ wait_till_to(buf); } } } if (scf_instance_delete(instance) != 0) { errflag = B_TRUE; KSSL_DEBUG( "ERROR scf_instance_delete failed: %s\n", scf_strerror(scf_error())); goto out4; } else { KSSL_DEBUG("deleted %s\n", instance_name); } status = SUCCESS; out4: scf_service_destroy(svc); out3: scf_scope_destroy(scope); out2: (void) scf_handle_unbind(handle); out1: if (handle != NULL) scf_handle_destroy(handle); if (errflag) (void) fprintf(stderr, gettext( "Unexpected fatal libscf error: %s. Exiting.\n"), scf_strerror(scf_error())); return (status); }
static void modify_defaults(int argc, char *argv[]) { int i, j; char *value; scf_instance_t *inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; if ((inst = scf_instance_create(h)) == NULL) scfdie(); if (scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1) { if (scf_error() == SCF_ERROR_NOT_FOUND) { uu_die(gettext("inetd instance missing in repository." "\n")); } else { scfdie(); } } if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair \"%s" "\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of defaults */ for (j = 0; mod[j].ip_name != NULL; j++) { if (!mod[j].ip_default) continue; if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a default inetd " "property.\n"), argv[i]); if (*value == '\0') uu_die(gettext("Cannot accept NULL values for default " "properties.\n")); switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) uu_die(gettext("Error: Out of memory.\n")); break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; } commit_props(inst, mod, B_TRUE); free(mod); scf_instance_destroy(inst); if (refresh_inetd() != 0) uu_warn(gettext("Warning: Unable to refresh inetd.\n")); }
static int modify_inst_props_cb(void *data, scf_walkinfo_t *wip) { int i, j; char *value; const char *fmri = wip->fmri; scf_instance_t *inst = wip->inst; inetd_prop_t *mod, *prop_table; size_t numprops; ssize_t max_val; int64_t new_int; int argc = ((arglist_t *)data)->argc; char **argv = ((arglist_t *)data)->argv; if ((max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH)) < 0) scfdie(); prop_table = get_prop_table(&numprops); if ((mod = malloc(numprops * sizeof (inetd_prop_t))) == NULL) uu_die(gettext("Error: Out of memory.\n")); (void) memcpy(mod, prop_table, numprops * sizeof (inetd_prop_t)); /* * For each property to be changed, look up the property name in the * property table. Change each property in the mod array, and then * write the entire thing back. */ for (i = 0; i < argc; i++) { /* Separate argument into name and value pair */ if ((value = strchr(argv[i], '=')) == NULL) uu_die(gettext("Error: Malformed name=value pair " "\"%s\"\n"), argv[i]); *value = '\0'; value++; /* Find property name in array of properties */ for (j = 0; mod[j].ip_name != NULL; j++) { if (strcmp(mod[j].ip_name, argv[i]) == 0) break; } if (mod[j].ip_name == NULL) uu_die(gettext("Error: \"%s\" is not a valid " "property.\n"), argv[i]); if (*value == '\0') { if ((mod[j].ip_default) || (j == PT_ARG0_INDEX)) { /* mark property for deletion */ mod[j].ip_error = IVE_INVALID; /* return the '=' taken out above */ *(--value) = '='; continue; } else { uu_die(gettext("\"%s\" is a mandatory " "property and can not be deleted.\n"), argv[i]); } } switch (mod[j].ip_type) { case INET_TYPE_INTEGER: if (uu_strtoint(value, &new_int, sizeof (new_int), NULL, NULL, NULL) == -1) uu_die(gettext("Error: \"%s\" is not a valid " "integer value.\n"), value); mod[j].ip_value.iv_int = new_int; break; case INET_TYPE_STRING: if (strlen(value) >= max_val) { uu_die(gettext("Error: String value is longer " "than %l characters.\n"), max_val); } else if ((mod[j].ip_value.iv_string = strdup(value)) == NULL) { uu_die(gettext("Error: Out of memory.\n")); } break; case INET_TYPE_STRING_LIST: if ((mod[j].ip_value.iv_string_list = get_protos(value)) == NULL) { if (errno == ENOMEM) { uu_die(gettext( "Error: Out of memory.\n")); } else if (errno == E2BIG) { uu_die(gettext( "Error: String value in " "%s property longer than " "%l characters.\n"), PR_PROTO_NAME, max_val); } else { uu_die(gettext( "Error: No values " "specified for %s " "property.\n"), PR_PROTO_NAME); } } break; case INET_TYPE_BOOLEAN: if (strcasecmp(value, INETADM_TRUE_STR) == 0) mod[j].ip_value.iv_boolean = B_TRUE; else if (strcasecmp(value, INETADM_FALSE_STR) == 0) mod[j].ip_value.iv_boolean = B_FALSE; else uu_die(gettext("Error: \"%s\" is not a valid " "boolean value. (TRUE or FALSE)\n"), value); } /* mark property for modification */ mod[j].ip_error = IVE_VALID; /* return the '=' taken out above */ *(--value) = '='; } commit_props(inst, mod, B_FALSE); free(mod); if (smf_refresh_instance(fmri) != 0) uu_die(gettext("Error: Unable to refresh instance %s.\n"), fmri); return (0); }
/*ARGSUSED*/ static int list_callback(scf_handle_t *hin, scf_instance_t *inst, void *buf) { ssize_t max_name_length; char *inst_name; scf_simple_prop_t *prop = NULL, *prop2 = NULL; const uint8_t *enabled; const char *state, *restart_str; max_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH); if ((inst_name = malloc(max_name_length + 1)) == NULL) uu_die(gettext("Error: Out of memory.\n")); /* * Get the FMRI of the instance, and check if its delegated restarter * is inetd. */ if (scf_instance_to_fmri(inst, inst_name, max_name_length + 1) < 0) return (SCF_FAILED); if ((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL, SCF_PROPERTY_RESTARTER)) == NULL) goto out; if ((restart_str = scf_simple_prop_next_ustring(prop)) == NULL) goto out; if (strstr(restart_str, INETADM_INETD_STR) == NULL) goto out; /* Free restarter prop so it can be reused below */ scf_simple_prop_free(prop); /* * We know that this instance is managed by inetd. * Now get the enabled and state properties. */ if (((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL, SCF_PROPERTY_ENABLED)) == NULL) || ((enabled = scf_simple_prop_next_boolean(prop)) == NULL)) { (void) uu_warn(gettext("Error: Instance %s is missing enabled " "property.\n"), inst_name); goto out; } if (((prop2 = scf_simple_prop_get(hin, inst_name, SCF_PG_RESTARTER, SCF_PROPERTY_STATE)) == NULL) || ((state = scf_simple_prop_next_astring(prop2)) == NULL)) { (void) uu_warn(gettext("Error: Instance %s is missing state " "property.\n"), inst_name); goto out; } /* Print enabled/disabled, state, and FMRI for the instance. */ if (*enabled) (void) printf("%-10s%-15s%s\n", INETADM_ENABLED_STR, state, inst_name); else (void) printf("%-10s%-15s%s\n", INETADM_DISABLED_STR, state, inst_name); out: free(inst_name); scf_simple_prop_free(prop); scf_simple_prop_free(prop2); return (SCF_SUCCESS); }
static void modify_prop(const scf_instance_t *inst, const char *pg, const char *prop, scf_type_t type, void *value) { scf_transaction_t *tx; scf_transaction_entry_t *ent; scf_propertygroup_t *gpg; scf_property_t *eprop; scf_value_t *v; int ret, create = 0; char *fmri; ssize_t max_fmri_len; if ((gpg = scf_pg_create(h)) == NULL || (eprop = scf_property_create(h)) == NULL || (v = scf_value_create(h)) == NULL) scfdie(); /* Get the property group or create it if it is missing. */ if (scf_instance_get_pg(inst, pg, gpg) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH); if ((fmri = malloc(max_fmri_len + 1)) == NULL) uu_die(gettext("Error: Out of memory.\n")); if (scf_instance_to_fmri(inst, fmri, max_fmri_len + 1) < 0) scfdie(); syslog(LOG_NOTICE, "inetadm: Property group \"%s\" missing " "from \"%s\", attempting to add it.\n", pg, fmri); free(fmri); if (scf_instance_add_pg(inst, pg, SCF_GROUP_FRAMEWORK, 0, gpg) == -1) { switch (scf_error()) { case SCF_ERROR_EXISTS: break; case SCF_ERROR_PERMISSION_DENIED: uu_die(gettext("Error: Permission denied.\n")); default: scfdie(); } } } if (scf_pg_get_property(gpg, prop, eprop) == -1) { if (scf_error() != SCF_ERROR_NOT_FOUND) scfdie(); create = 1; } if ((tx = scf_transaction_create(h)) == NULL || (ent = scf_entry_create(h)) == NULL) scfdie(); do { uu_list_t *sv_list; if (scf_transaction_start(tx, gpg) == -1) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } /* Modify the property or create it if it is missing */ if (create) ret = scf_transaction_property_new(tx, ent, prop, type); else ret = scf_transaction_property_change_type(tx, ent, prop, type); if (ret == -1) scfdie(); switch (type) { case SCF_TYPE_BOOLEAN: scf_value_set_boolean(v, *(uint8_t *)value); break; case SCF_TYPE_INTEGER: scf_value_set_integer(v, *(int64_t *)value); break; case SCF_TYPE_ASTRING: if (strcmp(prop, PR_PROTO_NAME) == 0) { add_proto_list(ent, h, (char **)value, &sv_list); } else if (scf_value_set_astring(v, value) == -1) { scfdie(); } break; default: uu_die(gettext("Error: Internal inetadm error")); } if ((strcmp(prop, PR_PROTO_NAME) != 0) && (scf_entry_add_value(ent, v) == -1)) scfdie(); ret = scf_transaction_commit(tx); if (ret == -1) { if (scf_error() != SCF_ERROR_PERMISSION_DENIED) scfdie(); uu_die(gettext("Error: Permission denied.\n")); } scf_transaction_reset(tx); if (ret == 0) { if (scf_pg_update(gpg) == -1) scfdie(); } if (strcmp(prop, PR_PROTO_NAME) == 0) remove_proto_list(ent, sv_list); } while (ret == 0); scf_value_destroy(v); scf_entry_destroy(ent); scf_transaction_destroy(tx); scf_property_destroy(eprop); scf_pg_destroy(gpg); }
/* * 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); }