xref: /titanic_51/usr/src/cmd/acctadm/main.c (revision 074e084f68dd0b08686612bec695a0cfe249da6d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*074e084fSml93401  * Common Development and Distribution License (the "License").
6*074e084fSml93401  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*074e084fSml93401  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/acctctl.h>
29*074e084fSml93401 #include <assert.h>
307c478bd9Sstevel@tonic-gate #include <stdio.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include <libintl.h>
367c478bd9Sstevel@tonic-gate #include <locale.h>
37*074e084fSml93401 #include <priv.h>
38*074e084fSml93401 #include <libscf.h>
39*074e084fSml93401 #include <zone.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include "utils.h"
427c478bd9Sstevel@tonic-gate #include "aconf.h"
437c478bd9Sstevel@tonic-gate #include "res.h"
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate static const char USAGE[] = "\
467c478bd9Sstevel@tonic-gate Usage:\n\
477c478bd9Sstevel@tonic-gate     acctadm [ {process | task | flow} ]\n\
48*074e084fSml93401     acctadm -s\n\
497c478bd9Sstevel@tonic-gate     acctadm -r [ {process | task | flow} ]\n\
507c478bd9Sstevel@tonic-gate     acctadm -x|-E|-D {process | task | flow}\n\
517c478bd9Sstevel@tonic-gate     acctadm -f filename {process | task | flow}\n\
527c478bd9Sstevel@tonic-gate     acctadm -e resources -d resources {process | task | flow}\n";
537c478bd9Sstevel@tonic-gate 
54*074e084fSml93401 static const char OPTS[] = "rsxf:e:d:ED";
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate static void
577c478bd9Sstevel@tonic-gate usage()
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(USAGE));
607c478bd9Sstevel@tonic-gate 	exit(E_USAGE);
617c478bd9Sstevel@tonic-gate }
627c478bd9Sstevel@tonic-gate 
63*074e084fSml93401 static void
64*074e084fSml93401 setup_privs()
65*074e084fSml93401 {
66*074e084fSml93401 	priv_set_t *privset;
67*074e084fSml93401 
68*074e084fSml93401 	if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
69*074e084fSml93401 		die(gettext("seteuid()/setegid() failed"));
70*074e084fSml93401 
71*074e084fSml93401 	/*
72*074e084fSml93401 	 * Add our privileges and remove unneeded 'basic' privileges from the
73*074e084fSml93401 	 * permitted set.
74*074e084fSml93401 	 */
75*074e084fSml93401 	if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
76*074e084fSml93401 		die(gettext("cannot setup privileges"));
77*074e084fSml93401 
78*074e084fSml93401 	(void) priv_addset(privset, PRIV_SYS_ACCT);
79*074e084fSml93401 	(void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
80*074e084fSml93401 	(void) priv_delset(privset, PRIV_FILE_LINK_ANY);
81*074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_EXEC);
82*074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_FORK);
83*074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_INFO);
84*074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_SESSION);
85*074e084fSml93401 	priv_inverse(privset);
86*074e084fSml93401 	if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
87*074e084fSml93401 		die(gettext("cannot setup privileges"));
88*074e084fSml93401 	priv_freeset(privset);
89*074e084fSml93401 
90*074e084fSml93401 	/*
91*074e084fSml93401 	 * Clear the Inheritable and Limit sets.
92*074e084fSml93401 	 */
93*074e084fSml93401 	if ((privset = priv_allocset()) == NULL)
94*074e084fSml93401 		die(gettext("cannot setup privileges"));
95*074e084fSml93401 	priv_emptyset(privset);
96*074e084fSml93401 	if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
97*074e084fSml93401 	    setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
98*074e084fSml93401 		die(gettext("cannot setup privileges"));
99*074e084fSml93401 
100*074e084fSml93401 	/*
101*074e084fSml93401 	 * Turn off the sys_acct and file_dac_write privileges until needed.
102*074e084fSml93401 	 */
103*074e084fSml93401 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
104*074e084fSml93401 	    PRIV_SYS_ACCT, NULL);
105*074e084fSml93401 }
106*074e084fSml93401 
1077c478bd9Sstevel@tonic-gate int
1087c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	int c;			/* options character */
1117c478bd9Sstevel@tonic-gate 	int type = 0;		/* type of accounting */
112*074e084fSml93401 	int modified = 0;	/* have we modified any properties? */
1137c478bd9Sstevel@tonic-gate 	acctconf_t ac;		/* current configuration */
1147c478bd9Sstevel@tonic-gate 	char *typestr = NULL;	/* type of accounting argument string */
1157c478bd9Sstevel@tonic-gate 	char *enabled = NULL;	/* enabled resources string */
1167c478bd9Sstevel@tonic-gate 	char *disabled = NULL;	/* disabled resources string */
1177c478bd9Sstevel@tonic-gate 	char *file = NULL;
1187c478bd9Sstevel@tonic-gate 	int Eflg = 0;
1197c478bd9Sstevel@tonic-gate 	int Dflg = 0;
1207c478bd9Sstevel@tonic-gate 	int rflg = 0;
121*074e084fSml93401 	int sflg = 0;
1227c478bd9Sstevel@tonic-gate 	int xflg = 0;
1237c478bd9Sstevel@tonic-gate 	int optcnt = 0;
1247c478bd9Sstevel@tonic-gate 	int state;
125*074e084fSml93401 	const char *fmri;	/* FMRI for this instance */
126*074e084fSml93401 
127*074e084fSml93401 	setup_privs();
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1307c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1317c478bd9Sstevel@tonic-gate 	(void) setprogname(argv[0]);
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate 	for (; optind < argc; optind++) {
1347c478bd9Sstevel@tonic-gate 		while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
1357c478bd9Sstevel@tonic-gate 			switch (c) {
1367c478bd9Sstevel@tonic-gate 			case 'd':
1377c478bd9Sstevel@tonic-gate 				disabled = optarg;
1387c478bd9Sstevel@tonic-gate 				break;
1397c478bd9Sstevel@tonic-gate 			case 'e':
1407c478bd9Sstevel@tonic-gate 				enabled = optarg;
1417c478bd9Sstevel@tonic-gate 				break;
1427c478bd9Sstevel@tonic-gate 			case 'D':
1437c478bd9Sstevel@tonic-gate 				Dflg = 1;
1447c478bd9Sstevel@tonic-gate 				optcnt++;
1457c478bd9Sstevel@tonic-gate 				break;
1467c478bd9Sstevel@tonic-gate 			case 'E':
1477c478bd9Sstevel@tonic-gate 				Eflg = 1;
1487c478bd9Sstevel@tonic-gate 				optcnt++;
1497c478bd9Sstevel@tonic-gate 				break;
1507c478bd9Sstevel@tonic-gate 			case 'f':
1517c478bd9Sstevel@tonic-gate 				file = optarg;
1527c478bd9Sstevel@tonic-gate 				optcnt++;
1537c478bd9Sstevel@tonic-gate 				break;
1547c478bd9Sstevel@tonic-gate 			case 'r':
1557c478bd9Sstevel@tonic-gate 				rflg = 1;
1567c478bd9Sstevel@tonic-gate 				optcnt++;
1577c478bd9Sstevel@tonic-gate 				break;
158*074e084fSml93401 			case 's':
159*074e084fSml93401 				sflg = 1;
1607c478bd9Sstevel@tonic-gate 				optcnt++;
1617c478bd9Sstevel@tonic-gate 				break;
1627c478bd9Sstevel@tonic-gate 			case 'x':
1637c478bd9Sstevel@tonic-gate 				xflg = 1;
1647c478bd9Sstevel@tonic-gate 				optcnt++;
1657c478bd9Sstevel@tonic-gate 				break;
1667c478bd9Sstevel@tonic-gate 			case '?':
1677c478bd9Sstevel@tonic-gate 			default:
1687c478bd9Sstevel@tonic-gate 				usage();
1697c478bd9Sstevel@tonic-gate 			}
1707c478bd9Sstevel@tonic-gate 		}
171*074e084fSml93401 
172*074e084fSml93401 		/*
173*074e084fSml93401 		 * Permanently give up euid 0, egid 0 and privileges we
174*074e084fSml93401 		 * don't need for the specified options.
175*074e084fSml93401 		 */
176*074e084fSml93401 		if (!(file || sflg)) {
177*074e084fSml93401 			if (setreuid(getuid(), getuid()) == -1 ||
178*074e084fSml93401 			    setregid(getgid(), getgid()) == -1)
179*074e084fSml93401 				die(gettext("setreuid()/setregid() failed"));
180*074e084fSml93401 			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
181*074e084fSml93401 			    PRIV_FILE_DAC_WRITE, NULL);
182*074e084fSml93401 		}
183*074e084fSml93401 		if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
184*074e084fSml93401 		    xflg))
185*074e084fSml93401 			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
186*074e084fSml93401 			    PRIV_SYS_ACCT, NULL);
187*074e084fSml93401 
1887c478bd9Sstevel@tonic-gate 		if (optind < argc) {
1897c478bd9Sstevel@tonic-gate 			if (typestr != NULL) {
1907c478bd9Sstevel@tonic-gate 				warn(gettext("illegal argument -- %s\n"),
1917c478bd9Sstevel@tonic-gate 				    argv[optind]);
1927c478bd9Sstevel@tonic-gate 				usage();
1937c478bd9Sstevel@tonic-gate 			} else {
1947c478bd9Sstevel@tonic-gate 				typestr = argv[optind];
1957c478bd9Sstevel@tonic-gate 			}
1967c478bd9Sstevel@tonic-gate 		}
1977c478bd9Sstevel@tonic-gate 	}
1987c478bd9Sstevel@tonic-gate 	if (typestr != NULL) {
1997c478bd9Sstevel@tonic-gate 		if (strcmp(typestr, "process") == 0 ||
2007c478bd9Sstevel@tonic-gate 		    strcmp(typestr, "proc") == 0)
2017c478bd9Sstevel@tonic-gate 			type |= AC_PROC;
2027c478bd9Sstevel@tonic-gate 		else if (strcmp(typestr, "task") == 0)
2037c478bd9Sstevel@tonic-gate 			type |= AC_TASK;
2047c478bd9Sstevel@tonic-gate 		else if (strcmp(typestr, "flow") == 0)
2057c478bd9Sstevel@tonic-gate 			type |= AC_FLOW;
2067c478bd9Sstevel@tonic-gate 		else {
2077c478bd9Sstevel@tonic-gate 			warn(gettext("unknown accounting type -- %s\n"),
2087c478bd9Sstevel@tonic-gate 			    typestr);
2097c478bd9Sstevel@tonic-gate 			usage();
2107c478bd9Sstevel@tonic-gate 		}
2117c478bd9Sstevel@tonic-gate 	} else
2127c478bd9Sstevel@tonic-gate 		type = AC_PROC | AC_TASK | AC_FLOW;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	/*
2157c478bd9Sstevel@tonic-gate 	 * check for invalid options
2167c478bd9Sstevel@tonic-gate 	 */
2177c478bd9Sstevel@tonic-gate 	if (optcnt > 1)
2187c478bd9Sstevel@tonic-gate 		usage();
2197c478bd9Sstevel@tonic-gate 
220*074e084fSml93401 	if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
2217c478bd9Sstevel@tonic-gate 		usage();
2227c478bd9Sstevel@tonic-gate 
2237c478bd9Sstevel@tonic-gate 	if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
2247c478bd9Sstevel@tonic-gate 	    !typestr) {
2257c478bd9Sstevel@tonic-gate 		warn(gettext("accounting type must be specified\n"));
2267c478bd9Sstevel@tonic-gate 		usage();
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	if (rflg) {
2307c478bd9Sstevel@tonic-gate 		printgroups(type);
2317c478bd9Sstevel@tonic-gate 		return (E_SUCCESS);
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	/*
235*074e084fSml93401 	 * If no arguments have been passed then just print out the current
236*074e084fSml93401 	 * state and exit.
2377c478bd9Sstevel@tonic-gate 	 */
2387c478bd9Sstevel@tonic-gate 	if (!enabled && !disabled && !file &&
239*074e084fSml93401 	    !Eflg && !rflg && !Dflg && !sflg && !xflg) {
240*074e084fSml93401 		aconf_print(stdout, type);
2417c478bd9Sstevel@tonic-gate 		return (E_SUCCESS);
2427c478bd9Sstevel@tonic-gate 	}
2437c478bd9Sstevel@tonic-gate 
244*074e084fSml93401 	/*
245*074e084fSml93401 	 * smf(5) start method.  The FMRI to operate on is retrieved from the
246*074e084fSml93401 	 * SMF_FMRI environment variable that the restarter provides.
247*074e084fSml93401 	 */
248*074e084fSml93401 	if (sflg) {
249*074e084fSml93401 		if ((fmri = getenv("SMF_FMRI")) != NULL)
250*074e084fSml93401 			return (aconf_setup(fmri));
251*074e084fSml93401 
252*074e084fSml93401 		warn(gettext("-s option should only be invoked by smf(5)\n"));
2537c478bd9Sstevel@tonic-gate 		return (E_ERROR);
2547c478bd9Sstevel@tonic-gate 	}
2557c478bd9Sstevel@tonic-gate 
256*074e084fSml93401 	assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW);
257*074e084fSml93401 
258*074e084fSml93401 	if (type == AC_FLOW && getzoneid() != GLOBAL_ZONEID)
259*074e084fSml93401 		die(gettext("%s accounting cannot be configured in "
260*074e084fSml93401 		    "non-global zones\n"), ac_type_name(type));
261*074e084fSml93401 
262*074e084fSml93401 	fmri = aconf_type2fmri(type);
263*074e084fSml93401 	if (aconf_scf_init(fmri) == -1)
264*074e084fSml93401 		die(gettext("cannot connect to repository for %s\n"), fmri);
265*074e084fSml93401 
266*074e084fSml93401 	/*
267*074e084fSml93401 	 * Since the sys_acct the privilege allows use of acctctl() regardless
268*074e084fSml93401 	 * of the accounting type, we check the smf(5) authorizations granted
269*074e084fSml93401 	 * to the user to determine whether the user is allowed to change the
270*074e084fSml93401 	 * configuration for this particular accounting type.
271*074e084fSml93401 	 */
272*074e084fSml93401 	if (!aconf_have_smf_auths())
273*074e084fSml93401 		die(gettext("insufficient authorization to change %s extended "
274*074e084fSml93401 		    "accounting configuration\n"), ac_type_name(type));
275*074e084fSml93401 
2767c478bd9Sstevel@tonic-gate 	if (xflg) {
2777c478bd9Sstevel@tonic-gate 		/*
2787c478bd9Sstevel@tonic-gate 		 * Turn off the specified accounting and close its file
2797c478bd9Sstevel@tonic-gate 		 */
2807c478bd9Sstevel@tonic-gate 		state = AC_OFF;
281*074e084fSml93401 
282*074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
2837c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
284*074e084fSml93401 			die(gettext("cannot disable %s accounting"),
285*074e084fSml93401 			    ac_type_name(type));
2867c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
287*074e084fSml93401 			die(gettext("cannot close %s accounting file\n"),
288*074e084fSml93401 			    ac_type_name(type));
289*074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
290*074e084fSml93401 
291*074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
292*074e084fSml93401 			die(gettext("cannot update %s property\n"),
293*074e084fSml93401 			    AC_PROP_STATE);
294*074e084fSml93401 		if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
295*074e084fSml93401 			die(gettext("cannot update %s property\n"),
296*074e084fSml93401 			    AC_PROP_FILE);
2977c478bd9Sstevel@tonic-gate 		modified++;
2987c478bd9Sstevel@tonic-gate 	}
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate 	if (enabled || disabled) {
3017c478bd9Sstevel@tonic-gate 		char *tracked, *untracked;
3027c478bd9Sstevel@tonic-gate 		ac_res_t *buf;
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 		/*
3057c478bd9Sstevel@tonic-gate 		 * Enable/disable resources
3067c478bd9Sstevel@tonic-gate 		 */
3077c478bd9Sstevel@tonic-gate 		if ((buf = malloc(AC_BUFSIZE)) == NULL)
3087c478bd9Sstevel@tonic-gate 			die(gettext("not enough memory\n"));
3097c478bd9Sstevel@tonic-gate 		(void) memset(buf, 0, AC_BUFSIZE);
3107c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
3117c478bd9Sstevel@tonic-gate 			free(buf);
3127c478bd9Sstevel@tonic-gate 			die(gettext("cannot obtain list of resources\n"));
3137c478bd9Sstevel@tonic-gate 		}
3147c478bd9Sstevel@tonic-gate 		if (disabled)
3157c478bd9Sstevel@tonic-gate 			str2buf(buf, disabled, AC_OFF, type);
3167c478bd9Sstevel@tonic-gate 		if (enabled)
3177c478bd9Sstevel@tonic-gate 			str2buf(buf, enabled, AC_ON, type);
318*074e084fSml93401 
319*074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3207c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
3217c478bd9Sstevel@tonic-gate 			free(buf);
322*074e084fSml93401 			die(gettext("cannot enable/disable %s accounting "
323*074e084fSml93401 			    "resources\n"), ac_type_name(type));
3247c478bd9Sstevel@tonic-gate 		}
325*074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
326*074e084fSml93401 
3277c478bd9Sstevel@tonic-gate 		tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
3287c478bd9Sstevel@tonic-gate 		untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
329*074e084fSml93401 		if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
330*074e084fSml93401 			die(gettext("cannot update %s property\n"),
331*074e084fSml93401 			    AC_PROP_TRACKED);
332*074e084fSml93401 		if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
333*074e084fSml93401 			die(gettext("cannot update %s property\n"),
334*074e084fSml93401 			    AC_PROP_UNTRACKED);
3357c478bd9Sstevel@tonic-gate 		free(tracked);
3367c478bd9Sstevel@tonic-gate 		free(untracked);
3377c478bd9Sstevel@tonic-gate 		free(buf);
3387c478bd9Sstevel@tonic-gate 		modified++;
3397c478bd9Sstevel@tonic-gate 	}
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 	if (file) {
3427c478bd9Sstevel@tonic-gate 		/*
3437c478bd9Sstevel@tonic-gate 		 * Open new accounting file
3447c478bd9Sstevel@tonic-gate 		 */
345*074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
346*074e084fSml93401 		if (open_exacct_file(file, type) == -1)
347*074e084fSml93401 			exit(E_ERROR);
348*074e084fSml93401 		if (aconf_set_string(AC_PROP_FILE, file) == -1)
349*074e084fSml93401 			die(gettext("cannot update %s property\n"),
350*074e084fSml93401 			    AC_PROP_FILE);
3517c478bd9Sstevel@tonic-gate 		state = AC_ON;
352*074e084fSml93401 
3537c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
354*074e084fSml93401 			die(gettext("cannot enable %s accounting"),
355*074e084fSml93401 			    ac_type_name(type));
356*074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
357*074e084fSml93401 
358*074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
359*074e084fSml93401 			die(gettext("cannot update %s property\n"),
360*074e084fSml93401 			    AC_PROP_STATE);
3617c478bd9Sstevel@tonic-gate 		modified++;
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	if (Dflg) {
3657c478bd9Sstevel@tonic-gate 		/*
3667c478bd9Sstevel@tonic-gate 		 * Disable accounting
3677c478bd9Sstevel@tonic-gate 		 */
3687c478bd9Sstevel@tonic-gate 		state = AC_OFF;
369*074e084fSml93401 
370*074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3717c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
372*074e084fSml93401 			die(gettext("cannot disable %s accounting"),
373*074e084fSml93401 			    ac_type_name(type));
374*074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
375*074e084fSml93401 
376*074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
377*074e084fSml93401 			die(gettext("cannot update %s property\n"),
378*074e084fSml93401 			    AC_PROP_STATE);
3797c478bd9Sstevel@tonic-gate 		modified++;
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	if (Eflg) {
3837c478bd9Sstevel@tonic-gate 		/*
3847c478bd9Sstevel@tonic-gate 		 * Enable accounting
3857c478bd9Sstevel@tonic-gate 		 */
3867c478bd9Sstevel@tonic-gate 		state = AC_ON;
387*074e084fSml93401 
388*074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3897c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
390*074e084fSml93401 			die(gettext("cannot enable %s accounting"),
391*074e084fSml93401 			    ac_type_name(type));
392*074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
393*074e084fSml93401 
394*074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
395*074e084fSml93401 			die(gettext("cannot update %s property\n"),
396*074e084fSml93401 			    AC_PROP_STATE);
3977c478bd9Sstevel@tonic-gate 		modified++;
3987c478bd9Sstevel@tonic-gate 	}
399*074e084fSml93401 	(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	if (modified) {
402*074e084fSml93401 		char *smf_state;
4037c478bd9Sstevel@tonic-gate 
404*074e084fSml93401 		if (aconf_save() == -1)
405*074e084fSml93401 			die(gettext("cannot save %s accounting "
406*074e084fSml93401 			    "configuration\n"), ac_type_name(type));
407*074e084fSml93401 
408*074e084fSml93401 		/*
409*074e084fSml93401 		 * Enable or disable the instance depending on the effective
410*074e084fSml93401 		 * configuration.  If the effective configuration results in
411*074e084fSml93401 		 * extended accounting being 'on', the instance is enabled so
412*074e084fSml93401 		 * the configuration is applied at the next boot.
413*074e084fSml93401 		 */
414*074e084fSml93401 		smf_state = smf_get_state(fmri);
415*074e084fSml93401 		aconf_init(&ac, type);
416*074e084fSml93401 
417*074e084fSml93401 		if (ac.state == AC_ON ||
418*074e084fSml93401 		    strcmp(ac.file, AC_STR_NONE) != 0 ||
419*074e084fSml93401 		    strcmp(ac.tracked, AC_STR_NONE) != 0) {
420*074e084fSml93401 			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
421*074e084fSml93401 				if (smf_enable_instance(fmri, 0) == -1)
422*074e084fSml93401 					die(gettext("cannot enable %s\n"),
423*074e084fSml93401 					    fmri);
424*074e084fSml93401 		} else {
425*074e084fSml93401 			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
426*074e084fSml93401 				if (smf_disable_instance(fmri, 0) == -1)
427*074e084fSml93401 					die(gettext("cannot disable %s\n"),
428*074e084fSml93401 					    fmri);
429*074e084fSml93401 		}
430*074e084fSml93401 		free(smf_state);
431*074e084fSml93401 	}
432*074e084fSml93401 	aconf_scf_fini();
4337c478bd9Sstevel@tonic-gate 	return (E_SUCCESS);
4347c478bd9Sstevel@tonic-gate }
435