Exemplo n.º 1
0
static int
repository_event_process(scf_propertygroup_t *pg)
{
	boolean_t isrpc = B_FALSE;
	int res;

	/*
	 * Figure out it's a firewall capable instance and call ipfilter_update
	 * if it is.
	 */
	if (scf_pg_get_parent_instance(pg, inst) == -1) {
		/* Not an error if pg doesn't belong to a valid instance */
		if (scf_error() == SCF_ERROR_CONSTRAINT_VIOLATED) {
			return (0);
		}

		syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_parent_instance "
		    "failed: %s\n", scf_strerror(scf_error()));

		if (scf_error() == SCF_ERROR_CONNECTION_BROKEN)
			repository_setup();

		return (1);
	}

	if (scf_instance_to_fmri(inst, scratch_fmri, max_scf_fmri_size) == -1) {
		syslog(LOG_ERR | LOG_DAEMON, "scf_instance_to_fmri "
		    "failed: %s\n", scf_strerror(scf_error()));

		if (scf_error() == SCF_ERROR_CONNECTION_BROKEN)
			repository_setup();

		return (1);
	}

	if (strcmp(scratch_fmri, IPFILTER_FMRI) == 0) {
		return (0);
	}

	isrpc = service_is_rpc(inst);

	/*
	 * If it's not an event we're interested in, returns success.
	 */
	res = is_correct_event(scratch_fmri, pg, isrpc);
	if (res == -1) {
		syslog(LOG_ERR | LOG_DAEMON,
		    "is_correct_event failed for %s.\n", scratch_fmri);
		return (1);
	} else if (res == 0) {
		return (0);
	}

	/*
	 * Proceed only if instance has firewall policy.
	 */
	res = instance_has_firewall(inst);
	if (res == -1) {
		syslog(LOG_ERR | LOG_DAEMON,
		    "instance_has_firewall failed for %s.\n", scratch_fmri);
		return (1);
	} else if (res == 0) {
		return (0);
	}

	if (ipfilter_update(scratch_fmri) == -1) {
		return (1);
	}

	return (0);
}
Exemplo n.º 2
0
static int
create_instance(scf_handle_t *handle, scf_service_t *svc,
    const char *instance_name, const char *kssl_entry, const char *command,
    const char *username, char *inaddr_any_name)
{
	int status = FAILURE;
	char *buf;
	boolean_t errflag = B_FALSE;
	ssize_t max_fmri_len;
	scf_instance_t *instance;

	instance = scf_instance_create(handle);
	if (instance == NULL) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_instance_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out;
	}
	KSSL_DEBUG("scf_instance_create succeeded\n");

	if (scf_service_get_instance(svc, inaddr_any_name, instance) == 0) {
		/* Let the caller deal with the duplicate instance */
		status = INSTANCE_ANY_EXISTS;
		goto out;
	}

	if (scf_service_add_instance(svc, instance_name, instance) != 0) {
		if (scf_error() == SCF_ERROR_EXISTS) {
			/* Let the caller deal with the duplicate instance */
			status = INSTANCE_OTHER_EXISTS;
			goto out;
		}

		errflag = B_TRUE;
		KSSL_DEBUG("scf_service_add_instance failed: %s\n",
		    scf_strerror(scf_error()));
		goto out;
	}
	KSSL_DEBUG("scf_service_add_instance succeeded\n");

	if ((add_pg_method(handle, instance, kssl_entry, "start",
		command, username) != SUCCESS) ||
	    (add_pg_method(handle, instance, kssl_entry, "refresh",
		command, username) != SUCCESS) ||
	    (add_pg_method(handle, instance, kssl_entry, "stop",
		"", username) != SUCCESS)) {
		scf_instance_destroy(instance);
		return (status);
	}

	/* enabling the instance */
	max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
	if ((buf = malloc(max_fmri_len + 1)) == NULL)
		goto out;

	if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
		KSSL_DEBUG("instance_fmri=%s\n", buf);
		if (smf_enable_instance(buf, 0) != 0) {
			errflag = B_TRUE;
			KSSL_DEBUG(
			    "smf_enable_instance failed: %s\n",
			    scf_strerror(scf_error()));
			goto out;
		}
		status = SUCCESS;
	}

