Beispiel #1
0
static Boolean_t
create_pg(targ_scf_t *h, char *pgname, char *prop)
{
	if (scf_service_get_pg(h->t_service, pgname, h->t_pg) != 0) {
		if (scf_service_add_pg(h->t_service, pgname,
		    prop, 0, h->t_pg) != 0) {
			return (False);
		}
	}
	return (True);
}
Beispiel #2
0
/*
 * smb_smf_delete_service_pgroup(handle, pgroup)
 *
 * remove the property group from the current service.
 * but only if it actually exists.
 */
int
smb_smf_delete_service_pgroup(smb_scfhandle_t *handle, char *pgroup)
{
	int ret = SMBC_SMF_OK;
	int err;

	if (handle == NULL) {
		return (SMBC_SMF_SYSTEM_ERR);
	}

	/*
	 * only create a handle if it doesn't exist. It is ok to exist
	 * since the pg handle will be set as a side effect.
	 */
	if (handle->scf_pg == NULL) {
		handle->scf_pg = scf_pg_create(handle->scf_handle);
	}

	/*
	 * only delete if it does exist.
	 */
	if (scf_service_get_pg(handle->scf_service,
	    pgroup, handle->scf_pg) == 0) {
		/* does exist so delete it */
		if (scf_pg_delete(handle->scf_pg) != 0) {
			ret = SMBC_SMF_SYSTEM_ERR;
			err = scf_error();
			if (err != SCF_ERROR_NONE) {
				smb_smf_scf_log_error("SMF delpg "
				    "problem: %s\n");
			}
		}
	} else {
		err = scf_error();
		if (err != SCF_ERROR_NONE)
			smb_smf_scf_log_error("SMF getpg problem: %s\n");
		ret = SMBC_SMF_SYSTEM_ERR;
	}
	if (ret == SMBC_SMF_SYSTEM_ERR &&
	    scf_error() == SCF_ERROR_PERMISSION_DENIED) {
		ret = SMBC_SMF_NO_PERMISSION;
	}
	return (ret);
}
Beispiel #3
0
/*
 * smb_smf_create_service_pgroup(handle, pgroup)
 *
 * create a new property group at service level.
 */
int
smb_smf_create_service_pgroup(smb_scfhandle_t *handle, char *pgroup)
{
	int ret = SMBD_SMF_OK;
	int err;

	if (handle == NULL)
		return (SMBD_SMF_SYSTEM_ERR);

	/*
	 * only create a handle if it doesn't exist. It is ok to exist
	 * since the pg handle will be set as a side effect.
	 */
	if (handle->scf_pg == NULL)
		if ((handle->scf_pg =
		    scf_pg_create(handle->scf_handle)) == NULL)
			return (SMBD_SMF_SYSTEM_ERR);

	/*
	 * if the pgroup exists, we are done. If it doesn't, then we
	 * need to actually add one to the service instance.
	 */
	if (scf_service_get_pg(handle->scf_service,
	    pgroup, handle->scf_pg) != 0) {
		/* doesn't exist so create one */
		if (scf_service_add_pg(handle->scf_service, pgroup,
		    SCF_GROUP_APPLICATION, 0, handle->scf_pg) != 0) {
			err = scf_error();
			if (err != SCF_ERROR_NONE)
				smb_smf_scf_log_error(NULL);
			switch (err) {
			case SCF_ERROR_PERMISSION_DENIED:
				ret = SMBD_SMF_NO_PERMISSION;
				break;
			default:
				ret = SMBD_SMF_SYSTEM_ERR;
				break;
			}
		}
	}
	return (ret);
}
Beispiel #4
0
static Boolean_t
create_pg(targ_scf_t *h, char *pgname, char *prop)
{
	int len;
	char *buf = NULL;

	len = strlen(pgname);
	buf = (char *)calloc(1, len * PG_FACTOR);
	if (buf == NULL)
		return (False);

	pgname_encode(pgname, buf, len * PG_FACTOR);

	if (scf_service_get_pg(h->t_service, buf, h->t_pg) != 0) {
		if (scf_service_add_pg(h->t_service, buf,
		    prop, 0, h->t_pg) != 0) {
			free(buf);
			return (False);
		}
	}
	free(buf);
	return (True);
}
Beispiel #5
0
/*
 * this function tries to convert configuration in files into scf
 * it loads xml conf into node tree then dump them to scf with
 * mgmt_config_save2scf()
 * this function has 3 return values:
 * CONVERT_OK: successfully converted
 * CONVERT_INIT_NEW: configuration files dont exist, created a new scf entry
 * CONVERT_FAIL: some error occurred in conversion and no scf entry created.
 *               In this case, user have to check files manually and try
 *               conversion again.
 */
