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 */
21*23a1cceaSRoger A. Faulkner
227c478bd9Sstevel@tonic-gate /*
23*23a1cceaSRoger A. Faulkner * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
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
44ae6aa22aSVenugopal Iyer #define ACCTADM_NET_LOG_INTERVAL 20
45ae6aa22aSVenugopal Iyer
467c478bd9Sstevel@tonic-gate static const char USAGE[] = "\
477c478bd9Sstevel@tonic-gate Usage:\n\
48da14cebeSEric Cheng acctadm [ {process | task | flow | net} ]\n\
49074e084fSml93401 acctadm -s\n\
50da14cebeSEric Cheng acctadm -r [ {process | task | flow | net} ]\n\
51da14cebeSEric Cheng acctadm -x|-E|-D {process | task | flow | net}\n\
52da14cebeSEric Cheng acctadm -f filename {process | task | flow | net}\n\
53da14cebeSEric Cheng acctadm -e resources -d resources {process | task | flow | net}\n";
547c478bd9Sstevel@tonic-gate
55074e084fSml93401 static const char OPTS[] = "rsxf:e:d:ED";
567c478bd9Sstevel@tonic-gate
574ac67f02SAnurag S. Maskey dladm_handle_t dld_handle = NULL;
584ac67f02SAnurag S. Maskey
597c478bd9Sstevel@tonic-gate static void
usage()607c478bd9Sstevel@tonic-gate usage()
617c478bd9Sstevel@tonic-gate {
627c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE));
637c478bd9Sstevel@tonic-gate exit(E_USAGE);
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate
66074e084fSml93401 static void
setup_privs()67074e084fSml93401 setup_privs()
68074e084fSml93401 {
69074e084fSml93401 priv_set_t *privset;
70074e084fSml93401
71074e084fSml93401 if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
72074e084fSml93401 die(gettext("seteuid()/setegid() failed"));
73074e084fSml93401
74074e084fSml93401 /*
75074e084fSml93401 * Add our privileges and remove unneeded 'basic' privileges from the
76074e084fSml93401 * permitted set.
77074e084fSml93401 */
78074e084fSml93401 if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
79074e084fSml93401 die(gettext("cannot setup privileges"));
80074e084fSml93401
81074e084fSml93401 (void) priv_addset(privset, PRIV_SYS_ACCT);
82074e084fSml93401 (void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
83da14cebeSEric Cheng (void) priv_addset(privset, PRIV_SYS_DL_CONFIG);
84074e084fSml93401 (void) priv_delset(privset, PRIV_FILE_LINK_ANY);
85074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_EXEC);
86074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_FORK);
87074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_INFO);
88074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_SESSION);
89074e084fSml93401 priv_inverse(privset);
90074e084fSml93401 if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
91074e084fSml93401 die(gettext("cannot setup privileges"));
92074e084fSml93401 priv_freeset(privset);
93074e084fSml93401
94074e084fSml93401 /*
95074e084fSml93401 * Clear the Inheritable and Limit sets.
96074e084fSml93401 */
97074e084fSml93401 if ((privset = priv_allocset()) == NULL)
98074e084fSml93401 die(gettext("cannot setup privileges"));
99074e084fSml93401 priv_emptyset(privset);
100074e084fSml93401 if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
101074e084fSml93401 setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
102074e084fSml93401 die(gettext("cannot setup privileges"));
103074e084fSml93401
104074e084fSml93401 /*
105da14cebeSEric Cheng * Turn off the sys_acct, file_dac_write and dl_config privileges
106da14cebeSEric Cheng * until needed.
107074e084fSml93401 */
108074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
109da14cebeSEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
110074e084fSml93401 }
111074e084fSml93401
1127c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])1137c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate int c; /* options character */
1167c478bd9Sstevel@tonic-gate int type = 0; /* type of accounting */
117074e084fSml93401 int modified = 0; /* have we modified any properties? */
1187c478bd9Sstevel@tonic-gate acctconf_t ac; /* current configuration */
1197c478bd9Sstevel@tonic-gate char *typestr = NULL; /* type of accounting argument string */
1207c478bd9Sstevel@tonic-gate char *enabled = NULL; /* enabled resources string */
1217c478bd9Sstevel@tonic-gate char *disabled = NULL; /* disabled resources string */
1227c478bd9Sstevel@tonic-gate char *file = NULL;
1237c478bd9Sstevel@tonic-gate int Eflg = 0;
1247c478bd9Sstevel@tonic-gate int Dflg = 0;
1257c478bd9Sstevel@tonic-gate int rflg = 0;
126074e084fSml93401 int sflg = 0;
1277c478bd9Sstevel@tonic-gate int xflg = 0;
1287c478bd9Sstevel@tonic-gate int optcnt = 0;
1297c478bd9Sstevel@tonic-gate int state;
130074e084fSml93401 const char *fmri; /* FMRI for this instance */
131ae6aa22aSVenugopal Iyer int err = 0;
132074e084fSml93401
133074e084fSml93401 setup_privs();
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
1367c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
137*23a1cceaSRoger A. Faulkner (void) setpname(argv[0]);
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) {
1407c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
1417c478bd9Sstevel@tonic-gate switch (c) {
1427c478bd9Sstevel@tonic-gate case 'd':
1437c478bd9Sstevel@tonic-gate disabled = optarg;
1447c478bd9Sstevel@tonic-gate break;
1457c478bd9Sstevel@tonic-gate case 'e':
1467c478bd9Sstevel@tonic-gate enabled = optarg;
1477c478bd9Sstevel@tonic-gate break;
1487c478bd9Sstevel@tonic-gate case 'D':
1497c478bd9Sstevel@tonic-gate Dflg = 1;
1507c478bd9Sstevel@tonic-gate optcnt++;
1517c478bd9Sstevel@tonic-gate break;
1527c478bd9Sstevel@tonic-gate case 'E':
1537c478bd9Sstevel@tonic-gate Eflg = 1;
1547c478bd9Sstevel@tonic-gate optcnt++;
1557c478bd9Sstevel@tonic-gate break;
1567c478bd9Sstevel@tonic-gate case 'f':
1577c478bd9Sstevel@tonic-gate file = optarg;
1587c478bd9Sstevel@tonic-gate optcnt++;
1597c478bd9Sstevel@tonic-gate break;
1607c478bd9Sstevel@tonic-gate case 'r':
1617c478bd9Sstevel@tonic-gate rflg = 1;
1627c478bd9Sstevel@tonic-gate optcnt++;
1637c478bd9Sstevel@tonic-gate break;
164074e084fSml93401 case 's':
165074e084fSml93401 sflg = 1;
1667c478bd9Sstevel@tonic-gate optcnt++;
1677c478bd9Sstevel@tonic-gate break;
1687c478bd9Sstevel@tonic-gate case 'x':
1697c478bd9Sstevel@tonic-gate xflg = 1;
1707c478bd9Sstevel@tonic-gate optcnt++;
1717c478bd9Sstevel@tonic-gate break;
1727c478bd9Sstevel@tonic-gate case '?':
1737c478bd9Sstevel@tonic-gate default:
1747c478bd9Sstevel@tonic-gate usage();
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate }
177074e084fSml93401
178074e084fSml93401 /*
179074e084fSml93401 * Permanently give up euid 0, egid 0 and privileges we
180074e084fSml93401 * don't need for the specified options.
181074e084fSml93401 */
182074e084fSml93401 if (!(file || sflg)) {
183074e084fSml93401 if (setreuid(getuid(), getuid()) == -1 ||
184074e084fSml93401 setregid(getgid(), getgid()) == -1)
185074e084fSml93401 die(gettext("setreuid()/setregid() failed"));
186074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
187074e084fSml93401 PRIV_FILE_DAC_WRITE, NULL);
188074e084fSml93401 }
189074e084fSml93401 if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
190074e084fSml93401 xflg))
191074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
192da14cebeSEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
193074e084fSml93401
1947c478bd9Sstevel@tonic-gate if (optind < argc) {
1957c478bd9Sstevel@tonic-gate if (typestr != NULL) {
1967c478bd9Sstevel@tonic-gate warn(gettext("illegal argument -- %s\n"),
1977c478bd9Sstevel@tonic-gate argv[optind]);
1987c478bd9Sstevel@tonic-gate usage();
1997c478bd9Sstevel@tonic-gate } else {
2007c478bd9Sstevel@tonic-gate typestr = argv[optind];
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate if (typestr != NULL) {
2057c478bd9Sstevel@tonic-gate if (strcmp(typestr, "process") == 0 ||
2067c478bd9Sstevel@tonic-gate strcmp(typestr, "proc") == 0)
2077c478bd9Sstevel@tonic-gate type |= AC_PROC;
2087c478bd9Sstevel@tonic-gate else if (strcmp(typestr, "task") == 0)
2097c478bd9Sstevel@tonic-gate type |= AC_TASK;
2107c478bd9Sstevel@tonic-gate else if (strcmp(typestr, "flow") == 0)
2117c478bd9Sstevel@tonic-gate type |= AC_FLOW;
212da14cebeSEric Cheng else if (strcmp(typestr, "net") == 0)
213da14cebeSEric Cheng type |= AC_NET;
2147c478bd9Sstevel@tonic-gate else {
2157c478bd9Sstevel@tonic-gate warn(gettext("unknown accounting type -- %s\n"),
2167c478bd9Sstevel@tonic-gate typestr);
2177c478bd9Sstevel@tonic-gate usage();
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate } else
220da14cebeSEric Cheng type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate /*
223da14cebeSEric Cheng * Drop the DL config privilege if we are not working with
224da14cebeSEric Cheng * net.
225da14cebeSEric Cheng */
226da14cebeSEric Cheng if ((type & AC_NET) == 0) {
227da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
228da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
229da14cebeSEric Cheng }
230da14cebeSEric Cheng /*
2317c478bd9Sstevel@tonic-gate * check for invalid options
2327c478bd9Sstevel@tonic-gate */
2337c478bd9Sstevel@tonic-gate if (optcnt > 1)
2347c478bd9Sstevel@tonic-gate usage();
2357c478bd9Sstevel@tonic-gate
236da14cebeSEric Cheng /*
237da14cebeSEric Cheng * XXX For AC_NET, enabled/disabled should only be "basic" or
238da14cebeSEric Cheng * "extended" - need to check it here.
239da14cebeSEric Cheng */
240074e084fSml93401 if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
2417c478bd9Sstevel@tonic-gate usage();
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
2447c478bd9Sstevel@tonic-gate !typestr) {
2457c478bd9Sstevel@tonic-gate warn(gettext("accounting type must be specified\n"));
2467c478bd9Sstevel@tonic-gate usage();
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate
2497c478bd9Sstevel@tonic-gate if (rflg) {
2507c478bd9Sstevel@tonic-gate printgroups(type);
2517c478bd9Sstevel@tonic-gate return (E_SUCCESS);
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate /*
255074e084fSml93401 * If no arguments have been passed then just print out the current
256074e084fSml93401 * state and exit.
2577c478bd9Sstevel@tonic-gate */
2587c478bd9Sstevel@tonic-gate if (!enabled && !disabled && !file &&
259074e084fSml93401 !Eflg && !rflg && !Dflg && !sflg && !xflg) {
260074e084fSml93401 aconf_print(stdout, type);
2617c478bd9Sstevel@tonic-gate return (E_SUCCESS);
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate
2644ac67f02SAnurag S. Maskey /* Open the libdladm handle */
2654ac67f02SAnurag S. Maskey if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
2664ac67f02SAnurag S. Maskey die(gettext("failed to open dladm handle\n"));
2674ac67f02SAnurag S. Maskey
268074e084fSml93401 /*
269074e084fSml93401 * smf(5) start method. The FMRI to operate on is retrieved from the
270074e084fSml93401 * SMF_FMRI environment variable that the restarter provides.
271074e084fSml93401 */
272074e084fSml93401 if (sflg) {
2734ac67f02SAnurag S. Maskey if ((fmri = getenv("SMF_FMRI")) != NULL) {
2744ac67f02SAnurag S. Maskey int ret = aconf_setup(fmri);
2754ac67f02SAnurag S. Maskey dladm_close(dld_handle);
2764ac67f02SAnurag S. Maskey return (ret);
2774ac67f02SAnurag S. Maskey }
278074e084fSml93401
2794ac67f02SAnurag S. Maskey die(gettext("-s option should only be invoked by smf(5)\n"));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate
282da14cebeSEric Cheng assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
283da14cebeSEric Cheng type == AC_NET);
284074e084fSml93401
285da14cebeSEric Cheng if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
286074e084fSml93401 die(gettext("%s accounting cannot be configured in "
287074e084fSml93401 "non-global zones\n"), ac_type_name(type));
288074e084fSml93401
289074e084fSml93401 fmri = aconf_type2fmri(type);
290074e084fSml93401 if (aconf_scf_init(fmri) == -1)
291074e084fSml93401 die(gettext("cannot connect to repository for %s\n"), fmri);
292074e084fSml93401
293074e084fSml93401 /*
294074e084fSml93401 * Since the sys_acct the privilege allows use of acctctl() regardless
295074e084fSml93401 * of the accounting type, we check the smf(5) authorizations granted
296074e084fSml93401 * to the user to determine whether the user is allowed to change the
297074e084fSml93401 * configuration for this particular accounting type.
298074e084fSml93401 */
299074e084fSml93401 if (!aconf_have_smf_auths())
300074e084fSml93401 die(gettext("insufficient authorization to change %s extended "
301074e084fSml93401 "accounting configuration\n"), ac_type_name(type));
302074e084fSml93401
3037c478bd9Sstevel@tonic-gate if (xflg) {
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate * Turn off the specified accounting and close its file
3067c478bd9Sstevel@tonic-gate */
307da14cebeSEric Cheng
308da14cebeSEric Cheng /*
309da14cebeSEric Cheng * Stop net logging before turning it off so that the last
310da14cebeSEric Cheng * set of logs can be written.
311da14cebeSEric Cheng */
312da14cebeSEric Cheng if (type & AC_NET) {
313da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
314da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
315ae6aa22aSVenugopal Iyer err = dladm_stop_usagelog(dld_handle,
3164ac67f02SAnurag S. Maskey DLADM_LOGTYPE_FLOW);
317da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
318da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
319ae6aa22aSVenugopal Iyer if (err != DLADM_STATUS_OK) {
320ae6aa22aSVenugopal Iyer die(gettext("failed to stop logging network "
321ae6aa22aSVenugopal Iyer "information, error %d\n"), errno);
322ae6aa22aSVenugopal Iyer }
323da14cebeSEric Cheng }
3247c478bd9Sstevel@tonic-gate state = AC_OFF;
325074e084fSml93401
326074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3277c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
328074e084fSml93401 die(gettext("cannot disable %s accounting"),
329074e084fSml93401 ac_type_name(type));
3307c478bd9Sstevel@tonic-gate if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
331074e084fSml93401 die(gettext("cannot close %s accounting file\n"),
332074e084fSml93401 ac_type_name(type));
333074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
334074e084fSml93401
335074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
336074e084fSml93401 die(gettext("cannot update %s property\n"),
337074e084fSml93401 AC_PROP_STATE);
338074e084fSml93401 if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
339074e084fSml93401 die(gettext("cannot update %s property\n"),
340074e084fSml93401 AC_PROP_FILE);
3417c478bd9Sstevel@tonic-gate modified++;
3427c478bd9Sstevel@tonic-gate }
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate if (enabled || disabled) {
3457c478bd9Sstevel@tonic-gate char *tracked, *untracked;
3467c478bd9Sstevel@tonic-gate ac_res_t *buf;
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate /*
3497c478bd9Sstevel@tonic-gate * Enable/disable resources
3507c478bd9Sstevel@tonic-gate */
3517c478bd9Sstevel@tonic-gate if ((buf = malloc(AC_BUFSIZE)) == NULL)
3527c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n"));
3537c478bd9Sstevel@tonic-gate (void) memset(buf, 0, AC_BUFSIZE);
3547c478bd9Sstevel@tonic-gate if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
3557c478bd9Sstevel@tonic-gate free(buf);
3567c478bd9Sstevel@tonic-gate die(gettext("cannot obtain list of resources\n"));
3577c478bd9Sstevel@tonic-gate }
358da14cebeSEric Cheng if (disabled) {
359da14cebeSEric Cheng /*
360da14cebeSEric Cheng * Stop net logging before turning it off so that the
361da14cebeSEric Cheng * last set of logs can be written.
362da14cebeSEric Cheng */
363da14cebeSEric Cheng if (type & AC_NET) {
364da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
365da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
366ae6aa22aSVenugopal Iyer err = dladm_stop_usagelog(dld_handle,
367ae6aa22aSVenugopal Iyer strcmp(disabled, "basic") == 0 ?
368ae6aa22aSVenugopal Iyer DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW);
369da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
370da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
371ae6aa22aSVenugopal Iyer if (err != DLADM_STATUS_OK) {
372ae6aa22aSVenugopal Iyer die(gettext("failed to stop logging "
373ae6aa22aSVenugopal Iyer "network information, error %d\n"),
374ae6aa22aSVenugopal Iyer errno);
375ae6aa22aSVenugopal Iyer }
376da14cebeSEric Cheng }
3777c478bd9Sstevel@tonic-gate str2buf(buf, disabled, AC_OFF, type);
3780dc2366fSVenugopal Iyer } else if (enabled) {
3797c478bd9Sstevel@tonic-gate str2buf(buf, enabled, AC_ON, type);
380ae6aa22aSVenugopal Iyer }
381074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3827c478bd9Sstevel@tonic-gate if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
3837c478bd9Sstevel@tonic-gate free(buf);
384074e084fSml93401 die(gettext("cannot enable/disable %s accounting "
385074e084fSml93401 "resources\n"), ac_type_name(type));
3867c478bd9Sstevel@tonic-gate }
387074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3887c478bd9Sstevel@tonic-gate tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
3897c478bd9Sstevel@tonic-gate untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
390074e084fSml93401 if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
391074e084fSml93401 die(gettext("cannot update %s property\n"),
392074e084fSml93401 AC_PROP_TRACKED);
393074e084fSml93401 if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
394074e084fSml93401 die(gettext("cannot update %s property\n"),
395074e084fSml93401 AC_PROP_UNTRACKED);
3967c478bd9Sstevel@tonic-gate free(tracked);
3977c478bd9Sstevel@tonic-gate free(untracked);
3987c478bd9Sstevel@tonic-gate free(buf);
3997c478bd9Sstevel@tonic-gate modified++;
4007c478bd9Sstevel@tonic-gate }
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate if (file) {
4037c478bd9Sstevel@tonic-gate /*
4047c478bd9Sstevel@tonic-gate * Open new accounting file
4057c478bd9Sstevel@tonic-gate */
406074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4074ac67f02SAnurag S. Maskey if (open_exacct_file(file, type) == -1) {
4084ac67f02SAnurag S. Maskey dladm_close(dld_handle);
409074e084fSml93401 exit(E_ERROR);
4104ac67f02SAnurag S. Maskey }
411074e084fSml93401 if (aconf_set_string(AC_PROP_FILE, file) == -1)
412074e084fSml93401 die(gettext("cannot update %s property\n"),
413074e084fSml93401 AC_PROP_FILE);
4147c478bd9Sstevel@tonic-gate state = AC_ON;
415074e084fSml93401
4167c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
417074e084fSml93401 die(gettext("cannot enable %s accounting"),
418074e084fSml93401 ac_type_name(type));
419074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
420074e084fSml93401
421074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
422074e084fSml93401 die(gettext("cannot update %s property\n"),
423074e084fSml93401 AC_PROP_STATE);
4247c478bd9Sstevel@tonic-gate modified++;
4257c478bd9Sstevel@tonic-gate }
4267c478bd9Sstevel@tonic-gate
4270dc2366fSVenugopal Iyer /*
4280dc2366fSVenugopal Iyer * Let's get network logging started. We do this after turning on
4290dc2366fSVenugopal Iyer * accounting and opening the file so that we can start writing
4300dc2366fSVenugopal Iyer * immediately.
4310dc2366fSVenugopal Iyer */
4320dc2366fSVenugopal Iyer if (enabled && (type & AC_NET)) {
4330dc2366fSVenugopal Iyer /*
4340dc2366fSVenugopal Iyer * Default logging interval for AC_NET is
4350dc2366fSVenugopal Iyer * ACCTADM_NET_LOG_INTERVAL.
4360dc2366fSVenugopal Iyer */
4370dc2366fSVenugopal Iyer (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
4380dc2366fSVenugopal Iyer PRIV_SYS_DL_CONFIG, NULL);
4390dc2366fSVenugopal Iyer err = dladm_start_usagelog(dld_handle,
4400dc2366fSVenugopal Iyer strcmp(enabled, "basic") == 0 ?
4410dc2366fSVenugopal Iyer DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW,
4420dc2366fSVenugopal Iyer ACCTADM_NET_LOG_INTERVAL);
4430dc2366fSVenugopal Iyer (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
4440dc2366fSVenugopal Iyer PRIV_SYS_DL_CONFIG, NULL);
4450dc2366fSVenugopal Iyer if (err != DLADM_STATUS_OK) {
4460dc2366fSVenugopal Iyer die(gettext("failed to start logging "
4470dc2366fSVenugopal Iyer "network information, error %d\n"),
4480dc2366fSVenugopal Iyer errno);
4490dc2366fSVenugopal Iyer }
4500dc2366fSVenugopal Iyer }
4510dc2366fSVenugopal Iyer
4527c478bd9Sstevel@tonic-gate if (Dflg) {
4537c478bd9Sstevel@tonic-gate /*
4547c478bd9Sstevel@tonic-gate * Disable accounting
4557c478bd9Sstevel@tonic-gate */
456da14cebeSEric Cheng
457da14cebeSEric Cheng /*
458da14cebeSEric Cheng * Stop net logging before turning it off so that the last
459da14cebeSEric Cheng * set of logs can be written.
460da14cebeSEric Cheng */
461da14cebeSEric Cheng if (type & AC_NET) {
462da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
463da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
464ae6aa22aSVenugopal Iyer err = dladm_stop_usagelog(dld_handle,
4654ac67f02SAnurag S. Maskey DLADM_LOGTYPE_FLOW);
466da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
467da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL);
468ae6aa22aSVenugopal Iyer if (err != DLADM_STATUS_OK) {
469ae6aa22aSVenugopal Iyer die(gettext("failed to stop logging "
470ae6aa22aSVenugopal Iyer "network information, error %d\n"), errno);
471ae6aa22aSVenugopal Iyer }
472da14cebeSEric Cheng }
4737c478bd9Sstevel@tonic-gate state = AC_OFF;
474074e084fSml93401
475074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4767c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
477074e084fSml93401 die(gettext("cannot disable %s accounting"),
478074e084fSml93401 ac_type_name(type));
479074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
480074e084fSml93401
481074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
482074e084fSml93401 die(gettext("cannot update %s property\n"),
483074e084fSml93401 AC_PROP_STATE);
4847c478bd9Sstevel@tonic-gate modified++;
4857c478bd9Sstevel@tonic-gate }
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate if (Eflg) {
4887c478bd9Sstevel@tonic-gate /*
4897c478bd9Sstevel@tonic-gate * Enable accounting
4907c478bd9Sstevel@tonic-gate */
491ae6aa22aSVenugopal Iyer
492ae6aa22aSVenugopal Iyer /*
493ae6aa22aSVenugopal Iyer * Let's get network logging started.
494ae6aa22aSVenugopal Iyer */
495ae6aa22aSVenugopal Iyer if (type & AC_NET) {
496ae6aa22aSVenugopal Iyer /*
497ae6aa22aSVenugopal Iyer * Default logging interval for AC_NET is
498ae6aa22aSVenugopal Iyer * ACCTADM_NET_LOG_INTERVAL.
499ae6aa22aSVenugopal Iyer */
500ae6aa22aSVenugopal Iyer (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
501ae6aa22aSVenugopal Iyer PRIV_SYS_DL_CONFIG, NULL);
502ae6aa22aSVenugopal Iyer err = dladm_start_usagelog(dld_handle,
503ae6aa22aSVenugopal Iyer DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL);
504ae6aa22aSVenugopal Iyer (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
505ae6aa22aSVenugopal Iyer PRIV_SYS_DL_CONFIG, NULL);
506ae6aa22aSVenugopal Iyer if (err != DLADM_STATUS_OK) {
507ae6aa22aSVenugopal Iyer die(gettext("failed to start logging "
508ae6aa22aSVenugopal Iyer "network information, error %d\n"), errno);
509ae6aa22aSVenugopal Iyer }
510ae6aa22aSVenugopal Iyer }
5117c478bd9Sstevel@tonic-gate state = AC_ON;
512074e084fSml93401
513074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
5147c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
515074e084fSml93401 die(gettext("cannot enable %s accounting"),
516074e084fSml93401 ac_type_name(type));
517074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
518074e084fSml93401
519074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
520074e084fSml93401 die(gettext("cannot update %s property\n"),
521074e084fSml93401 AC_PROP_STATE);
5227c478bd9Sstevel@tonic-gate modified++;
5237c478bd9Sstevel@tonic-gate }
524074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate if (modified) {
527074e084fSml93401 char *smf_state;
5287c478bd9Sstevel@tonic-gate
529074e084fSml93401 if (aconf_save() == -1)
530074e084fSml93401 die(gettext("cannot save %s accounting "
531074e084fSml93401 "configuration\n"), ac_type_name(type));
532074e084fSml93401
533074e084fSml93401 /*
534074e084fSml93401 * Enable or disable the instance depending on the effective
535074e084fSml93401 * configuration. If the effective configuration results in
536074e084fSml93401 * extended accounting being 'on', the instance is enabled so
537074e084fSml93401 * the configuration is applied at the next boot.
538074e084fSml93401 */
539074e084fSml93401 smf_state = smf_get_state(fmri);
540074e084fSml93401 aconf_init(&ac, type);
541074e084fSml93401
542074e084fSml93401 if (ac.state == AC_ON ||
543074e084fSml93401 strcmp(ac.file, AC_STR_NONE) != 0 ||
544074e084fSml93401 strcmp(ac.tracked, AC_STR_NONE) != 0) {
545074e084fSml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
546074e084fSml93401 if (smf_enable_instance(fmri, 0) == -1)
547074e084fSml93401 die(gettext("cannot enable %s\n"),
548074e084fSml93401 fmri);
549074e084fSml93401 } else {
550074e084fSml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
551074e084fSml93401 if (smf_disable_instance(fmri, 0) == -1)
552074e084fSml93401 die(gettext("cannot disable %s\n"),
553074e084fSml93401 fmri);
554074e084fSml93401 }
555074e084fSml93401 free(smf_state);
556074e084fSml93401 }
557074e084fSml93401 aconf_scf_fini();
5584ac67f02SAnurag S. Maskey dladm_close(dld_handle);
5597c478bd9Sstevel@tonic-gate return (E_SUCCESS);
5607c478bd9Sstevel@tonic-gate }
561