out:
	if (instance != NULL)
		scf_instance_destroy(instance);
	if (errflag)
		(void) fprintf(stderr, gettext(
		    "Unexpected fatal libscf error: %s. Exiting.\n"),
		    scf_strerror(scf_error()));
	return (status);
}
Exemplo n.º 3
0
/*ARGSUSED*/
static int
list_callback(scf_handle_t *hin, scf_instance_t *inst, void *buf)
{
	ssize_t			max_name_length;
	char			*inst_name;
	scf_simple_prop_t	*prop = NULL, *prop2 = NULL;
	const uint8_t		*enabled;
	const char		*state, *restart_str;

	max_name_length = scf_limit(SCF_LIMIT_MAX_NAME_LENGTH);
	if ((inst_name = malloc(max_name_length + 1)) == NULL)
		uu_die(gettext("Error: Out of memory.\n"));

	/*
	 * Get the FMRI of the instance, and check if its delegated restarter
	 * is inetd.
	 */

	if (scf_instance_to_fmri(inst, inst_name, max_name_length + 1) < 0)
		return (SCF_FAILED);

	if ((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL,
	    SCF_PROPERTY_RESTARTER)) == NULL)
		goto out;

	if ((restart_str = scf_simple_prop_next_ustring(prop)) == NULL)
		goto out;

	if (strstr(restart_str, INETADM_INETD_STR) == NULL)
		goto out;

	/* Free restarter prop so it can be reused below */
	scf_simple_prop_free(prop);

	/*
	 * We know that this instance is managed by inetd.
	 * Now get the enabled and state properties.
	 */

	if (((prop = scf_simple_prop_get(hin, inst_name, SCF_PG_GENERAL,
	    SCF_PROPERTY_ENABLED)) == NULL) ||
	    ((enabled = scf_simple_prop_next_boolean(prop)) == NULL)) {
		(void) uu_warn(gettext("Error: Instance %s is missing enabled "
		    "property.\n"), inst_name);
		goto out;
	}

	if (((prop2 = scf_simple_prop_get(hin, inst_name, SCF_PG_RESTARTER,
	    SCF_PROPERTY_STATE)) == NULL) ||
	    ((state = scf_simple_prop_next_astring(prop2)) == NULL)) {
		(void) uu_warn(gettext("Error: Instance %s is missing state "
		    "property.\n"), inst_name);
		goto out;
	}

	/* Print enabled/disabled, state, and FMRI for the instance. */

	if (*enabled)
		(void) printf("%-10s%-15s%s\n", INETADM_ENABLED_STR, state,
		    inst_name);
	else
		(void) printf("%-10s%-15s%s\n", INETADM_DISABLED_STR, state,
		    inst_name);

out:
	free(inst_name);
	scf_simple_prop_free(prop);
	scf_simple_prop_free(prop2);
	return (SCF_SUCCESS);
}
Exemplo n.º 4
0
int
delete_instance(const char *instance_name)
{
	int status = FAILURE;
	char *buf;
	boolean_t errflag = B_FALSE;
	ssize_t max_fmri_len;
	scf_scope_t *scope;
	scf_service_t *svc;
	scf_handle_t *handle;
	scf_instance_t *instance;

	handle = scf_handle_create(SCF_VERSION);
	if (handle == NULL) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_handle_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out1;
	}
	KSSL_DEBUG("scf_handle_create succeeded\n");

	if (scf_handle_bind(handle) == -1) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_handle_bind failed: %s\n",
		    scf_strerror(scf_error()));
		goto out1;
	}
	KSSL_DEBUG("scf_handle_bind succeeded\n");

	if ((scope = scf_scope_create(handle)) == NULL) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_scope_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out2;
	}
	KSSL_DEBUG("scf_scope_create succeeded\n");

	if ((svc = scf_service_create(handle)) == NULL) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_service_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out3;
	}
	KSSL_DEBUG("scf_service_create succeeded\n");

	if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_handle_get_scope failed: %s\n",
		    scf_strerror(scf_error()));
		goto out4;
	}
	KSSL_DEBUG("scf_handle_get_scope succeeded\n");

	if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0) {
		scf_error_t scf_errnum = scf_error();

		if (scf_errnum != SCF_ERROR_NOT_FOUND) {
			errflag = B_TRUE;
			KSSL_DEBUG(
			    "ERROR scf_scope_get_service failed: %s\n",
			    scf_strerror(scf_errnum));
		}
		goto out4;
	} else {
		KSSL_DEBUG("scf_scope_get_service succeeded\n");
	}

	instance = scf_instance_create(handle);
	if (instance == NULL) {
		errflag = B_TRUE;
		KSSL_DEBUG("scf_instance_create failed: %s\n",
		    scf_strerror(scf_error()));
		goto out4;
	}

	if (scf_service_get_instance(svc, instance_name, instance) != 0) {
		scf_error_t scf_errnum = scf_error();

		if (scf_errnum == SCF_ERROR_NOT_FOUND) {
			status = SUCCESS;
		} else {
			errflag = B_TRUE;
			KSSL_DEBUG(
			    "ERROR scf_scope_get_service failed: %s\n",
			    scf_strerror(scf_errnum));
		}
		scf_instance_destroy(instance);
		goto out4;
	}

	max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
	if ((buf = malloc(max_fmri_len + 1)) == NULL)
		goto out4;

	if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
		char *state;

		KSSL_DEBUG("instance_fmri=%s\n", buf);
		state = smf_get_state(buf);
		if (state)
			KSSL_DEBUG("state=%s\n", state);
		if (state && strcmp(state, "online") == 0) {
			if (smf_disable_instance(buf, 0) != 0) {
				errflag = B_TRUE;
				KSSL_DEBUG(
				    "smf_disable_instance failed: %s\n",
				    scf_strerror(scf_error()));
			} else {
				/*
				 * Wait for some time till timeout to avoid
				 * a race with scf_instance_delete() below.
				 */
				wait_till_to(buf);
			}
		}
	}

	if (scf_instance_delete(instance) != 0) {
		errflag = B_TRUE;
		KSSL_DEBUG(
		    "ERROR scf_instance_delete failed: %s\n",
		    scf_strerror(scf_error()));
		goto out4;
	} else {
		KSSL_DEBUG("deleted %s\n", instance_name);
	}

	status = SUCCESS;

out4:
	scf_service_destroy(svc);
out3:
	scf_scope_destroy(scope);
out2:
	(void) scf_handle_unbind(handle);
out1:
	if (handle != NULL)
		scf_handle_destroy(handle);
	if (errflag)
		(void) fprintf(stderr, gettext(
		    "Unexpected fatal libscf error: %s.  Exiting.\n"),
		    scf_strerror(scf_error()));
	return (status);
}
Exemplo n.º 5
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);
}