예제 #1
0
static scf_propertygroup_t *
add_property_group_to_instance(scf_handle_t *handle, scf_instance_t *instance,
    const char *pg_name, const char *pg_type)
{
	scf_propertygroup_t *pg;

	pg = scf_pg_create(handle);
	if (pg == NULL) {
		KSSL_DEBUG("scf_pg_create failed: %s\n",
		    scf_strerror(scf_error()));
		(void) fprintf(stderr, gettext(
		    "Unexpected fatal libscf error: %s. Exiting.\n"),
		    scf_strerror(scf_error()));
		return (NULL);
	}

	if (scf_instance_add_pg(instance, pg_name, pg_type, 0, pg) != 0) {
		KSSL_DEBUG("ERROR: scf_instance_add_pg failed: %s\n",
		    scf_strerror(scf_error()));
		if (scf_error() == SCF_ERROR_EXISTS)
			(void) fprintf(stderr, gettext(
			    "Error: another process is modifying this instance."
			    " Exiting.\n"));
		else
			(void) fprintf(stderr, gettext(
			    "Unexpected fatal libscf error: %s. Exiting.\n"),
			    scf_strerror(scf_error()));
		scf_pg_destroy(pg);
		return (NULL);
	} else {
		KSSL_DEBUG("property group created\n");
	}

	return (pg);
}
예제 #2
0
static void
repository_notify_setup(scf_handle_t *h)
{
	for (;;) {
		if (_scf_notify_add_pgtype(h, SCF_GROUP_FRAMEWORK) ==
		    SCF_SUCCESS)
			break;

		switch (scf_error()) {
		case SCF_ERROR_CONNECTION_BROKEN:
			repository_rebind(h);
			break;

		case SCF_ERROR_NO_RESOURCES:
			(void) sleep(1);
			break;

		default:
			syslog(LOG_ERR | LOG_DAEMON,
			    "Abort: Couldn't set up repository notification "
			    "for pg type %s: %s\n", SCF_GROUP_FRAMEWORK,
			    scf_strerror(scf_error()));
			abort();
		}
	}
}
예제 #3
0
/*
 * retrieve_inetd_hash retrieves inetd's configuration file hash from the
 * repository. On success, hash is modified to point to the hash string and
 * SCF_ERROR_NONE is returned. Otherwise, the scf_error value is returned.
 * The space for the hash string is obtained using malloc(3C) and should be
 * freed by the caller.
 */
scf_error_t
retrieve_inetd_hash(char **hash)
{
	scf_simple_prop_t *sp;
	char *hashstr, *s;
	scf_error_t scf_err;

	if ((sp = scf_simple_prop_get(NULL, INETD_INSTANCE_FMRI, HASH_PG,
	    HASH_PROP)) == NULL)
		return (scf_error());

	if ((hashstr = scf_simple_prop_next_astring(sp)) == NULL) {
		scf_err = scf_error();
		scf_simple_prop_free(sp);
		return (scf_err);
	}

	if ((s = strdup(hashstr)) == NULL) {
		scf_simple_prop_free(sp);
		return (SCF_ERROR_NO_MEMORY);
	}
	*hash = s;
	scf_simple_prop_free(sp);
	return (SCF_ERROR_NONE);
}
예제 #4
0
파일: inetadm.c 프로젝트: andreiw/polaris
static void
delete_prop(const scf_instance_t *inst, const char *pg, const char *prop)
{
	scf_transaction_t		*tx;
	scf_transaction_entry_t		*ent;
	scf_propertygroup_t		*gpg;
	scf_property_t			*eprop;
	int				ret;

	if ((gpg = scf_pg_create(h)) == NULL ||
	    (eprop = scf_property_create(h)) == NULL ||
	    (tx = scf_transaction_create(h)) == NULL ||
	    (ent = scf_entry_create(h)) == NULL)
		scfdie();

	if (scf_instance_get_pg(inst, pg, gpg) != SCF_SUCCESS) {
		if (scf_error() != SCF_ERROR_NOT_FOUND)
			scfdie();

		uu_die(gettext("Error: \"%s\" property group missing.\n"), pg);
	}

	do {
		if (scf_transaction_start(tx, gpg) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}

		if (scf_transaction_property_delete(tx, ent,
		    prop) != SCF_SUCCESS) {
			if (scf_error() != SCF_ERROR_NOT_FOUND)
				scfdie();

			uu_die(
			    gettext("Error: \"%s\" property does not exist.\n"),
			    prop);
		}

		ret = scf_transaction_commit(tx);
		if (ret < 0) {
			if (scf_error() != SCF_ERROR_PERMISSION_DENIED)
				scfdie();

			uu_die(gettext("Error: Permission denied.\n"));
		}
		if (ret == 0) {
			scf_transaction_reset(tx);
			if (scf_pg_update(gpg) == -1)
				scfdie();
		}
	} while (ret == 0);

	(void) scf_entry_destroy(ent);
	scf_transaction_destroy(tx);
	scf_property_destroy(eprop);
	scf_pg_destroy(gpg);
}
예제 #5
0
/*
 * Determine whether a given instance is a RPC service. Repository and
 * libscf errors are treated as if the service isn't an RPC service,
 * returning B_FALSE to indicate validation failure.
 */
