Ejemplo n.º 1
0
/*
 * Add the proto list contained in array 'plist' to entry 'entry', storing
 * aside the scf_value_t's created and added to the entry in a list that the
 * pointer referenced by sv_list is made to point at.
 */
static void
add_proto_list(scf_transaction_entry_t *entry, scf_handle_t *hdl,
    char **plist, uu_list_t **sv_list)
{
	scf_val_el_t		*sv_el;
	int			i;

	static uu_list_pool_t	*sv_pool = NULL;

	if ((sv_pool == NULL) &&
	    ((sv_pool = uu_list_pool_create("sv_pool",
	    sizeof (scf_val_el_t), offsetof(scf_val_el_t, link), NULL,
	    UU_LIST_POOL_DEBUG)) == NULL))
		uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));

	if ((*sv_list = uu_list_create(sv_pool, NULL, 0)) == NULL)
		uu_die(gettext("Error: %s.\n"), uu_strerror(uu_error()));

	for (i = 0; plist[i] != NULL; i++) {
		if ((sv_el = malloc(sizeof (scf_val_el_t))) == NULL)
			uu_die(gettext("Error:"));

		if (((sv_el->val = scf_value_create(hdl)) == NULL) ||
		    (scf_value_set_astring(sv_el->val, plist[i]) != 0) ||
		    (scf_entry_add_value(entry, sv_el->val) != 0))
			scfdie();

		uu_list_node_init(sv_el, &sv_el->link, sv_pool);
		(void) uu_list_insert_after(*sv_list, NULL, sv_el);
	}
}
Ejemplo n.º 2
0
/*
 * Sets string property in current pg
 */
int
smb_smf_set_string_property(smb_scfhandle_t *handle,
    char *propname, char *valstr)
{
	int ret = SMBC_SMF_OK;
	scf_value_t *value = NULL;
	scf_transaction_entry_t *entry = NULL;

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

	/*
	 * properties must be set in transactions and don't take
	 * effect until the transaction has been ended/committed.
	 */
	value = scf_value_create(handle->scf_handle);
	entry = scf_entry_create(handle->scf_handle);
	if (value != NULL && entry != NULL) {
		if (scf_transaction_property_change(handle->scf_trans, entry,
		    propname, SCF_TYPE_ASTRING) == 0 ||
		    scf_transaction_property_new(handle->scf_trans, entry,
		    propname, SCF_TYPE_ASTRING) == 0) {
			if (scf_value_set_astring(value, valstr) == 0) {
				if (scf_entry_add_value(entry, value) != 0) {
					ret = SMBC_SMF_SYSTEM_ERR;
					scf_value_destroy(value);
				}
				/* the value is in the transaction */
				value = NULL;
			} else {
				/* value couldn't be constructed */
				ret = SMBC_SMF_SYSTEM_ERR;
			}
			/* the entry is in the transaction */
			entry = NULL;
		} else {
			ret = SMBC_SMF_SYSTEM_ERR;
		}
	} else {
		ret = SMBC_SMF_SYSTEM_ERR;
	}
	if (ret == SMBC_SMF_SYSTEM_ERR) {
		switch (scf_error()) {
		case SCF_ERROR_PERMISSION_DENIED:
			ret = SMBC_SMF_NO_PERMISSION;
			break;
		}
	}

	/*
	 * cleanup if there were any errors that didn't leave these
	 * values where they would be cleaned up later.
	 */
	if (value != NULL)
		scf_value_destroy(value);
	if (entry != NULL)
		scf_entry_destroy(entry);
	return (ret);
}
Ejemplo n.º 3
0
static void
new_value_list(targ_scf_t *h,
	    tgt_node_t *p)
{
	scf_transaction_entry_t *e = NULL;
	scf_value_t *v = NULL;
	tgt_node_t *c;
	char *name;

	assert(p != NULL);

	name = p->x_name;
	e = scf_entry_create(h->t_handle);
	scf_transaction_property_new(h->t_trans, e, name, SCF_TYPE_ASTRING);

	for (c = p->x_child; c; c = c->x_sibling) {
		v = scf_value_create(h->t_handle);
		scf_value_set_astring(v, c->x_value);
		scf_entry_add_value(e, v);
	}
}
Ejemplo n.º 4
0
/*
 * store_inetd_hash stores the string hash in inetd's configuration file hash
 * in the repository. On success, SCF_ERROR_NONE is returned. Otherwise, the
 * scf_error value is returned.
 */
scf_error_t
store_inetd_hash(const char *hash)
{
	int ret;
	scf_error_t rval = SCF_ERROR_NONE;
	scf_handle_t *h;
	scf_propertygroup_t *pg = NULL;
	scf_instance_t *inst = NULL;
	scf_transaction_t *tx = NULL;
	scf_transaction_entry_t *txent = NULL;
	scf_property_t *prop = NULL;
	scf_value_t *val = NULL;

	if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
	    scf_handle_bind(h) == -1)
		goto error;

	if ((pg = scf_pg_create(h)) == NULL ||
	    (inst = scf_instance_create(h)) == NULL ||
	    scf_handle_decode_fmri(h, INETD_INSTANCE_FMRI, NULL, NULL, inst,
	    NULL, NULL, SCF_DECODE_FMRI_EXACT) == -1)
		goto error;

	if (scf_instance_get_pg(inst, HASH_PG, pg) == -1) {
		if (scf_error() != SCF_ERROR_NOT_FOUND ||
		    scf_instance_add_pg(inst, HASH_PG, SCF_GROUP_APPLICATION,
		    0, pg) == -1)
			goto error;
	}

	if ((tx = scf_transaction_create(h)) == NULL ||
	    (txent = scf_entry_create(h)) == NULL ||
	    (prop = scf_property_create(h)) == NULL ||
	    (val = scf_value_create(h)) == NULL)
		goto error;

	do {
		if (scf_transaction_start(tx, pg) == -1)
			goto error;

		if (scf_transaction_property_new(tx, txent, HASH_PROP,
		    SCF_TYPE_ASTRING) == -1 &&
		    scf_transaction_property_change_type(tx, txent, HASH_PROP,
		    SCF_TYPE_ASTRING) == -1)
			goto error;

		if (scf_value_set_astring(val, hash) == -1 ||
		    scf_entry_add_value(txent, val) == -1)
			goto error;

		if ((ret = scf_transaction_commit(tx)) == -1)
			goto error;

		if (ret == 0) {
			scf_transaction_reset(tx);
			if (scf_pg_update(pg) == -1)
				goto error;
		}
	} while (ret == 0);

	goto success;

