/*
 * 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);
}
Example #2
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 #3
0
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);
}
Example #4
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);
}