/* * Returns * 0 - success * ECANCELED - pg was deleted * ECONNABORTED - repository disconnected * ENOMEM - out of memory */ int load_pg_attrs(const scf_propertygroup_t *pg, pgroup_t **ipgp) { pgroup_t *ipg; ipg = internal_pgroup_new(); if (scf_pg_get_flags(pg, &ipg->sc_pgroup_flags) != 0) { switch (scf_error()) { case SCF_ERROR_DELETED: internal_pgroup_free(ipg); return (ECANCELED); case SCF_ERROR_CONNECTION_BROKEN: internal_pgroup_free(ipg); return (ECONNABORTED); case SCF_ERROR_NOT_SET: case SCF_ERROR_NOT_BOUND: default: bad_error("scf_pg_get_name", scf_error()); } } if (scf_pg_get_name(pg, loadbuf, loadbuf_sz) < 0) { switch (scf_error()) { case SCF_ERROR_DELETED: internal_pgroup_free(ipg); return (ECANCELED); case SCF_ERROR_CONNECTION_BROKEN: internal_pgroup_free(ipg); return (ECONNABORTED); case SCF_ERROR_NOT_SET: case SCF_ERROR_NOT_BOUND: default: bad_error("scf_pg_get_name", scf_error()); } } ipg->sc_pgroup_name = strdup(loadbuf); if (ipg->sc_pgroup_name == NULL) { internal_pgroup_free(ipg); return (ENOMEM); } if (scf_pg_get_type(pg, loadbuf, loadbuf_sz) < 0) { switch (scf_error()) { case SCF_ERROR_DELETED: free((char *)ipg->sc_pgroup_name); internal_pgroup_free(ipg); return (ECANCELED); case SCF_ERROR_CONNECTION_BROKEN: free((char *)ipg->sc_pgroup_name); internal_pgroup_free(ipg); return (ECONNABORTED); case SCF_ERROR_NOT_SET: case SCF_ERROR_NOT_BOUND: default: bad_error("scf_pg_get_name", scf_error()); } } ipg->sc_pgroup_type = strdup(loadbuf); if (ipg->sc_pgroup_type == NULL) { free((char *)ipg->sc_pgroup_name); internal_pgroup_free(ipg); return (ENOMEM); } *ipgp = ipg; return (0); }
/* * 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); }
static int is_correct_event(const char *fmri, const scf_propertygroup_t *pg, const boolean_t isrpc) { char *state = NULL; const char **proplist = all_props; int prop_cnt = ALL_PROPS_CNT; int i, ret = 0; if (scf_pg_get_name(pg, scratch_name, max_scf_name_size) < 0) { syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_name failed: %s\n", scf_strerror(scf_error())); return (-1); } /* * We care about enable, disable, and refresh since that's * when we activate, deactivate, or change firewall policy. * * - enable/disable -> change in "general" or "general_ovr" * - refresh/restart -> change in "restarter_actions" */ if (strcmp(scratch_name, SCF_PG_GENERAL) == 0 || strcmp(scratch_name, SCF_PG_GENERAL_OVR) == 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s", scratch_name); return (1); } if ((state = smf_get_state(fmri)) == NULL) { syslog(LOG_ERR | LOG_DAEMON, "smf_get_state failed for %s: " "%s\n", fmri, scf_strerror(scf_error())); return (-1); } syslog(LOG_DEBUG | LOG_DAEMON, "%s STATE: %s \n", fmri, state); if (strcmp(state, SCF_STATE_STRING_MAINT) == 0) { proplist = maint_props; prop_cnt = MAINT_PROPS_CNT; } /* * Only concerned with refresh, restart, and maint on|off actions. * RPC services are restarted whenever rpc/bind restarts so it's * an automatic valid event for RPC services. */ if (isrpc) { ret = 1; goto out; } else if (strcmp(scratch_name, SCF_PG_RESTARTER_ACTIONS) == 0) { for (i = 0; i < prop_cnt; i++) { if (pg_get_prop_value(pg, proplist[i], scratch_v) == 0) { syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s/%s", scratch_name, proplist[i]); ret = 1; goto out; } } } out: if (state) free(state); return (ret); }
/* * Display a property's values on a line. If types is true, prepend * identification (the FMRI if fmris is true, pg/prop otherwise) and the type * of the property. */ static void display_prop(scf_propertygroup_t *pg, scf_property_t *prop) { scf_value_t *val; scf_iter_t *iter; int ret, first, err; const char * const permission_denied_emsg = gettext("Permission denied.\n"); if (types) { scf_type_t ty; char *buf; size_t buf_sz; if (fmris) { buf_sz = max_scf_fmri_length + 1; buf = safe_malloc(buf_sz); if (scf_property_to_fmri(prop, buf, buf_sz) == -1) scfdie(); (void) fputs(buf, stdout); free(buf); } else { buf_sz = max_scf_name_length + 1; buf = safe_malloc(buf_sz); if (scf_pg_get_name(pg, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); (void) putchar('/'); if (scf_property_get_name(prop, buf, buf_sz) < 0) scfdie(); (void) fputs(buf, stdout); free(buf); } (void) putchar(' '); if (scf_property_type(prop, &ty) == -1) scfdie(); (void) fputs(scf_type_to_string(ty), stdout); (void) putchar(' '); } if ((iter = scf_iter_create(hndl)) == NULL || (val = scf_value_create(hndl)) == NULL) scfdie(); if (scf_iter_property_values(iter, prop) == -1) scfdie(); first = 1; while ((ret = scf_iter_next_value(iter, val)) == 1) { if (first) first = 0; else (void) putchar(' '); print_value(val); } if (ret == -1) { err = scf_error(); if (err == SCF_ERROR_PERMISSION_DENIED) { if (uu_list_numnodes(prop_list) > 0) die(permission_denied_emsg); } else { scfdie(); } } (void) putchar('\n'); scf_iter_destroy(iter); (void) scf_value_destroy(val); }