static boolean_t
service_is_rpc(const scf_instance_t *inst)
{
	scf_snapshot_t *lsnap = NULL;
	uint8_t	isrpc;

	if (scf_instance_get_snapshot(inst, SCF_SNAPSHOT_RUNNING, snap) != 0) {
		syslog(LOG_DEBUG | LOG_DAEMON,
		    "Could not get running snapshot, using editing value\n");
	} else {
		lsnap = snap;
	}

	if (scf_instance_get_pg_composed(inst, lsnap, SCF_PG_INETD,
	    scratch_pg) == -1) {
		switch (scf_error()) {
		case SCF_ERROR_NOT_FOUND:
		case SCF_ERROR_DELETED:
			break;

		default:
			syslog(LOG_ERR | LOG_DAEMON,
			    "scf_instance_get_pg_composed failed: %s\n",
			    scf_strerror(scf_error()));
			return (B_FALSE);
		}

		if (scf_instance_get_pg_composed(inst, lsnap,
		    SCF_PG_FW_CONTEXT, scratch_pg) == -1) {
			switch (scf_error()) {
			case SCF_ERROR_NOT_FOUND:
			case SCF_ERROR_DELETED:
				break;

			default:
				syslog(LOG_ERR | LOG_DAEMON,
				    "scf_instance_get_pg_composed failed: %s\n",
				    scf_strerror(scf_error()));
			}
			return (B_FALSE);
		}
	}

	if (pg_get_prop_value(scratch_pg, SCF_PROPERTY_ISRPC, scratch_v) == -1)
		return (B_FALSE);

	if (scf_value_get_boolean(scratch_v, &isrpc) == -1) {
		syslog(LOG_ERR | LOG_DAEMON, "scf_value_get_boolean failed: "
		    "%s\n", scf_strerror(scf_error()));
		return (B_FALSE);
	}

	if (isrpc)
		return (B_TRUE);
	else
		return (B_FALSE);
}
예제 #6
0
/*
 * Get FMRI for the named process.
 */
isc_result_t
ns_smf_get_instance(char **ins_name, int debug, isc_mem_t *mctx) {
	scf_handle_t *h = NULL;
	int namelen;
	char *instance;

	REQUIRE(ins_name != NULL && *ins_name == NULL);

	if ((h = scf_handle_create(SCF_VERSION)) == NULL) {
		if (debug)
			UNEXPECTED_ERROR(__FILE__, __LINE__,
					 "scf_handle_create() failed: %s",
					 scf_strerror(scf_error()));
		return (ISC_R_FAILURE);
	}

	if (scf_handle_bind(h) == -1) {
		if (debug)
			UNEXPECTED_ERROR(__FILE__, __LINE__,
					 "scf_handle_bind() failed: %s",
					 scf_strerror(scf_error()));
		scf_handle_destroy(h);
		return (ISC_R_FAILURE);
	}

	if ((namelen = scf_myname(h, NULL, 0)) == -1) {
		if (debug)
			UNEXPECTED_ERROR(__FILE__, __LINE__,
					 "scf_myname() failed: %s",
					 scf_strerror(scf_error()));
		scf_handle_destroy(h);
		return (ISC_R_FAILURE);
	}

	if ((instance = isc_mem_allocate(mctx, namelen + 1)) == NULL) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "ns_smf_get_instance memory "
				 "allocation failed: %s",
				 isc_result_totext(ISC_R_NOMEMORY));
		scf_handle_destroy(h);
		return (ISC_R_FAILURE);
	}

	if (scf_myname(h, instance, namelen + 1) == -1) {
		if (debug)
			UNEXPECTED_ERROR(__FILE__, __LINE__,
					 "scf_myname() failed: %s",
					 scf_strerror(scf_error()));
		scf_handle_destroy(h);
		isc_mem_free(mctx, instance);
		return (ISC_R_FAILURE);
	}

	scf_handle_destroy(h);
	*ins_name = instance;
	return (ISC_R_SUCCESS);
}
예제 #7
0
/*
 * smb_smf_scf_log_error(msg)
 * Logs error messages from scf API's
 */
