Beispiel #1
0
/*
 * Gets a blob property value.
 * Caller is responsible to have enough memory allocated.
 */
int
smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname,
    void *v, size_t sz)
{
	int ret = SMBD_SMF_OK;
	scf_value_t *value = NULL;
	scf_property_t *prop = NULL;

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

	value = scf_value_create(handle->scf_handle);
	prop = scf_property_create(handle->scf_handle);
	if ((prop) && (value) &&
	    (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) {
		if (scf_property_get_value(prop, value) == 0) {
			if (scf_value_get_opaque(value, (char *)v, sz) != sz) {
				ret = SMBD_SMF_SYSTEM_ERR;
			}
		} else {
			ret = SMBD_SMF_SYSTEM_ERR;
		}
	} else {
		ret = SMBD_SMF_SYSTEM_ERR;
	}
	if (value != NULL)
		scf_value_destroy(value);
	if (prop != NULL)
		scf_property_destroy(prop);
	return (ret);
}
Beispiel #2
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);
	}
}
Beispiel #3
0
/*
 * Gets string property value.upto sz size.
 * Caller is responsible to have enough memory allocated.
 */
int
smb_smf_get_string_property(smb_scfhandle_t *handle, char *propname,
    char *valstr, size_t sz)
{
	int ret = SMBD_SMF_OK;
	scf_value_t *value;
	scf_property_t *prop;

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

	value = scf_value_create(handle->scf_handle);
	prop = scf_property_create(handle->scf_handle);
	if (value && prop &&
	    (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) {
		if (scf_property_get_value(prop, value) == 0) {
			if (scf_value_get_astring(value, valstr, sz) < 0) {
				ret = SMBD_SMF_SYSTEM_ERR;
			}
		} else {
			ret = SMBD_SMF_SYSTEM_ERR;
		}
	} else {
		ret = SMBD_SMF_SYSTEM_ERR;
	}
	if (value != NULL)
		scf_value_destroy(value);
	if (prop != NULL)
		scf_property_destroy(prop);
	return (ret);
}
Beispiel #4
0
static void
new_property(targ_scf_t *h,
	    tgt_node_t *n)
{
	scf_transaction_entry_t *e = NULL;
	scf_value_t *v = NULL;
	scf_type_t type;

	assert(n != NULL);

	e = scf_entry_create(h->t_handle);
	v = scf_value_create(h->t_handle);

	if (strcmp(n->x_value, "true") == 0 ||
	    strcmp(n->x_value, "false") == 0) {
		type = SCF_TYPE_BOOLEAN;
	} else if (strcmp(n->x_name, "main") == 0 ||
	    strcmp(n->x_name, "radius") == 0) {
		type = SCF_TYPE_ASTRING;
	} else if (strncmp(n->x_name, "I_", 2) == 0) {
		type = SCF_TYPE_ASTRING;
	} else if (strcmp(n->x_name, XML_ELEMENT_VERS) == 0) {
		type = SCF_TYPE_ASTRING;
	} else if (isnumber(n->x_value)) {
		type = SCF_TYPE_COUNT;
	} else {
		type = SCF_TYPE_ASTRING;
	}
	scf_transaction_property_new(h->t_trans, e, n->x_name, type);
	scf_value_set_from_string(v, type, n->x_value);
	scf_entry_add_value(e, v);
}
Beispiel #5
0
/*
 * Sets boolean property value.
 * Caller is responsible to have enough memory allocated.
 */
int
smb_smf_get_boolean_property(smb_scfhandle_t *handle, char *propname,
    uint8_t *valbool)
{
	int ret = SMBC_SMF_OK;
	scf_value_t *value = NULL;
	scf_property_t *prop = NULL;

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

	value = scf_value_create(handle->scf_handle);
	prop = scf_property_create(handle->scf_handle);
	if ((prop) && (value) &&
	    (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) {
		if (scf_property_get_value(prop, value) == 0) {
			if (scf_value_get_boolean(value,
			    valbool) != 0) {
				ret = SMBC_SMF_SYSTEM_ERR;
			}
		} else {
			ret = SMBC_SMF_SYSTEM_ERR;
		}
	} else {
		ret = SMBC_SMF_SYSTEM_ERR;
	}
	if (value != NULL)
		scf_value_destroy(value);
	if (prop != NULL)
		scf_property_destroy(prop);
	return (ret);
}
Beispiel #6
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);
}
Beispiel #7
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);
}
Beispiel #8
0
fs_smfhandle_t *
fs_smf_init(char *fmri, char *instance)
{
	fs_smfhandle_t *handle = NULL;
	char *svcname, srv[MAXPATHLEN];

	/*
	 * svc name is of the form svc://network/fs/server:instance1
	 * FMRI portion is /network/fs/server
	 */
	snprintf(srv, MAXPATHLEN, "%s", fmri + strlen("svc:/"));
	svcname = strrchr(srv, ':');
	if (svcname != NULL)
		*svcname = '\0';
	svcname = srv;

	handle = calloc(1, sizeof (fs_smfhandle_t));
	if (handle != NULL) {
		handle->fs_handle = scf_handle_create(SCF_VERSION);
		if (handle->fs_handle == NULL)
			goto out;
		if (scf_handle_bind(handle->fs_handle) != 0)
			goto out;
		handle->fs_service =
		    scf_service_create(handle->fs_handle);
		handle->fs_scope =
		    scf_scope_create(handle->fs_handle);
		if (scf_handle_get_local_scope(handle->fs_handle,
		    handle->fs_scope) != 0)
			goto out;
		if (scf_scope_get_service(handle->fs_scope,
		    svcname, handle->fs_service)  != SCF_SUCCESS) {
			goto out;
		}
		handle->fs_pg =
		    scf_pg_create(handle->fs_handle);
		handle->fs_instance =
		    scf_instance_create(handle->fs_handle);
		handle->fs_property =
		    scf_property_create(handle->fs_handle);
		handle->fs_value =
		    scf_value_create(handle->fs_handle);
	} else {
		fprintf(stderr,
		    gettext("Cannot access SMF repository: %s\n"), fmri);
	}
	return (handle);

out:
	fs_smf_fini(handle);
	fprintf(stderr, gettext("SMF Initialization problems..%s\n"), fmri);
	return (NULL);
}
Beispiel #9
0
/*
  In Solaris 11 the audit daemon has been moved to SMF. In the process
  they simply dropped getacna() from the API, since it read from a now
  non-existent config file. This function re-implements getacna() to
  read from the SMF repository instead.
 */
