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