convert_ret_t
mgmt_convert_conf()
{
	targ_scf_t		*h = NULL;
	xmlTextReaderPtr	r;
	convert_ret_t		ret = CONVERT_FAIL;
	int			xml_fd = -1;
	int			n;
	tgt_node_t		*node = NULL;
	tgt_node_t		*next = NULL;
	char			path[MAXPATHLEN];
	char			*target = NULL;

	h = mgmt_handle_init();
	if (h == NULL)
		return (CONVERT_FAIL);

	/* check main config in pgroup iscsitgt */
	if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == 0) {
		ret = CONVERT_OK;
		goto done;
	}

	/* check the conf files */
	if (access(config_file, R_OK) != 0) {
		/*
		 * if there is no configuration file, initialize
		 * an empty scf entry
		 */
		if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) {
			ret = CONVERT_INIT_NEW;

			node = tgt_node_alloc(XML_ELEMENT_VERS, String, "1.0");
			new_property(h, node);
			tgt_node_free(node);
			/* "daemonize" is set to true by default */
			node = tgt_node_alloc(XML_ELEMENT_DBGDAEMON, String,
			    "true");
			new_property(h, node);
			tgt_node_free(node);
			node = NULL;
			node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
			    ISCSI_AUTH_MODIFY);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
			    ISCSI_AUTH_VALUE);
			new_property(h, node);
			tgt_node_free(node);
			mgmt_transaction_end(h);
		} else {
			syslog(LOG_ERR, "Creating empty entry failed");
			ret = CONVERT_FAIL;
			goto done;
		}
		if (mgmt_transaction_start(h, "passwords", "application") ==
		    True) {
			node = tgt_node_alloc(ISCSI_READ_AUTHNAME, String,
			    ISCSI_AUTH_READ);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
			    ISCSI_AUTH_MODIFY);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
			    ISCSI_AUTH_VALUE);
			new_property(h, node);
			tgt_node_free(node);
			mgmt_transaction_end(h);
		} else {
			syslog(LOG_ERR, "Creating empty entry failed");
			ret = CONVERT_FAIL;
		}
		goto done;
	}

	if ((xml_fd = open(config_file, O_RDONLY)) >= 0)
		r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0);

	if (r != NULL) {
		n = xmlTextReaderRead(r);
		while (n == 1) {
			if (tgt_node_process(r, &node) == False) {
				break;
			}
			n = xmlTextReaderRead(r);
		}
		if (n < 0) {
			syslog(LOG_ERR, "Parsing main config failed");
			ret = CONVERT_FAIL;
			goto done;
		}

		main_config = node;

		(void) tgt_find_value_str(node, XML_ELEMENT_BASEDIR,
		    &target_basedir);

		if (target_basedir == NULL)
			target_basedir = strdup(DEFAULT_TARGET_BASEDIR);

		/* Now convert targets' config if possible */
		if (xml_fd != -1)
			(void) close(xml_fd);
		xmlTextReaderClose(r);
		xmlFreeTextReader(r);
		xmlCleanupParser();
		r = NULL;
		xml_fd = -1;
		node = NULL;

		(void) snprintf(path, MAXPATHLEN, "%s/%s",
		    target_basedir, "config.xml");

		if ((xml_fd = open(path, O_RDONLY)) >= 0)
			r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd,
			    NULL, NULL, 0);

		if (r != NULL) {
			n = xmlTextReaderRead(r);
			while (n == 1) {
				if (tgt_node_process(r, &node) == False) {
					break;
				}
				n = xmlTextReaderRead(r);
			}
			if (n < 0) {
				syslog(LOG_ERR, "Parsing target conf failed");
				ret = CONVERT_FAIL;
				goto done;
			}

			/* now combine main_config and node */
			if (node) {
				next = NULL;
				while ((next = tgt_node_next(node,
				    XML_ELEMENT_TARG, next)) != NULL) {
					tgt_node_add(main_config,
					    tgt_node_dup(next));
				}
				tgt_node_free(node);
			}

			if (mgmt_config_save2scf() != True) {
				syslog(LOG_ERR, "Converting config failed");
				if (xml_fd != -1)
					(void) close(xml_fd);
				xmlTextReaderClose(r);
				xmlFreeTextReader(r);
				xmlCleanupParser();
				ret = CONVERT_FAIL;
				goto done;
			}

			/* Copy files into backup dir */
			(void) snprintf(path, sizeof (path), "%s/backup",
			    target_basedir);
			if ((mkdir(path, 0755) == -1) && (errno != EEXIST)) {
				syslog(LOG_ERR, "Creating backup dir failed");
				ret = CONVERT_FAIL;
				goto done;
			}
			backup(config_file, NULL);
			(void) snprintf(path, MAXPATHLEN, "%s/%s",
			    target_basedir, "config.xml");
			backup(path, NULL);


			while ((next = tgt_node_next(main_config,
			    XML_ELEMENT_TARG, next)) != NULL) {
				if (tgt_find_value_str(next, XML_ELEMENT_INAME,
				    &target) == False) {
					continue;
				}
				(void) snprintf(path, MAXPATHLEN, "%s/%s",
				    target_basedir, target);
				if (mgmt_convert_param(path, next)
				    != True) {
					ret = CONVERT_FAIL;
					goto done;
				}
				free(target);
			}

			ret = CONVERT_OK;
			syslog(LOG_NOTICE, "Conversion succeeded");

			xmlTextReaderClose(r);
			xmlFreeTextReader(r);
			xmlCleanupParser();
		} else {
			syslog(LOG_ERR, "Reading targets config failed");
			ret = CONVERT_FAIL;
			goto done;
		}
	} else {
		syslog(LOG_ERR, "Reading main config failed");
		ret = CONVERT_FAIL;
		goto done;
	}