static void
smb_smf_scf_log_error(char *msg)
{
	if (!msg) {
		syslog(LOG_ERR, " SMBC SMF problem: %s\n",
		    scf_strerror(scf_error()));
	} else { /*LINTED E_SEC_PRINTF_E_VAR_FMT*/
		syslog(LOG_ERR, msg, scf_strerror(scf_error()));
	}
}
예제 #8
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);
}
예제 #9
0
/*
 * Inputs:
 *   lpg is the property group to look up
 *   lprop is the property within that group to look up
 * Outputs:
 *   answer is a pointer to the property value
 * Returns:
 *    0 on success
 *   -1 on failure
 * If successful, the property value is retured in *answer.
 * Otherwise, *answer is undefined, and it is up to the caller to decide
 * how to handle that case.
 */
int
lookup_boolean_property(const char *lpg, const char *lprop, boolean_t *answer)
{
	int result = -1;
	scf_resources_t res;
	uint8_t prop_val;

	if (get_property_value(lpg, lprop, &res) != 0) {
		/*
		 * an error was already logged by get_property_value,
		 * and it released any resources assigned to res before
		 * returning.
		 */
		return (result);
	}
	if (scf_value_get_boolean(res.sr_val, &prop_val) != 0) {
		syslog(LOG_ERR, "scf_value_get_boolean() failed: %s",
		    scf_strerror(scf_error()));
		goto cleanup;
	}
	*answer = (boolean_t)prop_val;
	dprintf("lookup_boolean_property(%s, %s) returns %s", lpg, lprop,
	    *answer ? "TRUE" : "FALSE");
	result = 0;
cleanup:
	release_scf_resources(&res);
	return (result);
}
예제 #10
0
/*ARGSUSED*/
JNIEXPORT void JNICALL
Java_com_sun_dhcpmgr_bridge_Bridge_startup(
    JNIEnv *env,
    jobject obj)
{
	char *s;
	int ret;

	/*
	 * We first get the current state of the server according to
	 * svc.startd; if it's "disabled", we can just enable it.
	 * In any other case, we want to send a refresh so that
	 * dependencies are re-evaluated, which will be the case if the
	 * service was marked enabled by the profile, yet the
	 * config file didn't exist to allow it to run.
	 */
	if ((s = smf_get_state(DHCP_SERVER_INST)) != NULL) {
		if (strcmp(SCF_STATE_STRING_DISABLED, s) == 0)
			ret = smf_enable_instance(DHCP_SERVER_INST, 0);
		else
			ret = smf_refresh_instance(DHCP_SERVER_INST);
		free(s);
		if (ret == 0)
			return;
	}

	/* Something wasn't right, return exception with error from smf */
	throw_bridge_exception(env, scf_strerror(scf_error()));
}
예제 #11
0
/*
 * Inputs:
 *   lpg is the property group to look up
 *   lprop is the property within that group to look up
 * Outputs:
 *   answer is a pointer to the property value
 * Returns:
 *    0 on success
 *   -1 on failure
 * If successful, the property value is retured in *answer.
 * Otherwise, *answer is undefined, and it is up to the caller to decide
 * how to handle that case.
 */
