Example #1
0
/*
 * Gets an instance iterator for the service specified.
 */
smb_scfhandle_t *
smb_smf_get_iterator(char *svc_name)
{
	smb_scfhandle_t *handle = NULL;

	handle = smb_smf_scf_init(svc_name);
	if (!handle) {
		return (NULL);
	}

	handle->scf_inst_iter = scf_iter_create(handle->scf_handle);
	if (handle->scf_inst_iter) {
		if (scf_iter_service_instances(handle->scf_inst_iter,
		    handle->scf_service) != 0) {
			smb_smf_scf_fini(handle);
			handle = NULL;
		} else {
			handle->scf_instance = NULL;
		}
	} else {
		smb_smf_scf_fini(handle);
		handle = NULL;
	}
	return (handle);
}
Example #2
0
conerr_t
smfu_get_property(char *fmri, char *pgname, char *propname, char *value,
    size_t n)
{
	conerr_t err = ce_ok;
	scf_handle_t *scfhandle = handle_create();
	scf_service_t *service = scf_service_create(scfhandle);
	scf_instance_t *instance = scf_instance_create(scfhandle);
	scf_propertygroup_t *pg = scf_pg_create(scfhandle);
	scf_property_t *prop = scf_property_create(scfhandle);
	scf_iter_t *iter = scf_iter_create(scfhandle);
	scf_value_t *val = scf_value_create(scfhandle);

	if (scfhandle == NULL || service == NULL || instance == NULL ||
	    pg == NULL || prop == NULL || iter == NULL || val == NULL) {
		err = ce_nomem;
		goto out;
	}

	if (scf_handle_decode_fmri(scfhandle, fmri, NULL, service, instance,
	    NULL, NULL, 0) != SCF_SUCCESS) {
		rad_log(RL_ERROR, "couldn't decode '%s': %s\n", fmri,
		    scf_strerror(scf_error()));
		err = maperr(scf_error());
		goto out;
	}

	if (scf_instance_get_pg(instance, pgname, pg) != 0 ||
	    scf_pg_get_property(pg, propname, prop) != 0 ||
	    scf_iter_property_values(iter, prop) != 0) {
		rad_log(RL_ERROR, "couldn't get property: '%s/%s/%s': %s\n",
		    fmri, pgname, propname, scf_strerror(scf_error()));
		err = maperr(scf_error());
		goto out;
	}

	if (scf_iter_next_value(iter, val) > 0 &&
	    scf_value_get_as_string(val, value, n) == -1) {
		rad_log(RL_ERROR,
		    "couldn't get property value: '%s/%s/%s': %s\n", fmri,
		    pgname, propname, scf_strerror(scf_error()));
		err = maperr(scf_error());
		goto out;
	}
out:
	scf_value_destroy(val);
	scf_property_destroy(prop);
	scf_pg_destroy(pg);
	scf_iter_destroy(iter);
	scf_instance_destroy(instance);
	scf_service_destroy(service);
	scf_handle_destroy(scfhandle);

	return (err);
}
Example #3
0
/*
 * Initialize the global state for the load_*() routines.
 * Returns
 *   0 - success
 *   ENOMEM - out of memory
 */
int
load_init(void)
{
	loadbuf_sz = ((max_scf_value_len > max_scf_pg_type_len) ?
	    max_scf_value_len : max_scf_pg_type_len) + 1;

	loadbuf = malloc(loadbuf_sz);
	if (loadbuf == NULL)
		return (ENOMEM);

	if ((load_prop = scf_property_create(g_hndl)) == NULL ||
	    (load_val = scf_value_create(g_hndl)) == NULL ||
	    (load_propiter = scf_iter_create(g_hndl)) == NULL ||
	    (load_valiter = scf_iter_create(g_hndl)) == NULL) {
		load_fini();
		return (ENOMEM);
	}

	return (0);
}
Example #4
0
/*
 * display_prop() all of the properties in the given property group.  Force
 * types to true so identification will be displayed.
 */