int
getacna(char *auditstring, int len)
{
	scf_handle_t *handle = NULL;
	scf_property_t *property = NULL;
	scf_value_t *value = NULL;
	int ret = 0;

	handle = scf_handle_create(SCF_VERSION);
	if (handle == NULL) 
	        return -2; /* The man page for getacna on Solaris 10 states
			      we should return -2 in case of error and set
			      errno to indicate the error. We don't bother
			      with errno here, though, since the only use
			      of this function below doesn't check for errors
			      anyway. 
			   */

	ret = scf_handle_bind(handle);
	if (ret == -1) 
	        return -2;

	property = scf_property_create(handle);
	if (property == NULL) 
	        return -2;

	ret = scf_handle_decode_fmri(handle, 
	     "svc:/system/auditd:default/:properties/preselection/naflags",
				     NULL, NULL, NULL, NULL, property, 0);
	if (ret == -1) 
	        return -2;

	value = scf_value_create(handle);
	if (value == NULL) 
	        return -2;

	ret = scf_property_get_value(property, value);
	if (ret == -1) 
	        return -2;

	ret = scf_value_get_astring(value, auditstring, len);
	if (ret == -1) 
	        return -2;

	scf_value_destroy(value);
	scf_property_destroy(property);
	scf_handle_destroy(handle);

	return 0;
}
Beispiel #10
0
static int
add_new_property(scf_handle_t *handle, const char *prop_name,
    scf_type_t type, const char *val, scf_transaction_t *tx)
{
	scf_value_t *value = NULL;
	scf_transaction_entry_t *entry = NULL;
	int status = FAILURE;

	entry = scf_entry_create(handle);
	if (entry == NULL) {
		KSSL_DEBUG("scf_entry_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out;
	}
	KSSL_DEBUG("scf_entry_create succeeded\n");

	value = scf_value_create(handle);
	if (value == NULL) {
		goto out;
	}
	KSSL_DEBUG("scf_value_create succeeded\n");

	if (scf_transaction_property_new(tx, entry, prop_name, type) != 0) {
		goto out;
	}
	KSSL_DEBUG("scf_transaction_property_new succeeded\n");

	if (scf_value_set_from_string(value, type, val) != 0) {
		goto out;
	}
	KSSL_DEBUG("scf_value_set_from_string \'%s\' succeeded\n", val);

	if (scf_entry_add_value(entry, value) != 0) {
		KSSL_DEBUG(
		    "scf_entry_add_value failed: %s\n",
		    scf_strerror(scf_error()));
		goto out;
	}
	KSSL_DEBUG("scf_entry_add_value succeeded\n");

	status = SUCCESS;

out:
	if (status != SUCCESS)
		(void) fprintf(stderr, gettext(
		    "Unexpected fatal libscf error: %s. Exiting.\n"),
		    scf_strerror(scf_error()));
	return (status);
}
Beispiel #11
0
int
main()
{
	if (daemonize_self() == 1)
		return (1);

	max_scf_fmri_size = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH) + 1;
	max_scf_name_size = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH) + 1;

	assert(max_scf_fmri_size > 0);
	assert(max_scf_name_size > 0);

	if ((h = scf_handle_create(SCF_VERSION)) == NULL) {
		syslog(LOG_ERR | LOG_DAEMON, "scf_handle_create failed: %s\n",
		    scf_strerror(scf_error()));
		return (1);
	}

	repository_rebind(h);

	scratch_fmri = umem_alloc(max_scf_fmri_size, UMEM_DEFAULT);
	scratch_name = umem_alloc(max_scf_name_size, UMEM_DEFAULT);

	if (scratch_fmri == NULL || scratch_name == NULL) {
		syslog(LOG_ERR | LOG_DAEMON, "Out of memory");
		return (1);
	}

	inst = scf_instance_create(h);
	snap = scf_snapshot_create(h);
	scratch_pg = scf_pg_create(h);
	scratch_prop = scf_property_create(h);
	scratch_v = scf_value_create(h);

	if (inst == NULL || snap == NULL || scratch_pg == NULL ||
	    scratch_prop == NULL || scratch_v == NULL) {
		syslog(LOG_ERR | LOG_DAEMON, "Initialization failed: %s\n",
		    scf_strerror(scf_error()));
		return (1);
	}

	return (repository_event_wait());
}
Beispiel #12
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);
}
Beispiel #13
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);
	}
}
Status osDaemonIsEnabled( int inQuiet )
{
	Status			isEnabled = sStatusNotEnabled;
	scf_handle_t *	theHandle = scf_handle_create( SCF_VERSION );
	if (inQuiet == 0) { writeInitialMessage( sOpIsEnabled ); }
	if ( theHandle != 0 )
	{
		if ( scf_handle_bind( theHandle ) == 0 )
		{
			scf_instance_t * theInstance = scf_instance_create( theHandle );
			if ( theInstance != 0 )
			{
				if ( scf_handle_decode_fmri(
						theHandle,
						sInstanceName,
						0,
						0,
						theInstance,
						0,
						0,
						SCF_DECODE_FMRI_EXACT ) != -1 )
				{
					scf_handle_t * theInstanceHandle =
						scf_instance_handle( theInstance );
					if ( theInstanceHandle != 0 )
					{
						uint8_t					theEnabled;
						scf_propertygroup_t *	theGroup	=
							scf_pg_create( theInstanceHandle );
						scf_property_t *		theProp		=
							scf_property_create( theInstanceHandle );
						scf_value_t *			theValue	=
							scf_value_create( theInstanceHandle );
						if ( theGroup != 0 && theProp != 0 && theValue != 0 )
						{
							if ( scf_instance_get_pg( theInstance, 
							                          SCF_PG_GENERAL,
							                          theGroup ) == 0		&&
							     scf_pg_get_property( theGroup,
							                          SCF_PROPERTY_ENABLED,
							                          theProp ) == 0		&&
							     scf_property_get_value( theProp,
							                             theValue ) == 0	&&
							     scf_value_get_boolean( theValue,	
							                            &theEnabled ) == 0 )
								{
							     	isEnabled = theEnabled == 1 ?
										sStatusEnabled : sStatusNotEnabled;	
								}
						}
						scf_pg_destroy( theGroup );
						scf_property_destroy( theProp );
						scf_value_destroy( theValue );
					}
				}
				scf_instance_destroy( theInstance );
			}
		}
		scf_handle_destroy( theHandle );
	}
	if (inQuiet == 0) { writeFinalMessage( sOpIsEnabled, isEnabled ); }
	return isEnabled;
}
Beispiel #15
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);
}
Beispiel #16
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 #17
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);
}
Beispiel #18
0
conerr_t
smfu_set_property(char *fmri, char *pgname, char *propname, char *value)
{
	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_value_t *val = scf_value_create(scfhandle);
	scf_transaction_t *tx = scf_transaction_create(scfhandle);
	scf_transaction_entry_t *ent = scf_entry_create(scfhandle);
	scf_type_t type;

	if (scfhandle == NULL || service == NULL || instance == NULL ||
	    pg == NULL || prop == NULL || tx == NULL || ent == 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_property_type(prop, &type) != 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;
	}

top:
	if (scf_transaction_start(tx, pg) == -1 ||
	    scf_transaction_property_change(tx, ent, propname, type) != 0 ||
	    scf_value_set_from_string(val, type, value) != 0 ||
	    scf_entry_add_value(ent, val) != 0) {
		rad_log(RL_ERROR, "couldn't set property: '%s/%s/%s': %s\n",
		    fmri, pgname, propname, scf_strerror(scf_error()));
		err = maperr(scf_error());
		goto out;
	}

	switch (scf_transaction_commit(tx)) {
	/* success */
	case 1:
		if (smf_refresh_instance(fmri) != 0) {
			err = maperr(scf_error());
			goto out;
		}
		break;
	/* retry */
	case 0:
		if (scf_pg_update(pg) != 0) {
			err = maperr(scf_error());
			goto out;
		}
		scf_transaction_reset(tx);
		goto top;
	default:
		err = maperr(scf_error());
		goto out;
	}
out:
	scf_entry_destroy(ent);
	scf_transaction_destroy(tx);
	scf_value_destroy(val);
	scf_property_destroy(prop);
	scf_pg_destroy(pg);
	scf_instance_destroy(instance);
	scf_service_destroy(service);
	scf_handle_destroy(scfhandle);

	return (err);
}
Beispiel #19
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 #20
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 #21
0
static void
kbd_defaults(int kbd)
{
    scf_handle_t *h = NULL;
    scf_snapshot_t *snap = NULL;
    scf_instance_t *inst = NULL;
    scf_propertygroup_t *pg = NULL;
    scf_property_t *prop = NULL;
    scf_value_t *val = NULL;

    int layout_num;
    char *val_layout = NULL, *val_abort = NULL;
    uint8_t val_click;
    int64_t val_delay, val_rate;
    int64_t val_kbd_beeper, val_console_beeper;

    if ((h = scf_handle_create(SCF_VERSION)) == NULL ||
            scf_handle_bind(h) != 0 ||
            (inst = scf_instance_create(h)) == NULL ||
            (snap = scf_snapshot_create(h)) == NULL ||
            (pg = scf_pg_create(h)) == NULL ||
            (prop = scf_property_create(h)) == NULL ||
            (val = scf_value_create(h)) == NULL) {
        goto out;
    }

    if (scf_handle_decode_fmri(h, KBD_FMRI, NULL, NULL, inst,
                               NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
        goto out;
    }

    if (scf_instance_get_snapshot(inst, "running", snap) != 0) {
        scf_snapshot_destroy(snap);
        snap = NULL;
    }

    if (scf_instance_get_pg_composed(inst, snap, KBD_PG, pg) != 0) {
        goto out;
    }

    if ((val_abort = malloc(KBD_MAX_NAME_LEN)) == NULL) {
        (void) fprintf(stderr,
                       "Can not alloc memory for keyboard properties\n");
        goto out;
    }

    if ((val_layout = malloc(KBD_MAX_NAME_LEN)) == NULL) {
        (void) fprintf(stderr,
                       "Can not alloc memory for keyboard properties\n");
        goto out;
    }

    if (scf_pg_get_property(pg, KBD_PROP_KEYCLICK, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_boolean(val, &val_click) == -1) {
        (void) fprintf(stderr, "Can not get KEYCLICK\n");
    }

    if (val_click == 1)
        (void) click("on", kbd);
    else if (val_click == 0)
        (void) click("off", kbd);
    else
        (void) fprintf(stderr,
                       BAD_DEFAULT_INT, KBD_PROP_KEYCLICK, val_click);

    if (scf_pg_get_property(pg, KBD_PROP_KEYBOARD_ABORT, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_astring(val, val_abort, KBD_MAX_NAME_LEN) == -1) {
        (void) fprintf(stderr, "Can not get KEYBOARD_ABORT\n");
    }

    if (*val_abort != '\0') {
        /*
         * ABORT must equal "enable", "disable" or "alternate"
         */
        if ((strcmp(val_abort, "enable") == 0) ||
                (strcmp(val_abort, "alternate") == 0) ||
                (strcmp(val_abort, "disable") == 0))
            (void) abort_enable(val_abort, kbd);
        else
            (void) fprintf(stderr, BAD_DEFAULT_STR,
                           KBD_PROP_KEYBOARD_ABORT, val_abort);
    }

    if (scf_pg_get_property(pg, KBD_PROP_RPTDELAY, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_integer(val, &val_delay) == -1) {
        (void) fprintf(stderr, "Can not get RPTDELAY\n");
    }

    if (val_delay > 0)
        (void) set_rptdelay(val_delay, kbd);
    else
        (void) fprintf(stderr,
                       BAD_DEFAULT_LLINT, KBD_PROP_RPTDELAY, val_delay);

    if (scf_pg_get_property(pg, KBD_PROP_RPTRATE, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_integer(val, &val_rate) == -1) {
        (void) fprintf(stderr, "Can not get RPTRATE\n");
    }

    if (val_rate > 0)
        (void) set_rptrate(val_rate, kbd);
    else
        (void) fprintf(stderr,
                       BAD_DEFAULT_LLINT, KBD_PROP_RPTRATE, val_rate);

    if (scf_pg_get_property(pg, KBD_PROP_LAYOUT, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_astring(val, val_layout, KBD_MAX_NAME_LEN) == -1) {
        (void) fprintf(stderr, "Can not get LAYOUT\n");
    }

    if (*val_layout != '\0') {
        /*
         * LAYOUT must be one of the layouts supported in kbd_layouts
         */
        if (get_layouts() != 0)
            goto out;

        if ((layout_num = get_layout_number(val_layout)) == -1) {
            (void) fprintf(stderr,
                           BAD_DEFAULT_STR, KBD_PROP_LAYOUT, val_layout);
            goto out;
        }

        (void) set_layout(kbd, layout_num);
    }

    if (scf_pg_get_property(pg, KBD_PROP_FREQ, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_integer(val, &val_kbd_beeper) == -1) {
        (void) fprintf(stderr, "Can not get FREQ\n");
    }

    if (val_kbd_beeper >= 0 && val_kbd_beeper <= INT16_MAX)
        (void) set_beep_freq(kbd, "keyboard", val_kbd_beeper);
    else
        (void) fprintf(stderr,
                       BAD_DEFAULT_LLINT, KBD_PROP_FREQ, val_kbd_beeper);

    if (scf_pg_get_property(pg, KBD_PROP_CONSFREQ, prop) != 0 ||
            scf_property_get_value(prop, val) != 0 ||
            scf_value_get_integer(val, &val_console_beeper) == -1) {
        (void) fprintf(stderr, "Can not get CONSFREQ\n");
    }

    if (val_console_beeper >= 0 && val_console_beeper <= INT16_MAX)
        (void) set_beep_freq(kbd, "console", val_console_beeper);
    else
        (void) fprintf(stderr,
                       BAD_DEFAULT_LLINT, KBD_PROP_CONSFREQ, val_console_beeper);

out:
    if (val_layout != NULL)
        free(val_layout);
    if (val_abort != NULL)
        free(val_abort);
    if (snap != NULL)
        scf_snapshot_destroy(snap);
    scf_value_destroy(val);
    scf_property_destroy(prop);
    scf_pg_destroy(pg);
    scf_instance_destroy(inst);
    scf_handle_destroy(h);
}
Beispiel #22
0
/*
 * Inputs:
 *   lpg is the property group to look up
 *   lprop is the property within that group to look up
 * Outputs:
 *   res is a pointer to an scf_resources_t.  This is an internal
 *   structure that holds all the handles needed to get a specific
 *   property from the running snapshot; on a successful return it
 *   contains the scf_value_t that should be passed to the desired
 *   scf_value_get_foo() function, and must be freed after use by
 *   calling release_scf_resources().  On a failure return, any
 *   resources that may have been assigned to res are released, so
 *   the caller does not need to do any cleanup in the failure case.
 * Returns:
 *    0 on success
 *   -1 on failure
 */
static int
get_property_value(const char *lpg, const char *lprop, scf_resources_t *res)
{
	res->sr_inst = NULL;
	res->sr_snap = NULL;
	res->sr_pg = NULL;
	res->sr_prop = NULL;
	res->sr_val = NULL;

	if ((res->sr_handle = scf_handle_create(SCF_VERSION)) == NULL) {
		syslog(LOG_ERR, "scf_handle_create() failed: %s",
		    scf_strerror(scf_error()));
		return (-1);
	}

	if (scf_handle_bind(res->sr_handle) != 0) {
		scf_handle_destroy(res->sr_handle);
		syslog(LOG_ERR, "scf_handle_destroy() failed: %s",
		    scf_strerror(scf_error()));
		return (-1);
	}
	if ((res->sr_inst = scf_instance_create(res->sr_handle)) == NULL) {
		syslog(LOG_ERR, "scf_instance_create() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if (scf_handle_decode_fmri(res->sr_handle, OUR_FMRI, NULL, NULL,
	    res->sr_inst, NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) != 0) {
		syslog(LOG_ERR, "scf_handle_decode_fmri() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if ((res->sr_snap = scf_snapshot_create(res->sr_handle)) == NULL) {
		syslog(LOG_ERR, "scf_snapshot_create() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if (scf_instance_get_snapshot(res->sr_inst, "running",
	    res->sr_snap) != 0) {
		syslog(LOG_ERR, "scf_instance_get_snapshot() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if ((res->sr_pg = scf_pg_create(res->sr_handle)) == NULL) {
		syslog(LOG_ERR, "scf_pg_create() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if (scf_instance_get_pg_composed(res->sr_inst, res->sr_snap, lpg,
	    res->sr_pg) != 0) {
		syslog(LOG_ERR, "scf_instance_get_pg_composed(%s) failed: %s",
		    lpg, scf_strerror(scf_error()));
		goto failure;
	}
	if ((res->sr_prop = scf_property_create(res->sr_handle)) == NULL) {
		syslog(LOG_ERR, "scf_property_create() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if (scf_pg_get_property(res->sr_pg, lprop, res->sr_prop) != 0) {
		syslog(LOG_ERR, "scf_pg_get_property(%s) failed: %s",
		    lprop, scf_strerror(scf_error()));
		goto failure;
	}
	if ((res->sr_val = scf_value_create(res->sr_handle)) == NULL) {
		syslog(LOG_ERR, "scf_value_create() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	if (scf_property_get_value(res->sr_prop, res->sr_val) != 0) {
		syslog(LOG_ERR, "scf_property_get_value() failed: %s",
		    scf_strerror(scf_error()));
		goto failure;
	}
	return (0);

failure:
	release_scf_resources(res);
	return (-1);
}
Beispiel #23
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);
}
Beispiel #24
0
/*
 * Returns a zone ID of Solaris when the TZ value is "localtime".
 * First, it tries scf. If scf fails, it looks for the same file as
 * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/.
 */
static char *
getSolarisDefaultZoneID() {
    char *tz = NULL;
    struct stat statbuf;
    size_t size;
    char *buf;
    int fd;
    /* scf specific variables */
    scf_handle_t *h = NULL;
    scf_snapshot_t *snap = NULL;
    scf_instance_t *inst = NULL;
    scf_propertygroup_t *pg = NULL;
    scf_property_t *prop = NULL;
    scf_value_t *val = NULL;

    if ((h = scf_handle_create(SCF_VERSION)) != NULL
        && scf_handle_bind(h) == 0
        && (inst = scf_instance_create(h)) != NULL
        && (snap = scf_snapshot_create(h)) != NULL
        && (pg = scf_pg_create(h)) != NULL
        && (prop = scf_property_create(h)) != NULL
        && (val = scf_value_create(h)) != NULL
        && scf_handle_decode_fmri(h, TIMEZONE_FMRI, NULL, NULL, inst,
                                  NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) == 0
        && scf_instance_get_snapshot(inst, "running", snap) == 0
        && scf_instance_get_pg_composed(inst, snap, TIMEZONE_PG, pg) == 0
        && scf_pg_get_property(pg, LOCALTIME_PROP, prop) == 0
        && scf_property_get_value(prop, val) == 0) {
        ssize_t len;

        /* Gets the length of the zone ID string */
        len = scf_value_get_astring(val, NULL, 0);
        if (len != -1) {
            tz = malloc(++len); /* +1 for a null byte */
            if (tz != NULL && scf_value_get_astring(val, tz, len) != -1) {
                cleanupScf(h, snap, inst, pg, prop, val, NULL);
                return tz;
            }
        }
    }
    cleanupScf(h, snap, inst, pg, prop, val, tz);

    if (stat(DEFAULT_ZONEINFO_FILE, &statbuf) == -1) {
        return NULL;
    }
    size = (size_t) statbuf.st_size;
    buf = malloc(size);
    if (buf == NULL) {
        return NULL;
    }
    if ((fd = open(DEFAULT_ZONEINFO_FILE, O_RDONLY)) == -1) {
        free((void *) buf);
        return NULL;
    }

    if (read(fd, buf, size) != (ssize_t) size) {
        (void) close(fd);
        free((void *) buf);
        return NULL;
    }
    (void) close(fd);
    tz = findZoneinfoFile(buf, size, ZONEINFO_DIR);
    free((void *) buf);
    return tz;
}
Beispiel #25
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);
}
Beispiel #26
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);
}
Beispiel #27
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);
}