int
lookup_count_property(const char *lpg, const char *lprop, uint64_t *answer)
{
	int result = -1;
	scf_resources_t res;

	if (get_property_value(lpg, lprop, &res) != 0) {
		/*
		 * an error was already logged by get_property_value,
		 * and it released any resources assigned to res before
		 * returning.
		 */
		return (result);
	}
	if (scf_value_get_count(res.sr_val, answer) != 0) {
		syslog(LOG_ERR, "scf_value_get_count() failed: %s",
		    scf_strerror(scf_error()));
		goto cleanup;
	}
	dprintf("lookup_count_property(%s, %s) returns %lld", lpg, lprop,
	    *answer);
	result = 0;
cleanup:
	release_scf_resources(&res);
	return (result);
}
예제 #12
0
/*
 * Return a snapshot for the supplied instance and snapshot name.
 */
static scf_snapshot_t *
get_snapshot(const scf_instance_t *inst, const char *snapshot)
{
	scf_snapshot_t *snap = scf_snapshot_create(hndl);

	if (snap == NULL)
		scfdie();

	if (scf_instance_get_snapshot(inst, snapshot, snap) == -1) {
		switch (scf_error()) {
		case SCF_ERROR_INVALID_ARGUMENT:
			die(gettext("Invalid snapshot name.\n"));
			/* NOTREACHED */

		case SCF_ERROR_NOT_FOUND:
			if (sflag == 0) {
				scf_snapshot_destroy(snap);
				snap = NULL;
			} else
				die(gettext("No such snapshot.\n"));
			break;

		default:
			scfdie();
		}
	}

	return (snap);
}
예제 #13
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);
}
예제 #14
0
/*
 * Start transaction on current pg in handle.
 * The pg could be service or instance level.
 * Must be called after pg handle is obtained
 * from create or get.
 */
int
smb_smf_start_transaction(smb_scfhandle_t *handle)
{
	int ret = SMBD_SMF_OK;

	if (!handle || (!handle->scf_pg))
		return (SMBD_SMF_SYSTEM_ERR);

	/*
	 * lookup the property group and create it if it doesn't already
	 * exist.
	 */
	if (handle->scf_state == SCH_STATE_INIT) {
		if (ret == SMBD_SMF_OK) {
			handle->scf_trans =
			    scf_transaction_create(handle->scf_handle);
			if (handle->scf_trans != NULL) {
				if (scf_transaction_start(handle->scf_trans,
				    handle->scf_pg) != 0) {
					ret = SMBD_SMF_SYSTEM_ERR;
					scf_transaction_destroy(
					    handle->scf_trans);
					handle->scf_trans = NULL;
				}
			} else {
				ret = SMBD_SMF_SYSTEM_ERR;
			}
		}
	}
	if (ret == SMBD_SMF_SYSTEM_ERR &&
	    scf_error() == SCF_ERROR_PERMISSION_DENIED)
		ret = SMBD_SMF_NO_PERMISSION;

	return (ret);
}
예제 #15
0
파일: inetadm.c 프로젝트: andreiw/polaris
static int
set_svc_enable_cb(void *data, scf_walkinfo_t *wip)
{
	uint8_t			desired = *(uint8_t *)data;
	const char		*instname = wip->fmri;

	if (desired) {
		if (smf_enable_instance(instname, 0) == 0)
			return (0);
	} else {
		if (smf_disable_instance(instname, 0) == 0)
			return (0);
	}

	switch (scf_error()) {
	case SCF_ERROR_INVALID_ARGUMENT:
		uu_die(gettext("Error: \"%s\" is not a valid service "
		    "instance.\n"), instname);
		break;
	case SCF_ERROR_NOT_FOUND:
		uu_die(gettext("Error: Service instance \"%s\" not found.\n"),
		    instname);
		break;
	default:
		scfdie();
	}

	return (0);
}
예제 #16
0
/*
 * smb_smf_scf_log_error(msg)
 * Logs error messages from scf API's
 */