static void
display_pg(scf_propertygroup_t *pg)
{
	scf_property_t *prop;
	scf_iter_t *iter;
	int ret;

	types = 1;	/* Always display types for whole propertygroups. */

	if ((prop = scf_property_create(hndl)) == NULL ||
	    (iter = scf_iter_create(hndl)) == NULL)
		scfdie();

	if (scf_iter_pg_properties(iter, pg) == -1)
		scfdie();

	while ((ret = scf_iter_next_property(iter, prop)) == 1)
		display_prop(pg, prop);
	if (ret == -1)
		scfdie();

	scf_iter_destroy(iter);
	scf_property_destroy(prop);
}
Example #5
0
/*
 * 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);
}
Example #6
0
/*
 * mgmt_config_save2scf() saves main configuration to scf
 * See also : mgmt_get_main_config()
 */
Boolean_t
mgmt_config_save2scf()
{
	targ_scf_t *h = NULL;
	scf_property_t *prop = NULL;
	scf_value_t *value = NULL;
	scf_iter_t *iter = NULL;
	char pgname[64];
	char passcode[32];
	unsigned int	outlen;
	tgt_node_t	*n = NULL;
	tgt_node_t	*pn = NULL;
	tgt_node_t	*tn = NULL;
	scf_transaction_t *tx = NULL;
	secret_list_t	*sl_head;
	secret_list_t	*sl_tail;

	h = mgmt_handle_init();

	if (h == NULL)
		return (False);

	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);

	if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) {
		scf_pg_delete(h->t_pg);
		mgmt_transaction_end(h);
	}

	if (mgmt_transaction_start(h, "passwords", "application") == True) {
		scf_pg_delete(h->t_pg);
		mgmt_transaction_end(h);
	}

	if (scf_iter_service_pgs_typed(iter, h->t_service, "configuration")
	    == -1) {
		goto error;
	}

	tx = scf_transaction_create(h->t_handle);
	while (scf_iter_next_pg(iter, h->t_pg) > 0) {
		scf_transaction_start(tx, h->t_pg);
		scf_pg_delete(h->t_pg);
		scf_transaction_commit(tx);
	}
	scf_transaction_reset(tx);
	scf_transaction_destroy(tx);

	sl_head = (secret_list_t *)calloc(1, sizeof (secret_list_t));
	sl_tail = sl_head;

	if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) {
		for (n = main_config->x_child; n; n = n->x_sibling) {
			if (strcmp(n->x_name,
			    XML_ELEMENT_CHAPSECRET) == 0) {
				sl_tail->next =  (secret_list_t *)
				    calloc(1, sizeof (secret_list_t));
				sl_tail = sl_tail->next;
				sl_tail->name = strdup("main");
				sl_tail->secret = strdup(n->x_value);
				continue;
			}
			/* so does the radius server secret */
			if (strcmp(n->x_name,
			    XML_ELEMENT_RAD_SECRET) == 0) {
				sl_tail->next =  (secret_list_t *)
				    calloc(1, sizeof (secret_list_t));
				sl_tail = sl_tail->next;
				sl_tail->name = strdup("radius");
				sl_tail->secret = strdup(n->x_value);
				continue;
			}
			if (n->x_child == NULL) {
				new_property(h, n);
			}
		}
		new_property(h, main_config->x_attr);
		n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
		    ISCSI_AUTH_MODIFY);
		new_property(h, n);
		tgt_node_free(n);
		n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
		    ISCSI_AUTH_VALUE);
		new_property(h, n);
		tgt_node_free(n);
		mgmt_transaction_end(h);
	}

	/* now update target/initiator/tpgt information */
	for (n = main_config->x_child; n; n = n->x_sibling) {
		if (n->x_child == NULL)
			continue;

		snprintf(pgname, sizeof (pgname), "%s_%s", n->x_name,
		    n->x_value);

		if (mgmt_transaction_start(h, pgname, "configuration")
		    == True) {
			for (pn = n->x_child; pn; pn = pn->x_sibling) {
				if (strcmp(pn->x_name,
				    XML_ELEMENT_CHAPSECRET) == 0) {
					sl_tail->next =  (secret_list_t *)
					    calloc(1, sizeof (secret_list_t));
					sl_tail = sl_tail->next;
					sl_tail->name = (char *)
					    calloc(1, strlen(n->x_value) + 3);
					snprintf(sl_tail->name,
					    strlen(n->x_value) + 3,
					    "I_%s", n->x_value);
					sl_tail->secret = strdup(pn->x_value);
					continue;
				}
				if (pn->x_child == NULL) {
					/* normal property */
					new_property(h, pn);
				} else {
					/* pn -> xxx-list */
					new_value_list(h, pn);
				}
				tn = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME,
				    String, ISCSI_AUTH_MODIFY);
				new_property(h, tn);
				tgt_node_free(tn);
				tn = tgt_node_alloc(ISCSI_VALUE_AUTHNAME,
				    String, ISCSI_AUTH_VALUE);
				new_property(h, tn);
				tgt_node_free(tn);
			}
			mgmt_transaction_end(h);
		}
	}

	if (mgmt_transaction_start(h, "passwords", "application") == True) {
		while (sl_head != NULL) {
			/* Here we use sl_tail as a temporari var */
			sl_tail = sl_head->next;
			if (sl_head->name) {
				/* max length of encoded passwd is 24B */
				sasl_encode64(sl_head->secret,
				    strlen(sl_head->secret), passcode,
				    sizeof (passcode), &outlen);

				n = tgt_node_alloc(sl_head->name, String,
				    passcode);
				new_property(h, n);
				tgt_node_free(n);
			}
			if (sl_head->name)
				free(sl_head->name);
			if (sl_head->secret)
				free(sl_head->secret);
			free(sl_head);
			sl_head = sl_tail;
		}
		n = tgt_node_alloc(ISCSI_READ_AUTHNAME, String,
		    ISCSI_AUTH_READ);
		new_property(h, n);
		tgt_node_free(n);
		n = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
		    ISCSI_AUTH_VALUE);
		new_property(h, n);
		tgt_node_free(n);
		n = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
		    ISCSI_AUTH_MODIFY);
		new_property(h, n);
		tgt_node_free(n);
		mgmt_transaction_end(h);
	}

	if (smf_refresh_instance(SA_TARGET_SVC_INSTANCE_FMRI) != 0)
		goto error;

	(void) pthread_mutex_unlock(&scf_conf_mutex);
	scf_iter_destroy(iter);
	scf_value_destroy(value);
	scf_property_destroy(prop);
	return (True);