done:
	if (xml_fd != -1)
		(void) close(xml_fd);
	mgmt_handle_fini(h);
	return (ret);
}
Beispiel #6
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);
}
Beispiel #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);
}
Beispiel #8
0
/* ARGSUSED */
static int
do_wait(void *unused, scf_walkinfo_t *wip)
{
	scf_property_t *prop;
	scf_propertygroup_t *lpg, *pg;
	const char *propname;
	svcprop_prop_node_t *p;

	const char *emsg_not_found = gettext("Not found.\n");

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

	if (wip->prop != NULL) {
		if (uu_list_numnodes(prop_list) > 0)
			uu_xdie(UU_EXIT_USAGE, gettext("-p cannot be used with "
			    "property FMRIs.\n"));
		pg = wip->pg;

		assert(strrchr(wip->fmri, '/') != NULL);
		propname = strrchr(wip->fmri, '/') + 1;

	} else if (wip->pg != NULL) {
		p = uu_list_first(prop_list);

		if (p != NULL) {
			if (p->spn_comp2 != NULL)
				uu_xdie(UU_EXIT_USAGE, gettext("-p argument "
				    "\"%s/%s\" has too many components for "
				    "property group %s.\n"),
				    p->spn_comp1, p->spn_comp2, wip->fmri);

			propname = p->spn_comp1;

			if (scf_pg_get_property(wip->pg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

					/* NOTREACHED */

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		} else {
			propname = NULL;
		}

		pg = wip->pg;

	} else if (wip->inst != NULL) {

		p = uu_list_first(prop_list);
		if (p == NULL)
			uu_xdie(UU_EXIT_USAGE,
			    gettext("Cannot wait for an instance.\n"));

		if (scf_instance_get_pg(wip->inst, p->spn_comp1, lpg) !=
		    SCF_SUCCESS) {
			switch (scf_error()) {
			case SCF_ERROR_INVALID_ARGUMENT:
				uu_xdie(UU_EXIT_USAGE, gettext("Invalid "
				    "property group name \"%s\".\n"),
				    p->spn_comp1);

			case SCF_ERROR_NOT_FOUND:
				die(emsg_not_found);

				/* NOTREACHED */

			default:
				scfdie();
			}
		}

		propname = p->spn_comp2;

		if (propname != NULL) {
			if (scf_pg_get_property(lpg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		}

		pg = lpg;

	} else if (wip->svc != NULL) {

		p = uu_list_first(prop_list);
		if (p == NULL)
			uu_xdie(UU_EXIT_USAGE,
			    gettext("Cannot wait for a service.\n"));

		if (scf_service_get_pg(wip->svc, p->spn_comp1, lpg) !=
		    SCF_SUCCESS) {
			switch (scf_error()) {
			case SCF_ERROR_INVALID_ARGUMENT:
				uu_xdie(UU_EXIT_USAGE, gettext("Invalid "
				    "property group name \"%s\".\n"),
				    p->spn_comp1);

			case SCF_ERROR_NOT_FOUND:
				die(emsg_not_found);

			default:
				scfdie();
			}
		}

		propname = p->spn_comp2;

		if (propname != NULL) {
			if (scf_pg_get_property(lpg, propname, prop) !=
			    SCF_SUCCESS) {
				switch (scf_error()) {
				case SCF_ERROR_INVALID_ARGUMENT:
					uu_xdie(UU_EXIT_USAGE,
					    gettext("Invalid property name "
					    "\"%s\".\n"), propname);

					/* NOTREACHED */

				case SCF_ERROR_NOT_FOUND:
					die(emsg_not_found);

					/* NOTREACHED */

				default:
					scfdie();
				}
			}
		}

		pg = lpg;

	} else {
		uu_xdie(UU_EXIT_USAGE, gettext("FMRI must specify an entity, "
		    "property group, or property.\n"));
	}

	for (;;) {
		int ret;

		ret = _scf_pg_wait(pg, -1);
		if (ret != SCF_SUCCESS)
			scfdie();

		ret = scf_pg_update(pg);
		if (ret < 0) {
			if (scf_error() != SCF_ERROR_DELETED)
				scfdie();

			die(emsg_not_found);
		}
		if (ret == SCF_COMPLETE)
			break;
	}

	if (propname != NULL) {
		if (scf_pg_get_property(pg, propname, prop) == SCF_SUCCESS) {
			if (!quiet)
				display_prop(pg, prop);
		} else {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			if (PRINT_NOPROP_ERRORS)
				uu_warn(emsg_not_found);

			return_code = UU_EXIT_FATAL;
		}
	} else {
		if (!quiet)
			display_pg(pg);
	}

	scf_property_destroy(prop);
	scf_pg_destroy(lpg);

	return (0);
}
Beispiel #9
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);
}
Beispiel #10
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 = 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);
}
Beispiel #11
0
/*
 * Convert legacy (XML) configuration files into an equivalent SCF
 * representation.
 *
 * Read the XML from disk, translate the XML into a tree of nodes of
 * type tgt_node_t, and write the in-memory tree to SCF's persistent
 * data-store using mgmt_config_save2scf().
 *
 * Return Values:
 * CONVERT_OK:	     successfully converted
 * CONVERT_INIT_NEW: configuration files don't exist; created an SCF entry
 * CONVERT_FAIL: some conversion error occurred; no SCF entry created.
 *		 In this case, user has to manually check files and try
 *		 conversion again.
 */