static void
smb_smf_scf_log_error(char *msg)
{
	if (msg == NULL)
		msg = "SMBD SMF problem";

	syslog(LOG_ERR, " %s: %s", msg, scf_strerror(scf_error()));
}
예제 #17
0
파일: mgmt_scf.c 프로젝트: imp/slist
targ_scf_t *
mgmt_handle_init(void)
{
	targ_scf_t	*h;

	h = calloc(1, sizeof (targ_scf_t));
	if (h == NULL)
		return (NULL);

	h->t_handle = scf_handle_create(SCF_VERSION);
	if (h->t_handle != NULL) {
		if (scf_handle_bind(h->t_handle) == 0) {
			h->t_scope	= scf_scope_create(h->t_handle);
			h->t_service	= scf_service_create(h->t_handle);
			h->t_pg		= scf_pg_create(h->t_handle);
			h->t_instance	= scf_instance_create(h->t_handle);
			if (scf_handle_get_scope(h->t_handle, SCF_SCOPE_LOCAL,
			    h->t_scope) == 0) {
				if (scf_scope_get_service(h->t_scope,
				    SA_TARGET_SVC_NAME, h->t_service) != 0)
					goto error;

			} else {
				syslog(LOG_ERR,
				    "Got local scope which is wrong\n");
				goto error;
			}
		} else
			goto error;
	} else {
		free(h);
		h = NULL;
		syslog(LOG_ERR,
		    "iscsitgt could not access SMF repository: %s\n",
		    scf_strerror(scf_error()));
	}

	return (h);
error:
	mgmt_handle_fini(h);
	free(h);
	syslog(LOG_ERR, "iscsitgt SMF initialization problem: %s\n",
	    scf_strerror(scf_error()));
	return (NULL);
}
예제 #18
0
/*ARGSUSED*/
JNIEXPORT void JNICALL
Java_com_sun_dhcpmgr_bridge_Bridge_shutdown(
    JNIEnv *env,
    jobject obj)
{
	if (smf_disable_instance(DHCP_SERVER_INST, 0) != 0) {
		throw_bridge_exception(env, scf_strerror(scf_error()));
	}
}
예제 #19
0
static void *
scf_exception(const char *err, const char *value)
{
	int scferr = scf_error();
	const char *scfstrerr = scf_strerror(scferr);
	PyObject *obj = Py_BuildValue("(isss)", scferr, err, scfstrerr, value);
	PyErr_SetObject(scf_exc, obj);
	return (NULL);
}
예제 #20
0
/*
 * smb_smf_delete_instance_pgroup(handle, pgroup)
 *
 * remove the property group from the current instance.
 * but only if it actually exists.
 */
int
smb_smf_delete_instance_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_instance_get_pg(handle->scf_instance,
	    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);
}
예제 #21
0
/*
 * Reads the value of the enabled property from the named property group
 * of the given instance.
 * If an error occurs, the SCF error code is returned. The possible errors are:
 * - SCF_ERROR_INVALID_ARGUMENT: The enabled property is not a boolean.
 * - SCF_ERROR_NONE: No value exists for the enabled property.
 * - SCF_ERROR_CONNECTION_BROKEN: Repository connection broken.
 * - SCF_ERROR_NOT_FOUND: The property wasn't found.
 * - SCF_ERROR_NO_MEMORY: allocation failure.
 * Else 0 is returned and 'enabled' set appropriately.
 */
static scf_error_t
read_enable_prop(const char *fmri, boolean_t *enabled, const char *pg)
{
	scf_simple_prop_t	*sp;
	uint8_t			*u8p;

	if ((sp = scf_simple_prop_get(rep_handle, fmri, pg,
	    SCF_PROPERTY_ENABLED)) == NULL)
		return (scf_error());

	if ((u8p = scf_simple_prop_next_boolean(sp)) == NULL) {
		scf_simple_prop_free(sp);
		return (scf_error());
	}

	*enabled = (*u8p != 0);
	scf_simple_prop_free(sp);
	return (0);
}
예제 #22
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());
}
예제 #23
0
파일: config.c 프로젝트: alhazred/onarm
/*
 * Returns an allocated instance_cfg_t representation of an instance's
 * configuration read from the repository. If the configuration is invalid, a
 * repository error occurred, or a memory allocation occurred returns NULL,
 * else returns a pointer to the allocated instance_cfg_t.
 */
