10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57103Sml93401 * Common Development and Distribution License (the "License").
67103Sml93401 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21*13093SRoger.Faulkner@Oracle.COM
220Sstevel@tonic-gate /*
23*13093SRoger.Faulkner@Oracle.COM * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #include <sys/acctctl.h>
277103Sml93401 #include <assert.h>
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <unistd.h>
310Sstevel@tonic-gate #include <string.h>
320Sstevel@tonic-gate #include <errno.h>
330Sstevel@tonic-gate #include <libintl.h>
348275SEric Cheng #include <libdllink.h>
350Sstevel@tonic-gate #include <locale.h>
367103Sml93401 #include <priv.h>
377103Sml93401 #include <libscf.h>
387103Sml93401 #include <zone.h>
390Sstevel@tonic-gate
400Sstevel@tonic-gate #include "utils.h"
410Sstevel@tonic-gate #include "aconf.h"
420Sstevel@tonic-gate #include "res.h"
430Sstevel@tonic-gate
448833SVenu.Iyer@Sun.COM #define ACCTADM_NET_LOG_INTERVAL 20
458833SVenu.Iyer@Sun.COM
460Sstevel@tonic-gate static const char USAGE[] = "\
470Sstevel@tonic-gate Usage:\n\
488275SEric Cheng acctadm [ {process | task | flow | net} ]\n\
497103Sml93401 acctadm -s\n\
508275SEric Cheng acctadm -r [ {process | task | flow | net} ]\n\
518275SEric Cheng acctadm -x|-E|-D {process | task | flow | net}\n\
528275SEric Cheng acctadm -f filename {process | task | flow | net}\n\
538275SEric Cheng acctadm -e resources -d resources {process | task | flow | net}\n";
540Sstevel@tonic-gate
557103Sml93401 static const char OPTS[] = "rsxf:e:d:ED";
560Sstevel@tonic-gate
578453SAnurag.Maskey@Sun.COM dladm_handle_t dld_handle = NULL;
588453SAnurag.Maskey@Sun.COM
590Sstevel@tonic-gate static void
usage()600Sstevel@tonic-gate usage()
610Sstevel@tonic-gate {
620Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE));
630Sstevel@tonic-gate exit(E_USAGE);
640Sstevel@tonic-gate }
650Sstevel@tonic-gate
667103Sml93401 static void
setup_privs()677103Sml93401 setup_privs()
687103Sml93401 {
697103Sml93401 priv_set_t *privset;
707103Sml93401
717103Sml93401 if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
727103Sml93401 die(gettext("seteuid()/setegid() failed"));
737103Sml93401
747103Sml93401 /*
757103Sml93401 * Add our privileges and remove unneeded 'basic' privileges from the
767103Sml93401 * permitted set.
777103Sml93401 */
787103Sml93401 if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
797103Sml93401 die(gettext("cannot setup privileges"));
807103Sml93401
817103Sml93401 (void) priv_addset(privset, PRIV_SYS_ACCT);
827103Sml93401 (void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
838275SEric Cheng (void) priv_addset(privset, PRIV_SYS_DL_CONFIG);
847103Sml93401 (void) priv_delset(privset, PRIV_FILE_LINK_ANY);
857103Sml93401 (void) priv_delset(privset, PRIV_PROC_EXEC);
867103Sml93401 (void) priv_delset(privset, PRIV_PROC_FORK);
877103Sml93401 (void) priv_delset(privset, PRIV_PROC_INFO);
887103Sml93401 (void) priv_delset(privset, PRIV_PROC_SESSION);
897103Sml93401 priv_inverse(privset);
907103Sml93401 if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
917103Sml93401 die(gettext("cannot setup privileges"));
927103Sml93401 priv_freeset(privset);
937103Sml93401
947103Sml93401 /*
957103Sml93401 * Clear the Inheritable and Limit sets.
967103Sml93401 */
977103Sml93401 if ((privset = priv_allocset()) == NULL)
987103Sml93401 die(gettext("cannot setup privileges"));
997103Sml93401 priv_emptyset(privset);
1007103Sml93401 if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
1017103Sml93401 setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
1027103Sml93401 die(gettext("cannot setup privileges"));
1037103Sml93401
1047103Sml93401 /*
1058275SEric Cheng * Turn off the sys_acct, file_dac_write and dl_config privileges
1068275SEric Cheng * until needed.
1077103Sml93401 */
1087103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
1098275SEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
1107103Sml93401 }
1117103Sml93401
1120Sstevel@tonic-gate int
main(int argc,char * argv[])1130Sstevel@tonic-gate main(int argc, char *argv[])
1140Sstevel@tonic-gate {
1150Sstevel@tonic-gate int c; /* options character */
1160Sstevel@tonic-gate int type = 0; /* type of accounting */
1177103Sml93401 int modified = 0; /* have we modified any properties? */
1180Sstevel@tonic-gate acctconf_t ac; /* current configuration */
1190Sstevel@tonic-gate char *typestr = NULL; /* type of accounting argument string */
1200Sstevel@tonic-gate char *enabled = NULL; /* enabled resources string */
1210Sstevel@tonic-gate char *disabled = NULL; /* disabled resources string */
1220Sstevel@tonic-gate char *file = NULL;
1230Sstevel@tonic-gate int Eflg = 0;
1240Sstevel@tonic-gate int Dflg = 0;
1250Sstevel@tonic-gate int rflg = 0;
1267103Sml93401 int sflg = 0;
1270Sstevel@tonic-gate int xflg = 0;
1280Sstevel@tonic-gate int optcnt = 0;
1290Sstevel@tonic-gate int state;
1307103Sml93401 const char *fmri; /* FMRI for this instance */
1318833SVenu.Iyer@Sun.COM int err = 0;
1327103Sml93401
1337103Sml93401 setup_privs();
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
1360Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
137*13093SRoger.Faulkner@Oracle.COM (void) setpname(argv[0]);
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate for (; optind < argc; optind++) {
1400Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
1410Sstevel@tonic-gate switch (c) {
1420Sstevel@tonic-gate case 'd':
1430Sstevel@tonic-gate disabled = optarg;
1440Sstevel@tonic-gate break;
1450Sstevel@tonic-gate case 'e':
1460Sstevel@tonic-gate enabled = optarg;
1470Sstevel@tonic-gate break;
1480Sstevel@tonic-gate case 'D':
1490Sstevel@tonic-gate Dflg = 1;
1500Sstevel@tonic-gate optcnt++;
1510Sstevel@tonic-gate break;
1520Sstevel@tonic-gate case 'E':
1530Sstevel@tonic-gate Eflg = 1;
1540Sstevel@tonic-gate optcnt++;
1550Sstevel@tonic-gate break;
1560Sstevel@tonic-gate case 'f':
1570Sstevel@tonic-gate file = optarg;
1580Sstevel@tonic-gate optcnt++;
1590Sstevel@tonic-gate break;
1600Sstevel@tonic-gate case 'r':
1610Sstevel@tonic-gate rflg = 1;
1620Sstevel@tonic-gate optcnt++;
1630Sstevel@tonic-gate break;
1647103Sml93401 case 's':
1657103Sml93401 sflg = 1;
1660Sstevel@tonic-gate optcnt++;
1670Sstevel@tonic-gate break;
1680Sstevel@tonic-gate case 'x':
1690Sstevel@tonic-gate xflg = 1;
1700Sstevel@tonic-gate optcnt++;
1710Sstevel@tonic-gate break;
1720Sstevel@tonic-gate case '?':
1730Sstevel@tonic-gate default:
1740Sstevel@tonic-gate usage();
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate }
1777103Sml93401
1787103Sml93401 /*
1797103Sml93401 * Permanently give up euid 0, egid 0 and privileges we
1807103Sml93401 * don't need for the specified options.
1817103Sml93401 */
1827103Sml93401 if (!(file || sflg)) {
1837103Sml93401 if (setreuid(getuid(), getuid()) == -1 ||
1847103Sml93401 setregid(getgid(), getgid()) == -1)
1857103Sml93401 die(gettext("setreuid()/setregid() failed"));
1867103Sml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
1877103Sml93401 PRIV_FILE_DAC_WRITE, NULL);
1887103Sml93401 }
1897103Sml93401 if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
1907103Sml93401 xflg))
1917103Sml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
1928275SEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
1937103Sml93401
1940Sstevel@tonic-gate if (optind < argc) {
1950Sstevel@tonic-gate if (typestr != NULL) {
1960Sstevel@tonic-gate warn(gettext("illegal argument -- %s\n"),
1970Sstevel@tonic-gate argv[optind]);
1980Sstevel@tonic-gate usage();
1990Sstevel@tonic-gate } else {
2000Sstevel@tonic-gate typestr = argv[optind];
2010Sstevel@tonic-gate }
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate if (typestr != NULL) {
2050Sstevel@tonic-gate if (strcmp(typestr, "process") == 0 ||
2060Sstevel@tonic-gate strcmp(typestr, "proc") == 0)
2070Sstevel@tonic-gate type |= AC_PROC;
2080Sstevel@tonic-gate else if (strcmp(typestr, "task") == 0)
2090Sstevel@tonic-gate type |= AC_TASK;
2100Sstevel@tonic-gate else if (strcmp(typestr, "flow") == 0)
2110Sstevel@tonic-gate type |= AC_FLOW;
2128275SEric Cheng else if (strcmp(typestr, "net") == 0)
2138275SEric Cheng type |= AC_NET;
2140Sstevel@tonic-gate else {
2150Sstevel@tonic-gate warn(gettext("unknown accounting type -- %s\n"),
2160Sstevel@tonic-gate typestr);
2170Sstevel@tonic-gate usage();
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate } else
2208275SEric Cheng type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;
2210Sstevel@tonic-gate
2220Sstevel@tonic-gate /*
2238275SEric Cheng * Drop the DL config privilege if we are not working with
2248275SEric Cheng * net.
2258275SEric Cheng */
2268275SEric Cheng if ((type & AC_NET) == 0) {
2278275SEric Cheng (void) priv_set(PRIV_OFF, PRIV_PERMITTED,
2288275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
2298275SEric Cheng }
2308275SEric Cheng /*
2310Sstevel@tonic-gate * check for invalid options
2320Sstevel@tonic-gate */
2330Sstevel@tonic-gate if (optcnt > 1)
2340Sstevel@tonic-gate usage();
2350Sstevel@tonic-gate
2368275SEric Cheng /*
2378275SEric Cheng * XXX For AC_NET, enabled/disabled should only be "basic" or
2388275SEric Cheng * "extended" - need to check it here.
2398275SEric Cheng */
2407103Sml93401 if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
2410Sstevel@tonic-gate usage();
2420Sstevel@tonic-gate
2430Sstevel@tonic-gate if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
2440Sstevel@tonic-gate !typestr) {
2450Sstevel@tonic-gate warn(gettext("accounting type must be specified\n"));
2460Sstevel@tonic-gate usage();
2470Sstevel@tonic-gate }
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate if (rflg) {
2500Sstevel@tonic-gate printgroups(type);
2510Sstevel@tonic-gate return (E_SUCCESS);
2520Sstevel@tonic-gate }
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate /*
2557103Sml93401 * If no arguments have been passed then just print out the current
2567103Sml93401 * state and exit.
2570Sstevel@tonic-gate */
2580Sstevel@tonic-gate if (!enabled && !disabled && !file &&
2597103Sml93401 !Eflg && !rflg && !Dflg && !sflg && !xflg) {
2607103Sml93401 aconf_print(stdout, type);
2610Sstevel@tonic-gate return (E_SUCCESS);
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate
2648453SAnurag.Maskey@Sun.COM /* Open the libdladm handle */
2658453SAnurag.Maskey@Sun.COM if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
2668453SAnurag.Maskey@Sun.COM die(gettext("failed to open dladm handle\n"));
2678453SAnurag.Maskey@Sun.COM
2687103Sml93401 /*
2697103Sml93401 * smf(5) start method. The FMRI to operate on is retrieved from the
2707103Sml93401 * SMF_FMRI environment variable that the restarter provides.
2717103Sml93401 */
2727103Sml93401 if (sflg) {
2738453SAnurag.Maskey@Sun.COM if ((fmri = getenv("SMF_FMRI")) != NULL) {
2748453SAnurag.Maskey@Sun.COM int ret = aconf_setup(fmri);
2758453SAnurag.Maskey@Sun.COM dladm_close(dld_handle);
2768453SAnurag.Maskey@Sun.COM return (ret);
2778453SAnurag.Maskey@Sun.COM }
2787103Sml93401
2798453SAnurag.Maskey@Sun.COM die(gettext("-s option should only be invoked by smf(5)\n"));
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate
2828275SEric Cheng assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
2838275SEric Cheng type == AC_NET);
2847103Sml93401
2858275SEric Cheng if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
2867103Sml93401 die(gettext("%s accounting cannot be configured in "
2877103Sml93401 "non-global zones\n"), ac_type_name(type));
2887103Sml93401
2897103Sml93401 fmri = aconf_type2fmri(type);
2907103Sml93401 if (aconf_scf_init(fmri) == -1)
2917103Sml93401 die(gettext("cannot connect to repository for %s\n"), fmri);
2927103Sml93401
2937103Sml93401 /*
2947103Sml93401 * Since the sys_acct the privilege allows use of acctctl() regardless
2957103Sml93401 * of the accounting type, we check the smf(5) authorizations granted
2967103Sml93401 * to the user to determine whether the user is allowed to change the
2977103Sml93401 * configuration for this particular accounting type.
2987103Sml93401 */
2997103Sml93401 if (!aconf_have_smf_auths())
3007103Sml93401 die(gettext("insufficient authorization to change %s extended "
3017103Sml93401 "accounting configuration\n"), ac_type_name(type));
3027103Sml93401
3030Sstevel@tonic-gate if (xflg) {
3040Sstevel@tonic-gate /*
3050Sstevel@tonic-gate * Turn off the specified accounting and close its file
3060Sstevel@tonic-gate */
3078275SEric Cheng
3088275SEric Cheng /*
3098275SEric Cheng * Stop net logging before turning it off so that the last
3108275SEric Cheng * set of logs can be written.
3118275SEric Cheng */
3128275SEric Cheng if (type & AC_NET) {
3138275SEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
3148275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
3158833SVenu.Iyer@Sun.COM err = dladm_stop_usagelog(dld_handle,
3168453SAnurag.Maskey@Sun.COM DLADM_LOGTYPE_FLOW);
3178275SEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
3188275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
3198833SVenu.Iyer@Sun.COM if (err != DLADM_STATUS_OK) {
3208833SVenu.Iyer@Sun.COM die(gettext("failed to stop logging network "
3218833SVenu.Iyer@Sun.COM "information, error %d\n"), errno);
3228833SVenu.Iyer@Sun.COM }
3238275SEric Cheng }
3240Sstevel@tonic-gate state = AC_OFF;
3257103Sml93401
3267103Sml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3270Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
3287103Sml93401 die(gettext("cannot disable %s accounting"),
3297103Sml93401 ac_type_name(type));
3300Sstevel@tonic-gate if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
3317103Sml93401 die(gettext("cannot close %s accounting file\n"),
3327103Sml93401 ac_type_name(type));
3337103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3347103Sml93401
3357103Sml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
3367103Sml93401 die(gettext("cannot update %s property\n"),
3377103Sml93401 AC_PROP_STATE);
3387103Sml93401 if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
3397103Sml93401 die(gettext("cannot update %s property\n"),
3407103Sml93401 AC_PROP_FILE);
3410Sstevel@tonic-gate modified++;
3420Sstevel@tonic-gate }
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate if (enabled || disabled) {
3450Sstevel@tonic-gate char *tracked, *untracked;
3460Sstevel@tonic-gate ac_res_t *buf;
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate /*
3490Sstevel@tonic-gate * Enable/disable resources
3500Sstevel@tonic-gate */
3510Sstevel@tonic-gate if ((buf = malloc(AC_BUFSIZE)) == NULL)
3520Sstevel@tonic-gate die(gettext("not enough memory\n"));
3530Sstevel@tonic-gate (void) memset(buf, 0, AC_BUFSIZE);
3540Sstevel@tonic-gate if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
3550Sstevel@tonic-gate free(buf);
3560Sstevel@tonic-gate die(gettext("cannot obtain list of resources\n"));
3570Sstevel@tonic-gate }
3588275SEric Cheng if (disabled) {
3598275SEric Cheng /*
3608275SEric Cheng * Stop net logging before turning it off so that the
3618275SEric Cheng * last set of logs can be written.
3628275SEric Cheng */
3638275SEric Cheng if (type & AC_NET) {
3648275SEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
3658275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
3668833SVenu.Iyer@Sun.COM err = dladm_stop_usagelog(dld_handle,
3678833SVenu.Iyer@Sun.COM strcmp(disabled, "basic") == 0 ?
3688833SVenu.Iyer@Sun.COM DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW);
3698275SEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
3708275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
3718833SVenu.Iyer@Sun.COM if (err != DLADM_STATUS_OK) {
3728833SVenu.Iyer@Sun.COM die(gettext("failed to stop logging "
3738833SVenu.Iyer@Sun.COM "network information, error %d\n"),
3748833SVenu.Iyer@Sun.COM errno);
3758833SVenu.Iyer@Sun.COM }
3768275SEric Cheng }
3770Sstevel@tonic-gate str2buf(buf, disabled, AC_OFF, type);
37811878SVenu.Iyer@Sun.COM } else if (enabled) {
3790Sstevel@tonic-gate str2buf(buf, enabled, AC_ON, type);
3808833SVenu.Iyer@Sun.COM }
3817103Sml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3820Sstevel@tonic-gate if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
3830Sstevel@tonic-gate free(buf);
3847103Sml93401 die(gettext("cannot enable/disable %s accounting "
3857103Sml93401 "resources\n"), ac_type_name(type));
3860Sstevel@tonic-gate }
3877103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
3880Sstevel@tonic-gate tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
3890Sstevel@tonic-gate untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
3907103Sml93401 if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
3917103Sml93401 die(gettext("cannot update %s property\n"),
3927103Sml93401 AC_PROP_TRACKED);
3937103Sml93401 if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
3947103Sml93401 die(gettext("cannot update %s property\n"),
3957103Sml93401 AC_PROP_UNTRACKED);
3960Sstevel@tonic-gate free(tracked);
3970Sstevel@tonic-gate free(untracked);
3980Sstevel@tonic-gate free(buf);
3990Sstevel@tonic-gate modified++;
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate if (file) {
4030Sstevel@tonic-gate /*
4040Sstevel@tonic-gate * Open new accounting file
4050Sstevel@tonic-gate */
4067103Sml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4078453SAnurag.Maskey@Sun.COM if (open_exacct_file(file, type) == -1) {
4088453SAnurag.Maskey@Sun.COM dladm_close(dld_handle);
4097103Sml93401 exit(E_ERROR);
4108453SAnurag.Maskey@Sun.COM }
4117103Sml93401 if (aconf_set_string(AC_PROP_FILE, file) == -1)
4127103Sml93401 die(gettext("cannot update %s property\n"),
4137103Sml93401 AC_PROP_FILE);
4140Sstevel@tonic-gate state = AC_ON;
4157103Sml93401
4160Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
4177103Sml93401 die(gettext("cannot enable %s accounting"),
4187103Sml93401 ac_type_name(type));
4197103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4207103Sml93401
4217103Sml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
4227103Sml93401 die(gettext("cannot update %s property\n"),
4237103Sml93401 AC_PROP_STATE);
4240Sstevel@tonic-gate modified++;
4250Sstevel@tonic-gate }
4260Sstevel@tonic-gate
42711878SVenu.Iyer@Sun.COM /*
42811878SVenu.Iyer@Sun.COM * Let's get network logging started. We do this after turning on
42911878SVenu.Iyer@Sun.COM * accounting and opening the file so that we can start writing
43011878SVenu.Iyer@Sun.COM * immediately.
43111878SVenu.Iyer@Sun.COM */
43211878SVenu.Iyer@Sun.COM if (enabled && (type & AC_NET)) {
43311878SVenu.Iyer@Sun.COM /*
43411878SVenu.Iyer@Sun.COM * Default logging interval for AC_NET is
43511878SVenu.Iyer@Sun.COM * ACCTADM_NET_LOG_INTERVAL.
43611878SVenu.Iyer@Sun.COM */
43711878SVenu.Iyer@Sun.COM (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
43811878SVenu.Iyer@Sun.COM PRIV_SYS_DL_CONFIG, NULL);
43911878SVenu.Iyer@Sun.COM err = dladm_start_usagelog(dld_handle,
44011878SVenu.Iyer@Sun.COM strcmp(enabled, "basic") == 0 ?
44111878SVenu.Iyer@Sun.COM DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW,
44211878SVenu.Iyer@Sun.COM ACCTADM_NET_LOG_INTERVAL);
44311878SVenu.Iyer@Sun.COM (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
44411878SVenu.Iyer@Sun.COM PRIV_SYS_DL_CONFIG, NULL);
44511878SVenu.Iyer@Sun.COM if (err != DLADM_STATUS_OK) {
44611878SVenu.Iyer@Sun.COM die(gettext("failed to start logging "
44711878SVenu.Iyer@Sun.COM "network information, error %d\n"),
44811878SVenu.Iyer@Sun.COM errno);
44911878SVenu.Iyer@Sun.COM }
45011878SVenu.Iyer@Sun.COM }
45111878SVenu.Iyer@Sun.COM
4520Sstevel@tonic-gate if (Dflg) {
4530Sstevel@tonic-gate /*
4540Sstevel@tonic-gate * Disable accounting
4550Sstevel@tonic-gate */
4568275SEric Cheng
4578275SEric Cheng /*
4588275SEric Cheng * Stop net logging before turning it off so that the last
4598275SEric Cheng * set of logs can be written.
4608275SEric Cheng */
4618275SEric Cheng if (type & AC_NET) {
4628275SEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
4638275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
4648833SVenu.Iyer@Sun.COM err = dladm_stop_usagelog(dld_handle,
4658453SAnurag.Maskey@Sun.COM DLADM_LOGTYPE_FLOW);
4668275SEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
4678275SEric Cheng PRIV_SYS_DL_CONFIG, NULL);
4688833SVenu.Iyer@Sun.COM if (err != DLADM_STATUS_OK) {
4698833SVenu.Iyer@Sun.COM die(gettext("failed to stop logging "
4708833SVenu.Iyer@Sun.COM "network information, error %d\n"), errno);
4718833SVenu.Iyer@Sun.COM }
4728275SEric Cheng }
4730Sstevel@tonic-gate state = AC_OFF;
4747103Sml93401
4757103Sml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4760Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
4777103Sml93401 die(gettext("cannot disable %s accounting"),
4787103Sml93401 ac_type_name(type));
4797103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
4807103Sml93401
4817103Sml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
4827103Sml93401 die(gettext("cannot update %s property\n"),
4837103Sml93401 AC_PROP_STATE);
4840Sstevel@tonic-gate modified++;
4850Sstevel@tonic-gate }
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate if (Eflg) {
4880Sstevel@tonic-gate /*
4890Sstevel@tonic-gate * Enable accounting
4900Sstevel@tonic-gate */
4918833SVenu.Iyer@Sun.COM
4928833SVenu.Iyer@Sun.COM /*
4938833SVenu.Iyer@Sun.COM * Let's get network logging started.
4948833SVenu.Iyer@Sun.COM */
4958833SVenu.Iyer@Sun.COM if (type & AC_NET) {
4968833SVenu.Iyer@Sun.COM /*
4978833SVenu.Iyer@Sun.COM * Default logging interval for AC_NET is
4988833SVenu.Iyer@Sun.COM * ACCTADM_NET_LOG_INTERVAL.
4998833SVenu.Iyer@Sun.COM */
5008833SVenu.Iyer@Sun.COM (void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
5018833SVenu.Iyer@Sun.COM PRIV_SYS_DL_CONFIG, NULL);
5028833SVenu.Iyer@Sun.COM err = dladm_start_usagelog(dld_handle,
5038833SVenu.Iyer@Sun.COM DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL);
5048833SVenu.Iyer@Sun.COM (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
5058833SVenu.Iyer@Sun.COM PRIV_SYS_DL_CONFIG, NULL);
5068833SVenu.Iyer@Sun.COM if (err != DLADM_STATUS_OK) {
5078833SVenu.Iyer@Sun.COM die(gettext("failed to start logging "
5088833SVenu.Iyer@Sun.COM "network information, error %d\n"), errno);
5098833SVenu.Iyer@Sun.COM }
5108833SVenu.Iyer@Sun.COM }
5110Sstevel@tonic-gate state = AC_ON;
5127103Sml93401
5137103Sml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
5140Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
5157103Sml93401 die(gettext("cannot enable %s accounting"),
5167103Sml93401 ac_type_name(type));
5177103Sml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
5187103Sml93401
5197103Sml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
5207103Sml93401 die(gettext("cannot update %s property\n"),
5217103Sml93401 AC_PROP_STATE);
5220Sstevel@tonic-gate modified++;
5230Sstevel@tonic-gate }
5247103Sml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);
5250Sstevel@tonic-gate
5260Sstevel@tonic-gate if (modified) {
5277103Sml93401 char *smf_state;
5287103Sml93401
5297103Sml93401 if (aconf_save() == -1)
5307103Sml93401 die(gettext("cannot save %s accounting "
5317103Sml93401 "configuration\n"), ac_type_name(type));
5327103Sml93401
5330Sstevel@tonic-gate /*
5347103Sml93401 * Enable or disable the instance depending on the effective
5357103Sml93401 * configuration. If the effective configuration results in
5367103Sml93401 * extended accounting being 'on', the instance is enabled so
5377103Sml93401 * the configuration is applied at the next boot.
5380Sstevel@tonic-gate */
5397103Sml93401 smf_state = smf_get_state(fmri);
5407103Sml93401 aconf_init(&ac, type);
5417103Sml93401
5427103Sml93401 if (ac.state == AC_ON ||
5437103Sml93401 strcmp(ac.file, AC_STR_NONE) != 0 ||
5447103Sml93401 strcmp(ac.tracked, AC_STR_NONE) != 0) {
5457103Sml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
5467103Sml93401 if (smf_enable_instance(fmri, 0) == -1)
5477103Sml93401 die(gettext("cannot enable %s\n"),
5487103Sml93401 fmri);
5497103Sml93401 } else {
5507103Sml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
5517103Sml93401 if (smf_disable_instance(fmri, 0) == -1)
5527103Sml93401 die(gettext("cannot disable %s\n"),
5537103Sml93401 fmri);
5547103Sml93401 }
5557103Sml93401 free(smf_state);
5560Sstevel@tonic-gate }
5577103Sml93401 aconf_scf_fini();
5588453SAnurag.Maskey@Sun.COM dladm_close(dld_handle);
5590Sstevel@tonic-gate return (E_SUCCESS);
5600Sstevel@tonic-gate }
561