convert_ret_t
mgmt_convert_conf()
{
	targ_scf_t		*h = NULL;
	xmlTextReaderPtr	r;
	convert_ret_t		ret = CONVERT_FAIL;
	int			xml_fd = -1;
	int			n;
	tgt_node_t		*node = NULL;
	tgt_node_t		*next = NULL;
	char			path[MAXPATHLEN];
	char			*target = NULL;

	h = mgmt_handle_init();
	if (h == NULL)
		return (CONVERT_FAIL);

	/*
	 * Check if the "iscsitgt" PropertyGroup has already been added
	 * to the "iscsitgt" SMF Service.  If so, then we have already
	 * converted the legacy configuration files (and there is no work
	 * to do).
	 */
	if (scf_service_get_pg(h->t_service, "iscsitgt", h->t_pg) == 0) {
		ret = CONVERT_OK;
		goto done;
	}

	if (access(config_file, R_OK) != 0) {
		/*
		 * then the Main Config file is not present; initialize
		 * SCF Properties to default values.
		 */
		if (mgmt_transaction_start(h, "iscsitgt", "basic") == True) {
			ret = CONVERT_INIT_NEW;

			node = tgt_node_alloc(XML_ELEMENT_VERS, String, "1.0");
			new_property(h, node);
			tgt_node_free(node);
			/* "daemonize" is set to true by default */
			node = tgt_node_alloc(XML_ELEMENT_DBGDAEMON, String,
			    "true");
			new_property(h, node);
			tgt_node_free(node);
			node = NULL;
			node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
			    ISCSI_AUTH_MODIFY);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
			    ISCSI_AUTH_VALUE);
			new_property(h, node);
			tgt_node_free(node);
			(void) mgmt_transaction_end(h);
		} else {
			syslog(LOG_ERR, "Creating empty entry failed");
			ret = CONVERT_FAIL;
			goto done;
		}
		if (mgmt_transaction_start(h, "passwords", "application") ==
		    True) {
			node = tgt_node_alloc(ISCSI_READ_AUTHNAME, String,
			    ISCSI_AUTH_READ);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_MODIFY_AUTHNAME, String,
			    ISCSI_AUTH_MODIFY);
			new_property(h, node);
			tgt_node_free(node);
			node = tgt_node_alloc(ISCSI_VALUE_AUTHNAME, String,
			    ISCSI_AUTH_VALUE);
			new_property(h, node);
			tgt_node_free(node);
			(void) mgmt_transaction_end(h);
		} else {
			syslog(LOG_ERR, "Creating empty entry failed");
			ret = CONVERT_FAIL;
		}
		goto done;
	}

	if ((xml_fd = open(config_file, O_RDONLY)) >= 0)
		r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd, NULL, NULL, 0);

	if (r != NULL) {
		int is_target_config;

		n = xmlTextReaderRead(r);
		while (n == 1) {
			if (tgt_node_process(r, &node) == False) {
				break;
			}
			n = xmlTextReaderRead(r);
		}
		if (n < 0) {
			syslog(LOG_ERR, "Parsing main config failed");
			ret = CONVERT_FAIL;
			goto done;
		}

		main_config = node;

		/*
		 * Initialize the Base Directory (global) variable by
		 * using the value specified in the XML_ELEMENT_BASEDIR
		 * XML tag.  If a tag is not specified, use a default.
		 */
		(void) tgt_find_value_str(node, XML_ELEMENT_BASEDIR,
		    &target_basedir);

		if (target_basedir == NULL)
			target_basedir = strdup(DEFAULT_TARGET_BASEDIR);

		if (xml_fd != -1) {
			(void) close(xml_fd);
			xml_fd = -1;
		}
		(void) xmlTextReaderClose(r);
		xmlFreeTextReader(r);
		xmlCleanupParser();

		/*
		 * If a Target Config file is present, read and translate
		 * its XML representation into a tree of tgt_node_t.
		 * Merge that tree with the tree of tgt_node_t rooted at
		 * 'main_config'.  The merged tree will then be archived
		 * using an SCF representation.
		 */
		(void) snprintf(path, MAXPATHLEN, "%s/%s",
		    target_basedir, "config.xml");

		if ((xml_fd = open(path, O_RDONLY)) >= 0) {
			is_target_config = 1;
			r = (xmlTextReaderPtr)xmlReaderForFd(xml_fd,
			    NULL, NULL, 0);
		} else {
			is_target_config = 0;
			r = NULL;
		}

		if (r != NULL) {
			/* then the Target Config file is available. */

			node = NULL;

			/*
			 * Create a tree of tgt_node_t rooted at 'node' by
			 * processing each XML Tag in the file.
			 */
			n = xmlTextReaderRead(r);
			while (n == 1) {
				if (tgt_node_process(r, &node) == False) {
					break;
				}
				n = xmlTextReaderRead(r);
			}
			if (n < 0) {
				syslog(LOG_ERR, "Parsing target conf failed");
				ret = CONVERT_FAIL;
				goto done;
			}

			/*
			 * Merge the tree at 'node' into the tree rooted at
			 * 'main_config'.
			 */
			if (node != NULL) {
				next = NULL;
				while ((next = tgt_node_next(node,
				    XML_ELEMENT_TARG, next)) != NULL) {
					tgt_node_add(main_config,
					    tgt_node_dup(next));
				}
				tgt_node_free(node);
			}
		}

		/*
		 * Iterate over the in-memory tree rooted at 'main_config'
		 * and write a representation of the appropriate nodes to
		 * SCF's persistent data-store.
		 */
		if (mgmt_config_save2scf() != True) {
			syslog(LOG_ERR, "Converting config failed");
			if (xml_fd != -1) {
				(void) close(xml_fd);
				xml_fd = -1;
			}
			(void) xmlTextReaderClose(r);
			xmlFreeTextReader(r);
			xmlCleanupParser();
			ret = CONVERT_FAIL;
			goto done;
		}

		/*
		 * Move the configuration files into a well-known backup
		 * directory.  This allows a user to restore their
		 * configuration, if they choose.
		 */
		(void) snprintf(path, sizeof (path), "%s/backup",
		    target_basedir);
		if ((mkdir(path, 0755) == -1) && (errno != EEXIST)) {
			syslog(LOG_ERR, "Creating backup dir failed");
			ret = CONVERT_FAIL;
			goto done;
		}
		/* Save the Main Config file. */
		backup(config_file, NULL);

		/* Save the Target Config file, if it was present. */
		if (is_target_config != 0) {
			(void) snprintf(path, MAXPATHLEN, "%s/%s",
			    target_basedir, "config.xml");
			backup(path, NULL);
		}

		/*
		 * For each tgt_node_t node in 'main_config' whose value is
		 * an iSCSI Name as defined in the RFC (3720) standard (eg,
		 * "iqn.1986..."), read its XML-encoded attributes from a
		 * flat-file and write an equivalent representation to SCF's
		 * data-store.
		 */
		while ((next = tgt_node_next(main_config,
		    XML_ELEMENT_TARG, next)) != NULL) {
			if (tgt_find_value_str(next, XML_ELEMENT_INAME,
			    &target) == False) {
				continue;
			}
			(void) snprintf(path, MAXPATHLEN, "%s/%s",
			    target_basedir, target);
			if (mgmt_convert_param(path, next)
			    != True) {
				ret = CONVERT_FAIL;
				goto done;
			}
			free(target);
		}

		ret = CONVERT_OK;
		syslog(LOG_NOTICE, "Conversion succeeded");

		(void) xmlTextReaderClose(r);
		xmlFreeTextReader(r);
		xmlCleanupParser();
	} else {
		syslog(LOG_ERR, "Reading main config failed");
		ret = CONVERT_FAIL;
		goto done;
	}

done:
	if (xml_fd != -1)
		(void) close(xml_fd);
	mgmt_handle_fini(h);
	return (ret);
}