instance_cfg_t *
read_instance_cfg(const char *fmri)
{
	uint_t		retries;
	inetd_prop_t	*bprops;
	inetd_prop_t	*mprops[NUM_METHODS];
	instance_cfg_t	*ret = NULL;
	scf_error_t	err;

	debug_msg("Entering read_instance_cfg");

	if ((ret = calloc(1, sizeof (instance_cfg_t))) == NULL)
		return (NULL);

	for (retries = 0; retries <= REP_OP_RETRIES; retries++) {
		if (make_handle_bound(rep_handle) == -1) {
			err = scf_error();
			goto read_error;
		}

		if (read_inst_props(fmri, &bprops, mprops, &err) == 0)
			break;
		if (err != SCF_ERROR_CONNECTION_BROKEN)
			goto read_error;
		(void) scf_handle_unbind(rep_handle);
	}
	if (retries > REP_OP_RETRIES)
		goto read_error;

	/*
	 * Switch off validation of the start method's exec string, since
	 * during boot the filesystem it resides on may not have been
	 * mounted yet, which would result in a false validation failure.
	 * We'll catch any real errors when the start method is first run
	 * in passes_basic_exec_checks().
	 */
	bprops[PT_EXEC_INDEX].ip_error = IVE_UNSET;

	if ((!valid_inst_props(fmri, bprops, mprops, &ret->basic)) ||
	    (populate_defaults(bprops, ret->basic) != 0) ||
	    (create_method_infos(fmri, mprops, ret->methods) != 0)) {
		destroy_instance_cfg(ret);
		ret = NULL;
	}

	destroy_inst_props(bprops, mprops);
	return (ret);

read_error:
	error_msg(gettext(
	    "Failed to read the configuration of instance %s: %s"), fmri,
	    scf_strerror(err));
	free(ret);
	return (NULL);
}
예제 #24
0
static int
get_notify_prefs(fmd_hdl_t *hdl, nvlist_t *ev_nvl, nvlist_t ***pref_nvl,
    uint_t *nprefs)
{
	nvlist_t *top_nvl, **np_nvlarr, *mech_nvl;
	nvlist_t **tmparr;
	int ret, i;
	uint_t nelem, nslelem;

	if ((ret = smf_notify_get_params(&top_nvl, ev_nvl)) != SCF_SUCCESS) {
		ret = scf_error();
		if (ret != SCF_ERROR_NOT_FOUND) {
			fmd_hdl_debug(hdl, "Error looking up notification "
			    "preferences (%s)", scf_strerror(ret));
			return (ret);
		}
		return (ret);
	}

	if (nvlist_lookup_nvlist_array(top_nvl, SCF_NOTIFY_PARAMS, &np_nvlarr,
	    &nelem) != 0) {
		fmd_hdl_debug(hdl, "Malformed preference nvlist\n");
		ret = SCF_ERROR_INVALID_ARGUMENT;
		goto pref_done;
	}

	tmparr = fmd_hdl_alloc(hdl, nelem * sizeof (nvlist_t *), FMD_SLEEP);
	nslelem = 0;

	for (i = 0; i < nelem; i++) {
		if (nvlist_lookup_nvlist(np_nvlarr[i], "syslog", &mech_nvl)
		    == 0)
			tmparr[nslelem++] = fmd_nvl_dup(hdl, mech_nvl,
			    FMD_SLEEP);
	}

	if (nslelem != 0) {
		size_t sz = nslelem * sizeof (nvlist_t *);

		*pref_nvl = fmd_hdl_zalloc(hdl, sz, FMD_SLEEP);
		*nprefs = nslelem;
		bcopy(tmparr, *pref_nvl, sz);
		ret = 0;
	} else {
		*pref_nvl = NULL;
		*nprefs = 0;
		ret = SCF_ERROR_NOT_FOUND;
	}

	fmd_hdl_free(hdl, tmparr, nelem * sizeof (nvlist_t *));
pref_done:
	nvlist_free(top_nvl);
	return (ret);
}
예제 #25
0
/*
 * Returns a pointer to an allocated method context for the specified method
 * of the specified instance if it could retrieve it. Else, if there were
 * errors retrieving it, NULL is returned and the pointer referenced by
 * 'errstr' is set to point at an appropriate error string.
 */
