Ejemplo n.º 1
0
/*
 * if auditd isn't running, start it.  Otherwise refresh.
 * First check to see if c2audit is loaded via the auditon()
 * system call, then check SMF state.
 */
static void
start_auditd()
{
	int	audit_state;
	char	*state;

	if (auditon(A_GETCOND, (caddr_t)&audit_state,
	    sizeof (audit_state)) != 0)
		exit(1);

	if ((state = smf_get_state(AUDITD_FMRI)) == NULL) {
		display_smf_error();
		exit(1);
	}
	if (strcmp(SCF_STATE_STRING_ONLINE, state) != 0) {
		if (smf_enable_instance(AUDITD_FMRI, 0) != 0) {
			display_smf_error();
			free(state);
			exit(1);
		}
	} else {
		if (smf_refresh_instance(AUDITD_FMRI) != 0) {
			display_smf_error();
			free(state);
			exit(1);
		}
	}
	free(state);
}
Ejemplo n.º 2
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()));
}
int isServiceEnabled( void )
{
	static const char *	sInstanceName		= "svc:/network/apocd/udp:default";
	int					isServiceEnabled	= 0;
	char *				theState			= smf_get_state( sInstanceName );
	if ( theState != 0 )
	{
		if ( strcmp( theState, SCF_STATE_STRING_DISABLED ) != 0 )
		{
			isServiceEnabled = 1;
		}
		free( ( void * )theState );
	}
	return isServiceEnabled;
}
Ejemplo n.º 4
0
static boolean_t
is_iscsit_enabled(void)
{
	char		*state;

	state = smf_get_state(ISCSIT_FMRI);
	if (state != NULL) {
		if (strcmp(state, SCF_STATE_STRING_ONLINE) == 0) {
			free(state);
			return (B_TRUE);
		}
		free(state);
	}

	return (B_FALSE);
}
Ejemplo n.º 5
0
gboolean
ck_supports_activatable_consoles (void)
{
        char *state = NULL;
        gboolean vt_enabled;
                               
        state = smf_get_state ("svc:/system/vtdaemon:default");
        if (state && g_str_equal (state, SCF_STATE_STRING_ONLINE)) {
                vt_enabled = TRUE;
        } else {
                vt_enabled = FALSE;
        }           
                    
        g_free (state);
        return vt_enabled;
}
Ejemplo n.º 6
0
static boolean_t
check_svc_up(const char *fmri, int wait_time)
{
	int i;
	char *state;

	for (i = 1; i <= wait_time; i++) {
		state = smf_get_state(fmri);
		if (state == NULL) {
			syslog(LOG_ERR, "smf_get_state(%s) returned \"%s\"",
			    fmri, scf_strerror(scf_error()));
		} else {
			if (strcmp(SCF_STATE_STRING_ONLINE, state) == 0) {
				free(state);
				return (B_TRUE);
			}
			free(state);
		}
		(void) sleep(1);
	}
	return (B_FALSE);
}
Ejemplo n.º 7
0
void
wait_till_to(char *fmri)
{
	char *state;
	useconds_t max;
	useconds_t usecs;
	uint64_t *cp = NULL;
	scf_simple_prop_t *sp = NULL;

	max = DEFAULT_TIMEOUT;

	if (((sp = scf_simple_prop_get(NULL, fmri, "stop",
	    SCF_PROPERTY_TIMEOUT)) != NULL) &&
	    ((cp = scf_simple_prop_next_count(sp)) != NULL) && (*cp != 0))
		max = (*cp) * 1000000;	/* convert to usecs */

	if (sp != NULL)
		scf_simple_prop_free(sp);

	for (usecs = INIT_WAIT_USECS; max > 0; max -= usecs) {
		/* incremental wait */
		usecs *= 2;
		usecs = (usecs > max) ? max : usecs;

		(void) usleep(usecs);

		/* Check state after the wait */
		if ((state = smf_get_state(fmri)) != NULL) {
			if (strcmp(state, "disabled") == 0)
				return;
		}
	}

	(void) fprintf(stderr, gettext("Warning: delete %s timed out.\n"),
	    fmri);
}
Ejemplo n.º 8
0
/* Enables the location. */
static void
nwamd_loc_activate(const char *object_name)
{
	char *enabled;

	nlog(LOG_DEBUG, "nwamd_loc_activate: activating loc %s",
	    object_name);

	/*
	 * Find currently enabled location and change its state to disabled
	 * if it is a manual location, or offline (if it is not).
	 * Only manual locations reach disabled, since conditional and
	 * system locations which are manually disabled simply revert to
	 * their conditions for activation.
	 */
	if ((enabled = malloc(NWAM_MAX_NAME_LEN)) != NULL &&
	    nwamd_lookup_string_property(NET_LOC_FMRI, NET_LOC_PG,
	    NET_LOC_SELECTED_PROP, enabled, NWAM_MAX_NAME_LEN) == 0) {
		/* Only change state if current != new */
		if (strcmp(enabled, object_name) != 0) {
			boolean_t do_disable = B_FALSE;
			nwamd_object_t eobj = nwamd_object_find
			    (NWAM_OBJECT_TYPE_LOC, enabled);
			if (eobj == NULL) {
				nlog(LOG_INFO, "nwamd_loc_activate: could not "
				    "find old location %s", enabled);
				goto skip_disable;
			}
			/*
			 * Disable if the old location was manual, since the
			 * only way a manual location can deactivate is if
			 * it is disabled.
			 */
			do_disable =
			    (loc_get_activation_mode(eobj->nwamd_object_handle)
			    == (int64_t)NWAM_ACTIVATION_MODE_MANUAL);
			nwamd_object_release(eobj);

			if (do_disable) {
				nlog(LOG_DEBUG, "nwamd_loc_activate: "
				    "disable needed for old location %s",
				    enabled);
				nwamd_object_set_state
				    (NWAM_OBJECT_TYPE_LOC, enabled,
				    NWAM_STATE_DISABLED,
				    NWAM_AUX_STATE_MANUAL_DISABLE);
			} else {
				nlog(LOG_DEBUG, "nwamd_loc_activate: "
				    "offline needed for old location %s",
				    enabled);
				nwamd_object_set_state
				    (NWAM_OBJECT_TYPE_LOC, enabled,
				    NWAM_STATE_OFFLINE,
				    NWAM_AUX_STATE_CONDITIONS_NOT_MET);
			}
		}
	}
skip_disable:
	free(enabled);

	if (nwamd_set_string_property(NET_LOC_FMRI, NET_LOC_PG,
	    NET_LOC_SELECTED_PROP, object_name) == 0) {
		char *state = smf_get_state(NET_LOC_FMRI);
		nlog(LOG_INFO, "nwamd_loc_activate: set %s/%s to %s; "
		    "service is in %s state", NET_LOC_PG, NET_LOC_SELECTED_PROP,
		    object_name, state == NULL ? "unknown" : state);
		free(state);
		(void) smf_restore_instance(NET_LOC_FMRI);
		if (smf_refresh_instance(NET_LOC_FMRI) == 0) {
			(void) pthread_mutex_lock(&active_loc_mutex);
			(void) strlcpy(active_loc, object_name,
			    sizeof (active_loc));
			(void) pthread_mutex_unlock(&active_loc_mutex);
			nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
			    object_name,
			    NWAM_STATE_ONLINE, NWAM_AUX_STATE_ACTIVE);
		} else {
			nlog(LOG_ERR, "nwamd_loc_activate: "
			    "%s could not be refreshed", NET_LOC_FMRI);
			nwamd_object_set_state(NWAM_OBJECT_TYPE_LOC,
			    object_name,
			    NWAM_STATE_MAINTENANCE,
			    NWAM_AUX_STATE_METHOD_FAILED);
		}
	}
}
Ejemplo n.º 9
0
static int
is_correct_event(const char *fmri, const scf_propertygroup_t *pg,
    const boolean_t isrpc)
{
	char *state = NULL;
	const char **proplist = all_props;
	int prop_cnt = ALL_PROPS_CNT;

	int i, ret = 0;

	if (scf_pg_get_name(pg, scratch_name, max_scf_name_size) < 0) {
		syslog(LOG_ERR | LOG_DAEMON, "scf_pg_get_name failed: %s\n",
		    scf_strerror(scf_error()));
		return (-1);
	}

	/*
	 * We care about enable, disable, and refresh since that's
	 * when we activate, deactivate, or change firewall policy.
	 *
	 *  - enable/disable -> change in "general" or "general_ovr"
	 *  - refresh/restart -> change in "restarter_actions"
	 */
	if (strcmp(scratch_name, SCF_PG_GENERAL) == 0 ||
	    strcmp(scratch_name, SCF_PG_GENERAL_OVR) == 0) {
		syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s", scratch_name);
		return (1);
	}

	if ((state = smf_get_state(fmri)) == NULL) {
		syslog(LOG_ERR | LOG_DAEMON, "smf_get_state failed for %s: "
		    "%s\n", fmri, scf_strerror(scf_error()));
		return (-1);
	}

	syslog(LOG_DEBUG | LOG_DAEMON, "%s STATE: %s \n", fmri, state);
	if (strcmp(state, SCF_STATE_STRING_MAINT) == 0) {
		proplist = maint_props;
		prop_cnt = MAINT_PROPS_CNT;
	}

	/*
	 * Only concerned with refresh, restart, and maint on|off actions.
	 * RPC services are restarted whenever rpc/bind restarts so it's
	 * an automatic valid event for RPC services.
	 */
	if (isrpc) {
		ret = 1;
		goto out;
	} else if (strcmp(scratch_name, SCF_PG_RESTARTER_ACTIONS) == 0) {
		for (i = 0; i < prop_cnt; i++) {
			if (pg_get_prop_value(pg, proplist[i],
			    scratch_v) == 0) {
				syslog(LOG_DEBUG | LOG_DAEMON, "Action: %s/%s",
				    scratch_name, proplist[i]);

				ret = 1;
				goto out;
			}
		}
	}

out:
	if (state)
		free(state);

	return (ret);
}
Ejemplo n.º 10
0
int
main(int argc, char *argv[])
{
	int c;			/* options character */
	int type = 0;		/* type of accounting */
	int modified = 0;	/* have we modified any properties? */
	acctconf_t ac;		/* current configuration */
	char *typestr = NULL;	/* type of accounting argument string */
	char *enabled = NULL;	/* enabled resources string */
	char *disabled = NULL;	/* disabled resources string */
	char *file = NULL;
	int Eflg = 0;
	int Dflg = 0;
	int rflg = 0;
	int sflg = 0;
	int xflg = 0;
	int optcnt = 0;
	int state;
	const char *fmri;	/* FMRI for this instance */
	int err = 0;

	setup_privs();

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);
	(void) setpname(argv[0]);

	for (; optind < argc; optind++) {
		while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
			switch (c) {
			case 'd':
				disabled = optarg;
				break;
			case 'e':
				enabled = optarg;
				break;
			case 'D':
				Dflg = 1;
				optcnt++;
				break;
			case 'E':
				Eflg = 1;
				optcnt++;
				break;
			case 'f':
				file = optarg;
				optcnt++;
				break;
			case 'r':
				rflg = 1;
				optcnt++;
				break;
			case 's':
				sflg = 1;
				optcnt++;
				break;
			case 'x':
				xflg = 1;
				optcnt++;
				break;
			case '?':
			default:
				usage();
			}
		}

		/*
		 * Permanently give up euid 0, egid 0 and privileges we
		 * don't need for the specified options.
		 */
		if (!(file || sflg)) {
			if (setreuid(getuid(), getuid()) == -1 ||
			    setregid(getgid(), getgid()) == -1)
				die(gettext("setreuid()/setregid() failed"));
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_FILE_DAC_WRITE, NULL);
		}
		if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
		    xflg))
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);

		if (optind < argc) {
			if (typestr != NULL) {
				warn(gettext("illegal argument -- %s\n"),
				    argv[optind]);
				usage();
			} else {
				typestr = argv[optind];
			}
		}
	}
	if (typestr != NULL) {
		if (strcmp(typestr, "process") == 0 ||
		    strcmp(typestr, "proc") == 0)
			type |= AC_PROC;
		else if (strcmp(typestr, "task") == 0)
			type |= AC_TASK;
		else if (strcmp(typestr, "flow") == 0)
			type |= AC_FLOW;
		else if (strcmp(typestr, "net") == 0)
			type |= AC_NET;
		else {
			warn(gettext("unknown accounting type -- %s\n"),
			    typestr);
			usage();
		}
	} else
		type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;

	/*
	 * Drop the DL config privilege if we are not working with
	 * net.
	 */
	if ((type & AC_NET) == 0) {
		(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
		    PRIV_SYS_DL_CONFIG, NULL);
	}
	/*
	 * check for invalid options
	 */
	if (optcnt > 1)
		usage();

	/*
	 * XXX For AC_NET, enabled/disabled should only be "basic" or
	 * "extended" - need to check it here.
	 */
	if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
		usage();

	if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
	    !typestr) {
		warn(gettext("accounting type must be specified\n"));
		usage();
	}

	if (rflg) {
		printgroups(type);
		return (E_SUCCESS);
	}

	/*
	 * If no arguments have been passed then just print out the current
	 * state and exit.
	 */
	if (!enabled && !disabled && !file &&
	    !Eflg && !rflg && !Dflg && !sflg && !xflg) {
		aconf_print(stdout, type);
		return (E_SUCCESS);
	}

	/* Open the libdladm handle */
	if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
		die(gettext("failed to open dladm handle\n"));

	/*
	 * smf(5) start method.  The FMRI to operate on is retrieved from the
	 * SMF_FMRI environment variable that the restarter provides.
	 */
	if (sflg) {
		if ((fmri = getenv("SMF_FMRI")) != NULL) {
			int ret = aconf_setup(fmri);
			dladm_close(dld_handle);
			return (ret);
		}

		die(gettext("-s option should only be invoked by smf(5)\n"));
	}

	assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
	    type == AC_NET);

	if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
		die(gettext("%s accounting cannot be configured in "
		    "non-global zones\n"), ac_type_name(type));

	fmri = aconf_type2fmri(type);
	if (aconf_scf_init(fmri) == -1)
		die(gettext("cannot connect to repository for %s\n"), fmri);

	/*
	 * Since the sys_acct the privilege allows use of acctctl() regardless
	 * of the accounting type, we check the smf(5) authorizations granted
	 * to the user to determine whether the user is allowed to change the
	 * configuration for this particular accounting type.
	 */
	if (!aconf_have_smf_auths())
		die(gettext("insufficient authorization to change %s extended "
		    "accounting configuration\n"), ac_type_name(type));

	if (xflg) {
		/*
		 * Turn off the specified accounting and close its file
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging network "
				    "information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
			die(gettext("cannot close %s accounting file\n"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		modified++;
	}

	if (enabled || disabled) {
		char *tracked, *untracked;
		ac_res_t *buf;

		/*
		 * Enable/disable resources
		 */
		if ((buf = malloc(AC_BUFSIZE)) == NULL)
			die(gettext("not enough memory\n"));
		(void) memset(buf, 0, AC_BUFSIZE);
		if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot obtain list of resources\n"));
		}
		if (disabled) {
			/*
			 * Stop net logging before turning it off so that the
			 * last set of logs can be written.
			 */
			if (type & AC_NET) {
				(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				err = dladm_stop_usagelog(dld_handle,
				    strcmp(disabled, "basic") == 0 ?
				    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW);
				(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				if (err != DLADM_STATUS_OK) {
					die(gettext("failed to stop logging "
					    "network information, error %d\n"),
					    errno);
				}
			}
			str2buf(buf, disabled, AC_OFF, type);
		} else if (enabled) {
			str2buf(buf, enabled, AC_ON, type);
		}
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot enable/disable %s accounting "
			    "resources\n"), ac_type_name(type));
		}
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
		untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
		if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_TRACKED);
		if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_UNTRACKED);
		free(tracked);
		free(untracked);
		free(buf);
		modified++;
	}

	if (file) {
		/*
		 * Open new accounting file
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (open_exacct_file(file, type) == -1) {
			dladm_close(dld_handle);
			exit(E_ERROR);
		}
		if (aconf_set_string(AC_PROP_FILE, file) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		state = AC_ON;

		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	/*
	 * Let's get network logging started. We do this after turning on
	 * accounting and opening the file so that we can start writing
	 * immediately.
	 */
	if (enabled && (type & AC_NET)) {
		/*
		 * Default logging interval for AC_NET is
		 * ACCTADM_NET_LOG_INTERVAL.
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		err = dladm_start_usagelog(dld_handle,
		    strcmp(enabled, "basic") == 0 ?
		    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW,
		    ACCTADM_NET_LOG_INTERVAL);
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		if (err != DLADM_STATUS_OK) {
			die(gettext("failed to start logging "
			    "network information, error %d\n"),
			    errno);
		}
	}

	if (Dflg) {
		/*
		 * Disable accounting
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	if (Eflg) {
		/*
		 * Enable accounting
		 */

		/*
		 * Let's get network logging started.
		 */
		if (type & AC_NET) {
			/*
			 * Default logging interval for AC_NET is
			 * ACCTADM_NET_LOG_INTERVAL.
			 */
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_start_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to start logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_ON;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}
	(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);

	if (modified) {
		char *smf_state;

		if (aconf_save() == -1)
			die(gettext("cannot save %s accounting "
			    "configuration\n"), ac_type_name(type));

		/*
		 * Enable or disable the instance depending on the effective
		 * configuration.  If the effective configuration results in
		 * extended accounting being 'on', the instance is enabled so
		 * the configuration is applied at the next boot.
		 */
		smf_state = smf_get_state(fmri);
		aconf_init(&ac, type);

		if (ac.state == AC_ON ||
		    strcmp(ac.file, AC_STR_NONE) != 0 ||
		    strcmp(ac.tracked, AC_STR_NONE) != 0) {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
				if (smf_enable_instance(fmri, 0) == -1)
					die(gettext("cannot enable %s\n"),
					    fmri);
		} else {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
				if (smf_disable_instance(fmri, 0) == -1)
					die(gettext("cannot disable %s\n"),
					    fmri);
		}
		free(smf_state);
	}
	aconf_scf_fini();
	dladm_close(dld_handle);
	return (E_SUCCESS);
}
Ejemplo n.º 11
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);
}