error:
	rval = scf_error();

success:
	scf_value_destroy(val);
	scf_property_destroy(prop);
	scf_entry_destroy(txent);
	scf_transaction_destroy(tx);
	scf_instance_destroy(inst);
	scf_pg_destroy(pg);
	scf_handle_destroy(h);
	return (rval);
}
Ejemplo n.º 5
0
int
fs_smf_set_prop(smf_fstype_t fstype, char *prop_name, char *valbuf,
    char *instance, scf_type_t sctype, char *fmri)
{
	fs_smfhandle_t *phandle = NULL;
	scf_handle_t *handle;
	scf_propertygroup_t *pg;
	scf_property_t *prop;
	scf_transaction_t *tran = NULL;
	scf_transaction_entry_t *entry = NULL;
	scf_instance_t *inst;
	scf_value_t *val;
	int valint;
	int index = 0;
	int ret = 0;
	char *p = NULL;
	char *svcname, srv[MAXPATHLEN];
	const char *pgname;

	/*
	 * The SVC names we are using currently are already
	 * appended by default. Fix this for instances project.
	 */
	snprintf(srv, MAXPATHLEN, "%s", fmri);
	p = strstr(fmri, ":default");
	if (p == NULL) {
		strcat(srv, ":");
		if (instance == NULL)
			instance = "default";
		if (strlen(srv) + strlen(instance) > MAXPATHLEN)
			goto out;
		strncat(srv, instance, strlen(instance));
	}
	svcname = srv;
	phandle = fs_smf_init(fmri, instance);
	if (phandle == NULL) {
		return (SMF_SYSTEM_ERR);
	}
	handle = phandle->fs_handle;
	pg = phandle->fs_pg;
	prop = phandle->fs_property;
	inst = phandle->fs_instance;
	val = phandle->fs_value;
	tran = scf_transaction_create(handle);
	entry = scf_entry_create(handle);

	if (handle == NULL || pg == NULL || prop == NULL ||
	    val == NULL|| tran == NULL || entry == NULL || inst == NULL) {
		ret = SMF_SYSTEM_ERR;
		goto out;
	}

	if (scf_handle_decode_fmri(handle, svcname, phandle->fs_scope,
	    phandle->fs_service, inst, NULL, NULL, 0) != 0) {
		ret = scf_error();
		goto out;
	}
	if (fstype == AUTOFS_SMF)
		pgname = AUTOFS_PROPS_PGNAME;
	else
		pgname = NFS_PROPS_PGNAME;

	if (scf_instance_get_pg(inst, pgname,
	    pg) != -1) {
		uint8_t	vint;
		if (scf_transaction_start(tran, pg) == -1) {
			ret = scf_error();
			goto out;
		}
		switch (sctype) {
		case SCF_TYPE_INTEGER:
			errno = 0;
			valint = strtoul(valbuf, NULL, 0);
			if (errno != 0) {
				ret = SMF_SYSTEM_ERR;
				goto out;
			}
			if (scf_transaction_property_change(tran,
			    entry, prop_name, SCF_TYPE_INTEGER) == 0) {
				scf_value_set_integer(val, valint);
				if (scf_entry_add_value(entry, val) < 0) {
					ret = scf_error();
					goto out;
				}
			}
			break;
		case SCF_TYPE_ASTRING:
			if (scf_transaction_property_change(tran, entry,
			    prop_name, SCF_TYPE_ASTRING) == 0) {
				if (scf_value_set_astring(val,
				    valbuf) == 0) {
					if (scf_entry_add_value(entry,
					    val) != 0) {
						ret = scf_error();
						goto out;
					}
				} else
					ret = SMF_SYSTEM_ERR;
			} else
				ret = SMF_SYSTEM_ERR;
			break;
		case SCF_TYPE_BOOLEAN:
			if (strcmp(valbuf, "1") == 0) {
				vint = 1;
			} else if (strcmp(valbuf, "0") == 0) {
				vint = 0;
			} else  {
				ret = SMF_SYSTEM_ERR;
				break;
			}
			if (scf_transaction_property_change(tran, entry,
			    prop_name, SCF_TYPE_BOOLEAN) == 0) {
				scf_value_set_boolean(val, (uint8_t)vint);
				if (scf_entry_add_value(entry, val) != 0) {
					ret = scf_error();
					goto out;
				}
			} else {
				ret = SMF_SYSTEM_ERR;
			}
			break;
		}
		if (ret != SMF_SYSTEM_ERR)
			scf_transaction_commit(tran);
	}
out:
	if (tran != NULL)
		scf_transaction_destroy(tran);
	if (entry != NULL)
		scf_entry_destroy(entry);
	fs_smf_fini(phandle);
	return (ret);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}