xref: /titanic_51/usr/src/cmd/acctadm/main.c (revision 4ac67f0276a8313b5cefec38af347b94b7bfb526)
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
5074e084fSml93401  * Common Development and Distribution License (the "License").
6074e084fSml93401  * 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 /*
22074e084fSml93401  * 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 #include <sys/acctctl.h>
27074e084fSml93401 #include <assert.h>
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <stdlib.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <string.h>
327c478bd9Sstevel@tonic-gate #include <errno.h>
337c478bd9Sstevel@tonic-gate #include <libintl.h>
34da14cebeSEric Cheng #include <libdllink.h>
357c478bd9Sstevel@tonic-gate #include <locale.h>
36074e084fSml93401 #include <priv.h>
37074e084fSml93401 #include <libscf.h>
38074e084fSml93401 #include <zone.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include "utils.h"
417c478bd9Sstevel@tonic-gate #include "aconf.h"
427c478bd9Sstevel@tonic-gate #include "res.h"
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate static const char USAGE[] = "\
457c478bd9Sstevel@tonic-gate Usage:\n\
46da14cebeSEric Cheng     acctadm [ {process | task | flow | net} ]\n\
47074e084fSml93401     acctadm -s\n\
48da14cebeSEric Cheng     acctadm -r [ {process | task | flow | net} ]\n\
49da14cebeSEric Cheng     acctadm -x|-E|-D {process | task | flow | net}\n\
50da14cebeSEric Cheng     acctadm -f filename {process | task | flow | net}\n\
51da14cebeSEric Cheng     acctadm -e resources -d resources {process | task | flow | net}\n";
527c478bd9Sstevel@tonic-gate 
53074e084fSml93401 static const char OPTS[] = "rsxf:e:d:ED";
547c478bd9Sstevel@tonic-gate 
55*4ac67f02SAnurag S. Maskey dladm_handle_t dld_handle = NULL;
56*4ac67f02SAnurag S. Maskey 
577c478bd9Sstevel@tonic-gate static void
587c478bd9Sstevel@tonic-gate usage()
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(USAGE));
617c478bd9Sstevel@tonic-gate 	exit(E_USAGE);
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate 
64074e084fSml93401 static void
65074e084fSml93401 setup_privs()
66074e084fSml93401 {
67074e084fSml93401 	priv_set_t *privset;
68074e084fSml93401 
69074e084fSml93401 	if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
70074e084fSml93401 		die(gettext("seteuid()/setegid() failed"));
71074e084fSml93401 
72074e084fSml93401 	/*
73074e084fSml93401 	 * Add our privileges and remove unneeded 'basic' privileges from the
74074e084fSml93401 	 * permitted set.
75074e084fSml93401 	 */
76074e084fSml93401 	if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
77074e084fSml93401 		die(gettext("cannot setup privileges"));
78074e084fSml93401 
79074e084fSml93401 	(void) priv_addset(privset, PRIV_SYS_ACCT);
80074e084fSml93401 	(void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
81da14cebeSEric Cheng 	(void) priv_addset(privset, PRIV_SYS_DL_CONFIG);
82074e084fSml93401 	(void) priv_delset(privset, PRIV_FILE_LINK_ANY);
83074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_EXEC);
84074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_FORK);
85074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_INFO);
86074e084fSml93401 	(void) priv_delset(privset, PRIV_PROC_SESSION);
87074e084fSml93401 	priv_inverse(privset);
88074e084fSml93401 	if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
89074e084fSml93401 		die(gettext("cannot setup privileges"));
90074e084fSml93401 	priv_freeset(privset);
91074e084fSml93401 
92074e084fSml93401 	/*
93074e084fSml93401 	 * Clear the Inheritable and Limit sets.
94074e084fSml93401 	 */
95074e084fSml93401 	if ((privset = priv_allocset()) == NULL)
96074e084fSml93401 		die(gettext("cannot setup privileges"));
97074e084fSml93401 	priv_emptyset(privset);
98074e084fSml93401 	if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
99074e084fSml93401 	    setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
100074e084fSml93401 		die(gettext("cannot setup privileges"));
101074e084fSml93401 
102074e084fSml93401 	/*
103da14cebeSEric Cheng 	 * Turn off the sys_acct, file_dac_write and dl_config privileges
104da14cebeSEric Cheng 	 * until needed.
105074e084fSml93401 	 */
106074e084fSml93401 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
107da14cebeSEric Cheng 	    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
108074e084fSml93401 }
109074e084fSml93401 
1107c478bd9Sstevel@tonic-gate int
1117c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1127c478bd9Sstevel@tonic-gate {
1137c478bd9Sstevel@tonic-gate 	int c;			/* options character */
1147c478bd9Sstevel@tonic-gate 	int type = 0;		/* type of accounting */
115074e084fSml93401 	int modified = 0;	/* have we modified any properties? */
1167c478bd9Sstevel@tonic-gate 	acctconf_t ac;		/* current configuration */
1177c478bd9Sstevel@tonic-gate 	char *typestr = NULL;	/* type of accounting argument string */
1187c478bd9Sstevel@tonic-gate 	char *enabled = NULL;	/* enabled resources string */
1197c478bd9Sstevel@tonic-gate 	char *disabled = NULL;	/* disabled resources string */
1207c478bd9Sstevel@tonic-gate 	char *file = NULL;
1217c478bd9Sstevel@tonic-gate 	int Eflg = 0;
1227c478bd9Sstevel@tonic-gate 	int Dflg = 0;
1237c478bd9Sstevel@tonic-gate 	int rflg = 0;
124074e084fSml93401 	int sflg = 0;
1257c478bd9Sstevel@tonic-gate 	int xflg = 0;
1267c478bd9Sstevel@tonic-gate 	int optcnt = 0;
1277c478bd9Sstevel@tonic-gate 	int state;
128074e084fSml93401 	const char *fmri;	/* FMRI for this instance */
129074e084fSml93401 
130074e084fSml93401 	setup_privs();
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
1337c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
1347c478bd9Sstevel@tonic-gate 	(void) setprogname(argv[0]);
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	for (; optind < argc; optind++) {
1377c478bd9Sstevel@tonic-gate 		while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
1387c478bd9Sstevel@tonic-gate 			switch (c) {
1397c478bd9Sstevel@tonic-gate 			case 'd':
1407c478bd9Sstevel@tonic-gate 				disabled = optarg;
1417c478bd9Sstevel@tonic-gate 				break;
1427c478bd9Sstevel@tonic-gate 			case 'e':
1437c478bd9Sstevel@tonic-gate 				enabled = optarg;
1447c478bd9Sstevel@tonic-gate 				break;
1457c478bd9Sstevel@tonic-gate 			case 'D':
1467c478bd9Sstevel@tonic-gate 				Dflg = 1;
1477c478bd9Sstevel@tonic-gate 				optcnt++;
1487c478bd9Sstevel@tonic-gate 				break;
1497c478bd9Sstevel@tonic-gate 			case 'E':
1507c478bd9Sstevel@tonic-gate 				Eflg = 1;
1517c478bd9Sstevel@tonic-gate 				optcnt++;
1527c478bd9Sstevel@tonic-gate 				break;
1537c478bd9Sstevel@tonic-gate 			case 'f':
1547c478bd9Sstevel@tonic-gate 				file = optarg;
1557c478bd9Sstevel@tonic-gate 				optcnt++;
1567c478bd9Sstevel@tonic-gate 				break;
1577c478bd9Sstevel@tonic-gate 			case 'r':
1587c478bd9Sstevel@tonic-gate 				rflg = 1;
1597c478bd9Sstevel@tonic-gate 				optcnt++;
1607c478bd9Sstevel@tonic-gate 				break;
161074e084fSml93401 			case 's':
162074e084fSml93401 				sflg = 1;
1637c478bd9Sstevel@tonic-gate 				optcnt++;
1647c478bd9Sstevel@tonic-gate 				break;
1657c478bd9Sstevel@tonic-gate 			case 'x':
1667c478bd9Sstevel@tonic-gate 				xflg = 1;
1677c478bd9Sstevel@tonic-gate 				optcnt++;
1687c478bd9Sstevel@tonic-gate 				break;
1697c478bd9Sstevel@tonic-gate 			case '?':
1707c478bd9Sstevel@tonic-gate 			default:
1717c478bd9Sstevel@tonic-gate 				usage();
1727c478bd9Sstevel@tonic-gate 			}
1737c478bd9Sstevel@tonic-gate 		}
174074e084fSml93401 
175074e084fSml93401 		/*
176074e084fSml93401 		 * Permanently give up euid 0, egid 0 and privileges we
177074e084fSml93401 		 * don't need for the specified options.
178074e084fSml93401 		 */
179074e084fSml93401 		if (!(file || sflg)) {
180074e084fSml93401 			if (setreuid(getuid(), getuid()) == -1 ||
181074e084fSml93401 			    setregid(getgid(), getgid()) == -1)
182074e084fSml93401 				die(gettext("setreuid()/setregid() failed"));
183074e084fSml93401 			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
184074e084fSml93401 			    PRIV_FILE_DAC_WRITE, NULL);
185074e084fSml93401 		}
186074e084fSml93401 		if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
187074e084fSml93401 		    xflg))
188074e084fSml93401 			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
189da14cebeSEric Cheng 			    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
190074e084fSml93401 
1917c478bd9Sstevel@tonic-gate 		if (optind < argc) {
1927c478bd9Sstevel@tonic-gate 			if (typestr != NULL) {
1937c478bd9Sstevel@tonic-gate 				warn(gettext("illegal argument -- %s\n"),
1947c478bd9Sstevel@tonic-gate 				    argv[optind]);
1957c478bd9Sstevel@tonic-gate 				usage();
1967c478bd9Sstevel@tonic-gate 			} else {
1977c478bd9Sstevel@tonic-gate 				typestr = argv[optind];
1987c478bd9Sstevel@tonic-gate 			}
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 	}
2017c478bd9Sstevel@tonic-gate 	if (typestr != NULL) {
2027c478bd9Sstevel@tonic-gate 		if (strcmp(typestr, "process") == 0 ||
2037c478bd9Sstevel@tonic-gate 		    strcmp(typestr, "proc") == 0)
2047c478bd9Sstevel@tonic-gate 			type |= AC_PROC;
2057c478bd9Sstevel@tonic-gate 		else if (strcmp(typestr, "task") == 0)
2067c478bd9Sstevel@tonic-gate 			type |= AC_TASK;
2077c478bd9Sstevel@tonic-gate 		else if (strcmp(typestr, "flow") == 0)
2087c478bd9Sstevel@tonic-gate 			type |= AC_FLOW;
209da14cebeSEric Cheng 		else if (strcmp(typestr, "net") == 0)
210da14cebeSEric Cheng 			type |= AC_NET;
2117c478bd9Sstevel@tonic-gate 		else {
2127c478bd9Sstevel@tonic-gate 			warn(gettext("unknown accounting type -- %s\n"),
2137c478bd9Sstevel@tonic-gate 			    typestr);
2147c478bd9Sstevel@tonic-gate 			usage();
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 	} else
217da14cebeSEric Cheng 		type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate 	/*
220da14cebeSEric Cheng 	 * Drop the DL config privilege if we are not working with
221da14cebeSEric Cheng 	 * net.
222da14cebeSEric Cheng 	 */
223da14cebeSEric Cheng 	if ((type & AC_NET) == 0) {
224da14cebeSEric Cheng 		(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
225da14cebeSEric Cheng 		    PRIV_SYS_DL_CONFIG, NULL);
226da14cebeSEric Cheng 	}
227da14cebeSEric Cheng 	/*
2287c478bd9Sstevel@tonic-gate 	 * check for invalid options
2297c478bd9Sstevel@tonic-gate 	 */
2307c478bd9Sstevel@tonic-gate 	if (optcnt > 1)
2317c478bd9Sstevel@tonic-gate 		usage();
2327c478bd9Sstevel@tonic-gate 
233da14cebeSEric Cheng 	/*
234da14cebeSEric Cheng 	 * XXX For AC_NET, enabled/disabled should only be "basic" or
235da14cebeSEric Cheng 	 * "extended" - need to check it here.
236da14cebeSEric Cheng 	 */
237074e084fSml93401 	if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
2387c478bd9Sstevel@tonic-gate 		usage();
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
2417c478bd9Sstevel@tonic-gate 	    !typestr) {
2427c478bd9Sstevel@tonic-gate 		warn(gettext("accounting type must be specified\n"));
2437c478bd9Sstevel@tonic-gate 		usage();
2447c478bd9Sstevel@tonic-gate 	}
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate 	if (rflg) {
2477c478bd9Sstevel@tonic-gate 		printgroups(type);
2487c478bd9Sstevel@tonic-gate 		return (E_SUCCESS);
2497c478bd9Sstevel@tonic-gate 	}
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	/*
252074e084fSml93401 	 * If no arguments have been passed then just print out the current
253074e084fSml93401 	 * state and exit.
2547c478bd9Sstevel@tonic-gate 	 */
2557c478bd9Sstevel@tonic-gate 	if (!enabled && !disabled && !file &&
256074e084fSml93401 	    !Eflg && !rflg && !Dflg && !sflg && !xflg) {
257074e084fSml93401 		aconf_print(stdout, type);
2587c478bd9Sstevel@tonic-gate 		return (E_SUCCESS);
2597c478bd9Sstevel@tonic-gate 	}
2607c478bd9Sstevel@tonic-gate 
261*4ac67f02SAnurag S. Maskey 	/* Open the libdladm handle */
262*4ac67f02SAnurag S. Maskey 	if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
263*4ac67f02SAnurag S. Maskey 		die(gettext("failed to open dladm handle\n"));
264*4ac67f02SAnurag S. Maskey 
265074e084fSml93401 	/*
266074e084fSml93401 	 * smf(5) start method.  The FMRI to operate on is retrieved from the
267074e084fSml93401 	 * SMF_FMRI environment variable that the restarter provides.
268074e084fSml93401 	 */
269074e084fSml93401 	if (sflg) {
270*4ac67f02SAnurag S. Maskey 		if ((fmri = getenv("SMF_FMRI")) != NULL) {
271*4ac67f02SAnurag S. Maskey 			int ret = aconf_setup(fmri);
272*4ac67f02SAnurag S. Maskey 			dladm_close(dld_handle);
273*4ac67f02SAnurag S. Maskey 			return (ret);
274*4ac67f02SAnurag S. Maskey 		}
275074e084fSml93401 
276*4ac67f02SAnurag S. Maskey 		die(gettext("-s option should only be invoked by smf(5)\n"));
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 
279da14cebeSEric Cheng 	assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
280da14cebeSEric Cheng 	    type == AC_NET);
281074e084fSml93401 
282da14cebeSEric Cheng 	if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
283074e084fSml93401 		die(gettext("%s accounting cannot be configured in "
284074e084fSml93401 		    "non-global zones\n"), ac_type_name(type));
285074e084fSml93401 
286074e084fSml93401 	fmri = aconf_type2fmri(type);
287074e084fSml93401 	if (aconf_scf_init(fmri) == -1)
288074e084fSml93401 		die(gettext("cannot connect to repository for %s\n"), fmri);
289074e084fSml93401 
290074e084fSml93401 	/*
291074e084fSml93401 	 * Since the sys_acct the privilege allows use of acctctl() regardless
292074e084fSml93401 	 * of the accounting type, we check the smf(5) authorizations granted
293074e084fSml93401 	 * to the user to determine whether the user is allowed to change the
294074e084fSml93401 	 * configuration for this particular accounting type.
295074e084fSml93401 	 */
296074e084fSml93401 	if (!aconf_have_smf_auths())
297074e084fSml93401 		die(gettext("insufficient authorization to change %s extended "
298074e084fSml93401 		    "accounting configuration\n"), ac_type_name(type));
299074e084fSml93401 
3007c478bd9Sstevel@tonic-gate 	if (xflg) {
3017c478bd9Sstevel@tonic-gate 		/*
3027c478bd9Sstevel@tonic-gate 		 * Turn off the specified accounting and close its file
3037c478bd9Sstevel@tonic-gate 		 */
304da14cebeSEric Cheng 
305da14cebeSEric Cheng 		/*
306da14cebeSEric Cheng 		 * Stop net logging before turning it off so that the last
307da14cebeSEric Cheng 		 * set of logs can be written.
308da14cebeSEric Cheng 		 */
309da14cebeSEric Cheng 		if (type & AC_NET) {
310da14cebeSEric Cheng 			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
311da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
312*4ac67f02SAnurag S. Maskey 			(void) dladm_stop_usagelog(dld_handle,
313*4ac67f02SAnurag S. Maskey 			    DLADM_LOGTYPE_FLOW);
314da14cebeSEric Cheng 			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
315da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
316da14cebeSEric Cheng 		}
3177c478bd9Sstevel@tonic-gate 		state = AC_OFF;
318074e084fSml93401 
319074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3207c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
321074e084fSml93401 			die(gettext("cannot disable %s accounting"),
322074e084fSml93401 			    ac_type_name(type));
3237c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
324074e084fSml93401 			die(gettext("cannot close %s accounting file\n"),
325074e084fSml93401 			    ac_type_name(type));
326074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
327074e084fSml93401 
328074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
329074e084fSml93401 			die(gettext("cannot update %s property\n"),
330074e084fSml93401 			    AC_PROP_STATE);
331074e084fSml93401 		if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
332074e084fSml93401 			die(gettext("cannot update %s property\n"),
333074e084fSml93401 			    AC_PROP_FILE);
3347c478bd9Sstevel@tonic-gate 		modified++;
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	if (enabled || disabled) {
3387c478bd9Sstevel@tonic-gate 		char *tracked, *untracked;
3397c478bd9Sstevel@tonic-gate 		ac_res_t *buf;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 		/*
3427c478bd9Sstevel@tonic-gate 		 * Enable/disable resources
3437c478bd9Sstevel@tonic-gate 		 */
3447c478bd9Sstevel@tonic-gate 		if ((buf = malloc(AC_BUFSIZE)) == NULL)
3457c478bd9Sstevel@tonic-gate 			die(gettext("not enough memory\n"));
3467c478bd9Sstevel@tonic-gate 		(void) memset(buf, 0, AC_BUFSIZE);
3477c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
3487c478bd9Sstevel@tonic-gate 			free(buf);
3497c478bd9Sstevel@tonic-gate 			die(gettext("cannot obtain list of resources\n"));
3507c478bd9Sstevel@tonic-gate 		}
351da14cebeSEric Cheng 		if (disabled) {
352da14cebeSEric Cheng 			/*
353da14cebeSEric Cheng 			 * Stop net logging before turning it off so that the
354da14cebeSEric Cheng 			 * last set of logs can be written.
355da14cebeSEric Cheng 			 */
356da14cebeSEric Cheng 			if (type & AC_NET) {
357da14cebeSEric Cheng 				(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
358da14cebeSEric Cheng 				    PRIV_SYS_DL_CONFIG, NULL);
359*4ac67f02SAnurag S. Maskey 				(void) dladm_stop_usagelog(dld_handle,
360*4ac67f02SAnurag S. Maskey 				    strncmp(disabled, "basic", strlen("basic"))
361*4ac67f02SAnurag S. Maskey 				    == 0 ? DLADM_LOGTYPE_LINK :
362*4ac67f02SAnurag S. Maskey 				    DLADM_LOGTYPE_FLOW);
363da14cebeSEric Cheng 				(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
364da14cebeSEric Cheng 				    PRIV_SYS_DL_CONFIG, NULL);
365da14cebeSEric Cheng 			}
3667c478bd9Sstevel@tonic-gate 			str2buf(buf, disabled, AC_OFF, type);
367da14cebeSEric Cheng 		}
3687c478bd9Sstevel@tonic-gate 		if (enabled)
3697c478bd9Sstevel@tonic-gate 			str2buf(buf, enabled, AC_ON, type);
370074e084fSml93401 
371074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3727c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
3737c478bd9Sstevel@tonic-gate 			free(buf);
374074e084fSml93401 			die(gettext("cannot enable/disable %s accounting "
375074e084fSml93401 			    "resources\n"), ac_type_name(type));
3767c478bd9Sstevel@tonic-gate 		}
377074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
378074e084fSml93401 
3797c478bd9Sstevel@tonic-gate 		tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
3807c478bd9Sstevel@tonic-gate 		untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
381074e084fSml93401 		if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
382074e084fSml93401 			die(gettext("cannot update %s property\n"),
383074e084fSml93401 			    AC_PROP_TRACKED);
384074e084fSml93401 		if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
385074e084fSml93401 			die(gettext("cannot update %s property\n"),
386074e084fSml93401 			    AC_PROP_UNTRACKED);
387da14cebeSEric Cheng 		/*
388da14cebeSEric Cheng 		 * We will enable net logging after turning it on so that
389da14cebeSEric Cheng 		 * it can immediately start writing log.
390da14cebeSEric Cheng 		 */
391da14cebeSEric Cheng 		if (type & AC_NET && enabled != NULL) {
392da14cebeSEric Cheng 			/*
393da14cebeSEric Cheng 			 * Default logging interval for AC_NET is 20.
394da14cebeSEric Cheng 			 * XXX need to find the right place to
395da14cebeSEric Cheng 			 * configure it.
396da14cebeSEric Cheng 			 */
397da14cebeSEric Cheng 			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
398da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
399*4ac67f02SAnurag S. Maskey 			(void) dladm_start_usagelog(dld_handle,
400*4ac67f02SAnurag S. Maskey 			    strncmp(enabled, "basic", strlen("basic")) == 0 ?
401*4ac67f02SAnurag S. Maskey 			    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW, 20);
402da14cebeSEric Cheng 			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
403da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
404da14cebeSEric Cheng 		}
4057c478bd9Sstevel@tonic-gate 		free(tracked);
4067c478bd9Sstevel@tonic-gate 		free(untracked);
4077c478bd9Sstevel@tonic-gate 		free(buf);
4087c478bd9Sstevel@tonic-gate 		modified++;
4097c478bd9Sstevel@tonic-gate 	}
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 	if (file) {
4127c478bd9Sstevel@tonic-gate 		/*
4137c478bd9Sstevel@tonic-gate 		 * Open new accounting file
4147c478bd9Sstevel@tonic-gate 		 */
415074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
416*4ac67f02SAnurag S. Maskey 		if (open_exacct_file(file, type) == -1) {
417*4ac67f02SAnurag S. Maskey 			dladm_close(dld_handle);
418074e084fSml93401 			exit(E_ERROR);
419*4ac67f02SAnurag S. Maskey 		}
420074e084fSml93401 		if (aconf_set_string(AC_PROP_FILE, file) == -1)
421074e084fSml93401 			die(gettext("cannot update %s property\n"),
422074e084fSml93401 			    AC_PROP_FILE);
4237c478bd9Sstevel@tonic-gate 		state = AC_ON;
424074e084fSml93401 
4257c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
426074e084fSml93401 			die(gettext("cannot enable %s accounting"),
427074e084fSml93401 			    ac_type_name(type));
428074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
429074e084fSml93401 
430074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
431074e084fSml93401 			die(gettext("cannot update %s property\n"),
432074e084fSml93401 			    AC_PROP_STATE);
4337c478bd9Sstevel@tonic-gate 		modified++;
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 	if (Dflg) {
4377c478bd9Sstevel@tonic-gate 		/*
4387c478bd9Sstevel@tonic-gate 		 * Disable accounting
4397c478bd9Sstevel@tonic-gate 		 */
440da14cebeSEric Cheng 
441da14cebeSEric Cheng 		/*
442da14cebeSEric Cheng 		 * Stop net logging before turning it off so that the last
443da14cebeSEric Cheng 		 * set of logs can be written.
444da14cebeSEric Cheng 		 */
445da14cebeSEric Cheng 		if (type & AC_NET) {
446da14cebeSEric Cheng 			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
447da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
448*4ac67f02SAnurag S. Maskey 			(void) dladm_stop_usagelog(dld_handle,
449*4ac67f02SAnurag S. Maskey 			    DLADM_LOGTYPE_FLOW);
450da14cebeSEric Cheng 			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
451da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
452da14cebeSEric Cheng 		}
4537c478bd9Sstevel@tonic-gate 		state = AC_OFF;
454074e084fSml93401 
455074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4567c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
457074e084fSml93401 			die(gettext("cannot disable %s accounting"),
458074e084fSml93401 			    ac_type_name(type));
459074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
460074e084fSml93401 
461074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
462074e084fSml93401 			die(gettext("cannot update %s property\n"),
463074e084fSml93401 			    AC_PROP_STATE);
4647c478bd9Sstevel@tonic-gate 		modified++;
4657c478bd9Sstevel@tonic-gate 	}
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate 	if (Eflg) {
4687c478bd9Sstevel@tonic-gate 		/*
4697c478bd9Sstevel@tonic-gate 		 * Enable accounting
4707c478bd9Sstevel@tonic-gate 		 */
4717c478bd9Sstevel@tonic-gate 		state = AC_ON;
472074e084fSml93401 
473074e084fSml93401 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4747c478bd9Sstevel@tonic-gate 		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
475074e084fSml93401 			die(gettext("cannot enable %s accounting"),
476074e084fSml93401 			    ac_type_name(type));
477074e084fSml93401 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
478074e084fSml93401 
479074e084fSml93401 		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
480074e084fSml93401 			die(gettext("cannot update %s property\n"),
481074e084fSml93401 			    AC_PROP_STATE);
4827c478bd9Sstevel@tonic-gate 		modified++;
483da14cebeSEric Cheng 		if (type & AC_NET) {
484da14cebeSEric Cheng 			/*
485da14cebeSEric Cheng 			 * Default logging interval for AC_NET is 20,
486da14cebeSEric Cheng 			 * XXX need to find the right place to configure it.
487da14cebeSEric Cheng 			 */
488da14cebeSEric Cheng 			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
489da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
490*4ac67f02SAnurag S. Maskey 			(void) dladm_start_usagelog(dld_handle,
491*4ac67f02SAnurag S. Maskey 			    DLADM_LOGTYPE_FLOW, 20);
492da14cebeSEric Cheng 			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
493da14cebeSEric Cheng 			    PRIV_SYS_DL_CONFIG, NULL);
494da14cebeSEric Cheng 		}
4957c478bd9Sstevel@tonic-gate 	}
496074e084fSml93401 	(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 	if (modified) {
499074e084fSml93401 		char *smf_state;
5007c478bd9Sstevel@tonic-gate 
501074e084fSml93401 		if (aconf_save() == -1)
502074e084fSml93401 			die(gettext("cannot save %s accounting "
503074e084fSml93401 			    "configuration\n"), ac_type_name(type));
504074e084fSml93401 
505074e084fSml93401 		/*
506074e084fSml93401 		 * Enable or disable the instance depending on the effective
507074e084fSml93401 		 * configuration.  If the effective configuration results in
508074e084fSml93401 		 * extended accounting being 'on', the instance is enabled so
509074e084fSml93401 		 * the configuration is applied at the next boot.
510074e084fSml93401 		 */
511074e084fSml93401 		smf_state = smf_get_state(fmri);
512074e084fSml93401 		aconf_init(&ac, type);
513074e084fSml93401 
514074e084fSml93401 		if (ac.state == AC_ON ||
515074e084fSml93401 		    strcmp(ac.file, AC_STR_NONE) != 0 ||
516074e084fSml93401 		    strcmp(ac.tracked, AC_STR_NONE) != 0) {
517074e084fSml93401 			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
518074e084fSml93401 				if (smf_enable_instance(fmri, 0) == -1)
519074e084fSml93401 					die(gettext("cannot enable %s\n"),
520074e084fSml93401 					    fmri);
521074e084fSml93401 		} else {
522074e084fSml93401 			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
523074e084fSml93401 				if (smf_disable_instance(fmri, 0) == -1)
524074e084fSml93401 					die(gettext("cannot disable %s\n"),
525074e084fSml93401 					    fmri);
526074e084fSml93401 		}
527074e084fSml93401 		free(smf_state);
528074e084fSml93401 	}
529074e084fSml93401 	aconf_scf_fini();
530*4ac67f02SAnurag S. Maskey 	dladm_close(dld_handle);
5317c478bd9Sstevel@tonic-gate 	return (E_SUCCESS);
5327c478bd9Sstevel@tonic-gate }
533