struct method_context *
read_method_context(const char *inst_fmri, const char *method, const char *path)
{
	scf_instance_t			*scf_inst = NULL;
	struct method_context		*ret;
	uint_t				retries;
	mc_error_t			*tmperr;
	char				*fail;

	fail = gettext("Failed to retrieve method context for the %s method of "
	    "instance %s : %s");
	for (retries = 0; retries <= REP_OP_RETRIES; retries++) {
		if (make_handle_bound(rep_handle) == -1)
			goto inst_failure;

		if (((scf_inst = scf_instance_create(rep_handle)) != NULL) &&
		    (scf_handle_decode_fmri(rep_handle, inst_fmri, NULL, NULL,
		    scf_inst, NULL, NULL, SCF_DECODE_FMRI_EXACT) == 0))
			break;
		if (scf_error() != SCF_ERROR_CONNECTION_BROKEN) {
			scf_instance_destroy(scf_inst);
			goto inst_failure;
		}

		(void) scf_instance_destroy(scf_inst);
		scf_inst = NULL;

		(void) scf_handle_unbind(rep_handle);
	}
	if (retries > REP_OP_RETRIES)
		goto inst_failure;

	if ((tmperr = restarter_get_method_context(
	    RESTARTER_METHOD_CONTEXT_VERSION, scf_inst, NULL, method, path,
	    &ret)) != NULL) {
		ret = NULL;
		error_msg(fail, method, inst_fmri, tmperr->msg);
		restarter_mc_error_destroy(tmperr);
	}

	scf_instance_destroy(scf_inst);
	return (ret);

inst_failure:
	/*
	 * We can rely on this string not becoming invalid
	 * since we don't call bind_textdomain_codeset() or
	 * setlocale(3C) after initialization.
	 */
	error_msg(fail, method, inst_fmri,
	    gettext("failed to get instance from repository"));
	return (NULL);
}
예제 #26
0
파일: config.c 프로젝트: alhazred/onarm
/*
 * Reads the enabled value for the given instance FMRI. The read value
 * is based on a merge of the 'standard' enabled property, and the temporary
 * override one; the merge involves using the latter properties value if
 * present, else resporting to the formers. If an error occurs -1 is returned,
 * else 0 is returned and 'enabled' set approriately.
 */
int
read_enable_merged(const char *fmri, boolean_t *enabled)
{
	uint_t		retries;

	debug_msg("Entering read_enabled_prop: inst: %s", fmri);

	for (retries = 0; retries <= REP_OP_RETRIES; retries++) {
		if (make_handle_bound(rep_handle) == -1)
			goto gen_fail;

		switch (read_enable_prop(fmri, enabled, SCF_PG_GENERAL_OVR)) {
		case 0:
			debug_msg("read %d from override", *enabled);
			return (0);
		case SCF_ERROR_CONNECTION_BROKEN:
			break;
		case SCF_ERROR_NOT_FOUND:
		case SCF_ERROR_NONE:
		case SCF_ERROR_INVALID_ARGUMENT:
			switch (read_enable_prop(fmri, enabled,
			    SCF_PG_GENERAL)) {
			case 0:
				debug_msg("read %d from non_override",
				    *enabled);
				return (0);
			case SCF_ERROR_CONNECTION_BROKEN:
				break;
			case SCF_ERROR_NOT_FOUND:
			case SCF_ERROR_NONE:
			case SCF_ERROR_INVALID_ARGUMENT:
				error_msg(gettext("Missing %s property/value "
				    "for instance %s"), SCF_PROPERTY_ENABLED,
				    fmri);
				return (-1);
			default:
				goto gen_fail;
			}
			break;
		default:
			goto gen_fail;
		}

		(void) scf_handle_unbind(rep_handle);
		continue;
	}

gen_fail:
	error_msg(gettext("Failed to read the %s property of instance %s: %s"),
	    SCF_PROPERTY_ENABLED, fmri, scf_strerror(scf_error()));
	return (-1);
}
예제 #27
0
파일: mgmt_scf.c 프로젝트: alhazred/onarm
/*
 * This function starts a transaction with name of a property group
 * and name of its property. If the property group does not exist
 * this function will create an empty property group.
 */