error:
	(void) pthread_mutex_unlock(&scf_conf_mutex);
	scf_iter_destroy(iter);
	scf_value_destroy(value);
	scf_property_destroy(prop);
	mgmt_handle_fini(h);
	return (False);
}
Example #7
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);
}
Example #8
0
/*
 * Entity (service or instance): If there are -p options,
 * display_{pg,prop}() the named property groups and/or properties.  Otherwise
 * display_pg() all property groups.
 */
static void
process_ent(scf_entityp_t ent)
{
	scf_snapshot_t *snap = NULL;
	scf_propertygroup_t *pg;
	scf_property_t *prop;
	scf_iter_t *iter;
	svcprop_prop_node_t *spn;
	int ret, err;

	if (uu_list_numnodes(prop_list) == 0) {
		if (quiet)
			return;

		if ((pg = scf_pg_create(hndl)) == NULL ||
		    (iter = scf_iter_create(hndl)) == NULL)
			scfdie();

		if (cflag || Cflag || ent.type != ENT_INSTANCE) {
			if (scf_iter_entity_pgs(iter, ent) == -1)
				scfdie();
		} else {
			if (snapshot != NULL)
				snap = get_snapshot(ent.u.inst, snapshot);

			if (scf_iter_instance_pgs_composed(iter, ent.u.inst,
			    snap) == -1)
				scfdie();
			if (snap)
				scf_snapshot_destroy(snap);
		}

		while ((ret = scf_iter_next_pg(iter, pg)) == 1)
			display_pg(pg);
		if (ret == -1)
			scfdie();

		/*
		 * In normal usage, i.e. against the running snapshot,
		 * we must iterate over the current non-persistent
		 * pg's.
		 */
		if (sflag == 0 && snap != NULL) {
			scf_iter_reset(iter);
			if (scf_iter_instance_pgs_composed(iter, ent.u.inst,
			    NULL) == -1)
				scfdie();
			while ((ret = scf_iter_next_pg(iter, pg)) == 1) {
				uint32_t flags;

				if (scf_pg_get_flags(pg, &flags) == -1)
					scfdie();
				if (flags & SCF_PG_FLAG_NONPERSISTENT)
					display_pg(pg);
			}
		}
		if (ret == -1)
			scfdie();

		scf_iter_destroy(iter);
		scf_pg_destroy(pg);

		return;
	}

	if ((pg = scf_pg_create(hndl)) == NULL ||
	    (prop = scf_property_create(hndl)) == NULL)
		scfdie();

	if (ent.type == ENT_INSTANCE && snapshot != NULL)
		snap = get_snapshot(ent.u.inst, snapshot);

	for (spn = uu_list_first(prop_list);
	    spn != NULL;
	    spn = uu_list_next(prop_list, spn)) {
		if (ent.type == ENT_INSTANCE) {
			if (Cflag)
				ret = scf_instance_get_pg(ent.u.inst,
				    spn->spn_comp1, pg);
			else
				ret = scf_instance_get_pg_composed(ent.u.inst,
				    snap, spn->spn_comp1, pg);
			err = scf_error();

			/*
			 * If we didn't find it in the specified snapshot, use
			 * the current values if the pg is nonpersistent.
			 */
			if (ret == -1 && !Cflag &&snap != NULL && err ==
			    SCF_ERROR_NOT_FOUND) {
				ret = scf_instance_get_pg_composed(
				    ent.u.inst, NULL, spn->spn_comp1,
				    pg);

				if (ret == 0) {
					uint32_t flags;

					if (scf_pg_get_flags(pg, &flags) == -1)
						scfdie();
					if ((flags & SCF_PG_FLAG_NONPERSISTENT)
					    == 0) {
						ret = -1;
					}
				}
			}
		} else {
			/*
			 * If we are displaying properties for a service,
			 * treat it as though it were a composed, current
			 * lookup. (implicit cflag) However, if a snapshot
			 * was specified, fail.
			 */
			if (sflag)
				die(gettext("Only instances have "
				    "snapshots.\n"));
			ret = scf_entity_get_pg(ent, spn->spn_comp1, pg);
			err = scf_error();
		}
		if (ret == -1) {
			if (err != SCF_ERROR_NOT_FOUND)
				scfdie();

			if (PRINT_NOPROP_ERRORS) {
				char *buf;

				buf = safe_malloc(max_scf_fmri_length + 1);
				if (scf_entity_to_fmri(ent, buf,
				    max_scf_fmri_length + 1) == -1)
					scfdie();

				uu_warn(gettext("Couldn't find property group "
				    "`%s' for %s `%s'.\n"), spn->spn_comp1,
				    SCF_ENTITY_TYPE_NAME(ent), buf);

				free(buf);
			}

			noprop_common_action();

			continue;
		}

		if (spn->spn_comp2 == NULL) {
			if (!quiet)
				display_pg(pg);
			continue;
		}

		if (scf_pg_get_property(pg, spn->spn_comp2, prop) == -1) {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			if (PRINT_NOPROP_ERRORS) {
				char *buf;

				buf = safe_malloc(max_scf_fmri_length + 1);
				if (scf_entity_to_fmri(ent, buf,
				    max_scf_fmri_length + 1) == -1)
					scfdie();

				/* FMRI syntax knowledge */
				uu_warn(gettext("Couldn't find property "
				    "`%s/%s' for %s `%s'.\n"), spn->spn_comp1,
				    spn->spn_comp2, SCF_ENTITY_TYPE_NAME(ent),
				    buf);

				free(buf);
			}

			noprop_common_action();

			continue;
		}

		if (!quiet)
			display_prop(pg, prop);
	}

	scf_property_destroy(prop);
	scf_pg_destroy(pg);
	if (snap)
		scf_snapshot_destroy(snap);
}
Example #9
0
/*
 * 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);
}
Example #10
0
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);
}
Example #11
0
File: mgmt_scf.c Project: imp/slist
/*
 * 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);
}