Boolean_t
mgmt_transaction_start(targ_scf_t *h, char *pg, char *prop)
{
	Boolean_t	ret = True;

	h->t_trans = scf_transaction_create(h->t_handle);
	if (h->t_trans != NULL) {
		if ((create_pg(h, pg, prop) == False) ||
		    (scf_transaction_start(h->t_trans, h->t_pg) != 0)) {
			scf_transaction_destroy(h->t_trans);
			h->t_trans = NULL;
			ret = False;
			syslog(LOG_ERR, "transaction_start start: %s\n",
			    scf_strerror(scf_error()));
		}
	} else {
		syslog(LOG_ERR, "transaction_start create: %s\n",
		    scf_strerror(scf_error()));
		ret = False;
	}
	return (ret);
}
예제 #28
0
static void *
get_smf_prop(const char *var, char type, void *def_val)
{
	scf_simple_prop_t	*prop;
	void			*val;
	char			*me = "get_smf_prop";

	prop = scf_simple_prop_get(NULL, NULL, "config", var);
	if (prop) {
		switch (type) {
		case 'b':
			val = scf_simple_prop_next_boolean(prop);
			if (val != NULL)
				(void) memcpy(def_val, val, sizeof (uint8_t));
			break;

		case 'i':
			val = scf_simple_prop_next_integer(prop);
			if (val != NULL)
				(void) memcpy(def_val, val, sizeof (int64_t));
			break;
		}
		scf_simple_prop_free(prop);
	}

	if (prop == NULL || val == NULL) {
		char	vs[64];

		switch (type) {
		case 'b':
			if (*(uint8_t *)def_val)
				(void) strcpy(vs, "yes");
			else
				(void) strcpy(vs, "no");

			break;

		case 'i':
			(void) sprintf(vs, "%lld", *(int64_t *)def_val);
			break;

		}
		_NSCD_LOG(NSCD_LOG_SELF_CRED, NSCD_LOG_LEVEL_ALERT)
		(me, "no value for config/%s (%s). "
		    "Using default \"%s\"\n", var,
		    scf_strerror(scf_error()), vs);
	}

	return (def_val);
}
예제 #29
0
static int
pg_get_prop_value(const scf_propertygroup_t *pg, const char *pname,
    scf_value_t *v)
{
	if (pg == NULL || pname == NULL || v == NULL)
		return (-1);

	if (scf_pg_get_property(pg, pname, scratch_prop) == -1 ||
	    scf_property_get_value(scratch_prop, v) == -1) {
		switch (scf_error()) {
		case SCF_ERROR_NOT_FOUND:
		case SCF_ERROR_DELETED:
			break;

		default:
			syslog(LOG_ERR | LOG_DAEMON,
			    "scf_pg_get_property failed for %s: %s\n",
			    pname, scf_strerror(scf_error()));
		}
		return (-1);
	}
	return (0);
}
예제 #30
0
/*
 * Refresh the value of debug property under the property group "config"
 * for network/inetd service.
 */
void
refresh_debug_flag(void)
{
	scf_simple_prop_t	*sprop;
	uint8_t			*tmp_bool;

	if ((sprop = scf_simple_prop_get(rep_handle, INETD_INSTANCE_FMRI,
	    PG_NAME_APPLICATION_CONFIG, PR_NAME_DEBUG_FLAG)) == NULL) {
		error_msg(gettext("Unable to read %s property from %s property "
		    "group. scf_simple_prop_get() failed: %s"),
		    PR_NAME_DEBUG_FLAG, PG_NAME_APPLICATION_CONFIG,
		    scf_strerror(scf_error()));
		return;
	} else if ((tmp_bool = scf_simple_prop_next_boolean(sprop)) == NULL) {
		error_msg(gettext("Unable to read %s property for %s service. "
		    "scf_simple_prop_next_boolean() failed: %s"),
		    PR_NAME_DEBUG_FLAG, INETD_INSTANCE_FMRI,
		    scf_strerror(scf_error()));
	} else {
		debug_enabled = ((*tmp_bool == 0) ? B_FALSE : B_TRUE);
	}

	scf_simple_prop_free(sprop);
}