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> 34*da14cebeSEric 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\ 46*da14cebeSEric Cheng acctadm [ {process | task | flow | net} ]\n\ 47074e084fSml93401 acctadm -s\n\ 48*da14cebeSEric Cheng acctadm -r [ {process | task | flow | net} ]\n\ 49*da14cebeSEric Cheng acctadm -x|-E|-D {process | task | flow | net}\n\ 50*da14cebeSEric Cheng acctadm -f filename {process | task | flow | net}\n\ 51*da14cebeSEric 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 557c478bd9Sstevel@tonic-gate static void 567c478bd9Sstevel@tonic-gate usage() 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(USAGE)); 597c478bd9Sstevel@tonic-gate exit(E_USAGE); 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 62074e084fSml93401 static void 63074e084fSml93401 setup_privs() 64074e084fSml93401 { 65074e084fSml93401 priv_set_t *privset; 66074e084fSml93401 67074e084fSml93401 if (seteuid(getuid()) == -1 || setegid(getgid()) == -1) 68074e084fSml93401 die(gettext("seteuid()/setegid() failed")); 69074e084fSml93401 70074e084fSml93401 /* 71074e084fSml93401 * Add our privileges and remove unneeded 'basic' privileges from the 72074e084fSml93401 * permitted set. 73074e084fSml93401 */ 74074e084fSml93401 if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL) 75074e084fSml93401 die(gettext("cannot setup privileges")); 76074e084fSml93401 77074e084fSml93401 (void) priv_addset(privset, PRIV_SYS_ACCT); 78074e084fSml93401 (void) priv_addset(privset, PRIV_FILE_DAC_WRITE); 79*da14cebeSEric Cheng (void) priv_addset(privset, PRIV_SYS_DL_CONFIG); 80074e084fSml93401 (void) priv_delset(privset, PRIV_FILE_LINK_ANY); 81074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_EXEC); 82074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_FORK); 83074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_INFO); 84074e084fSml93401 (void) priv_delset(privset, PRIV_PROC_SESSION); 85074e084fSml93401 priv_inverse(privset); 86074e084fSml93401 if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1) 87074e084fSml93401 die(gettext("cannot setup privileges")); 88074e084fSml93401 priv_freeset(privset); 89074e084fSml93401 90074e084fSml93401 /* 91074e084fSml93401 * Clear the Inheritable and Limit sets. 92074e084fSml93401 */ 93074e084fSml93401 if ((privset = priv_allocset()) == NULL) 94074e084fSml93401 die(gettext("cannot setup privileges")); 95074e084fSml93401 priv_emptyset(privset); 96074e084fSml93401 if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 || 97074e084fSml93401 setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1) 98074e084fSml93401 die(gettext("cannot setup privileges")); 99074e084fSml93401 100074e084fSml93401 /* 101*da14cebeSEric Cheng * Turn off the sys_acct, file_dac_write and dl_config privileges 102*da14cebeSEric Cheng * until needed. 103074e084fSml93401 */ 104074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 105*da14cebeSEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL); 106074e084fSml93401 } 107074e084fSml93401 1087c478bd9Sstevel@tonic-gate int 1097c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 1107c478bd9Sstevel@tonic-gate { 1117c478bd9Sstevel@tonic-gate int c; /* options character */ 1127c478bd9Sstevel@tonic-gate int type = 0; /* type of accounting */ 113074e084fSml93401 int modified = 0; /* have we modified any properties? */ 1147c478bd9Sstevel@tonic-gate acctconf_t ac; /* current configuration */ 1157c478bd9Sstevel@tonic-gate char *typestr = NULL; /* type of accounting argument string */ 1167c478bd9Sstevel@tonic-gate char *enabled = NULL; /* enabled resources string */ 1177c478bd9Sstevel@tonic-gate char *disabled = NULL; /* disabled resources string */ 1187c478bd9Sstevel@tonic-gate char *file = NULL; 1197c478bd9Sstevel@tonic-gate int Eflg = 0; 1207c478bd9Sstevel@tonic-gate int Dflg = 0; 1217c478bd9Sstevel@tonic-gate int rflg = 0; 122074e084fSml93401 int sflg = 0; 1237c478bd9Sstevel@tonic-gate int xflg = 0; 1247c478bd9Sstevel@tonic-gate int optcnt = 0; 1257c478bd9Sstevel@tonic-gate int state; 126074e084fSml93401 const char *fmri; /* FMRI for this instance */ 127074e084fSml93401 128074e084fSml93401 setup_privs(); 1297c478bd9Sstevel@tonic-gate 1307c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1317c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 1327c478bd9Sstevel@tonic-gate (void) setprogname(argv[0]); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) { 1357c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, OPTS)) != (int)EOF) { 1367c478bd9Sstevel@tonic-gate switch (c) { 1377c478bd9Sstevel@tonic-gate case 'd': 1387c478bd9Sstevel@tonic-gate disabled = optarg; 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate case 'e': 1417c478bd9Sstevel@tonic-gate enabled = optarg; 1427c478bd9Sstevel@tonic-gate break; 1437c478bd9Sstevel@tonic-gate case 'D': 1447c478bd9Sstevel@tonic-gate Dflg = 1; 1457c478bd9Sstevel@tonic-gate optcnt++; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case 'E': 1487c478bd9Sstevel@tonic-gate Eflg = 1; 1497c478bd9Sstevel@tonic-gate optcnt++; 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate case 'f': 1527c478bd9Sstevel@tonic-gate file = optarg; 1537c478bd9Sstevel@tonic-gate optcnt++; 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate case 'r': 1567c478bd9Sstevel@tonic-gate rflg = 1; 1577c478bd9Sstevel@tonic-gate optcnt++; 1587c478bd9Sstevel@tonic-gate break; 159074e084fSml93401 case 's': 160074e084fSml93401 sflg = 1; 1617c478bd9Sstevel@tonic-gate optcnt++; 1627c478bd9Sstevel@tonic-gate break; 1637c478bd9Sstevel@tonic-gate case 'x': 1647c478bd9Sstevel@tonic-gate xflg = 1; 1657c478bd9Sstevel@tonic-gate optcnt++; 1667c478bd9Sstevel@tonic-gate break; 1677c478bd9Sstevel@tonic-gate case '?': 1687c478bd9Sstevel@tonic-gate default: 1697c478bd9Sstevel@tonic-gate usage(); 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate } 172074e084fSml93401 173074e084fSml93401 /* 174074e084fSml93401 * Permanently give up euid 0, egid 0 and privileges we 175074e084fSml93401 * don't need for the specified options. 176074e084fSml93401 */ 177074e084fSml93401 if (!(file || sflg)) { 178074e084fSml93401 if (setreuid(getuid(), getuid()) == -1 || 179074e084fSml93401 setregid(getgid(), getgid()) == -1) 180074e084fSml93401 die(gettext("setreuid()/setregid() failed")); 181074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED, 182074e084fSml93401 PRIV_FILE_DAC_WRITE, NULL); 183074e084fSml93401 } 184074e084fSml93401 if (!(disabled || enabled || Dflg || Eflg || file || sflg || 185074e084fSml93401 xflg)) 186074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED, 187*da14cebeSEric Cheng PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL); 188074e084fSml93401 1897c478bd9Sstevel@tonic-gate if (optind < argc) { 1907c478bd9Sstevel@tonic-gate if (typestr != NULL) { 1917c478bd9Sstevel@tonic-gate warn(gettext("illegal argument -- %s\n"), 1927c478bd9Sstevel@tonic-gate argv[optind]); 1937c478bd9Sstevel@tonic-gate usage(); 1947c478bd9Sstevel@tonic-gate } else { 1957c478bd9Sstevel@tonic-gate typestr = argv[optind]; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate if (typestr != NULL) { 2007c478bd9Sstevel@tonic-gate if (strcmp(typestr, "process") == 0 || 2017c478bd9Sstevel@tonic-gate strcmp(typestr, "proc") == 0) 2027c478bd9Sstevel@tonic-gate type |= AC_PROC; 2037c478bd9Sstevel@tonic-gate else if (strcmp(typestr, "task") == 0) 2047c478bd9Sstevel@tonic-gate type |= AC_TASK; 2057c478bd9Sstevel@tonic-gate else if (strcmp(typestr, "flow") == 0) 2067c478bd9Sstevel@tonic-gate type |= AC_FLOW; 207*da14cebeSEric Cheng else if (strcmp(typestr, "net") == 0) 208*da14cebeSEric Cheng type |= AC_NET; 2097c478bd9Sstevel@tonic-gate else { 2107c478bd9Sstevel@tonic-gate warn(gettext("unknown accounting type -- %s\n"), 2117c478bd9Sstevel@tonic-gate typestr); 2127c478bd9Sstevel@tonic-gate usage(); 2137c478bd9Sstevel@tonic-gate } 2147c478bd9Sstevel@tonic-gate } else 215*da14cebeSEric Cheng type = AC_PROC | AC_TASK | AC_FLOW | AC_NET; 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate /* 218*da14cebeSEric Cheng * Drop the DL config privilege if we are not working with 219*da14cebeSEric Cheng * net. 220*da14cebeSEric Cheng */ 221*da14cebeSEric Cheng if ((type & AC_NET) == 0) { 222*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_PERMITTED, 223*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 224*da14cebeSEric Cheng } 225*da14cebeSEric Cheng /* 2267c478bd9Sstevel@tonic-gate * check for invalid options 2277c478bd9Sstevel@tonic-gate */ 2287c478bd9Sstevel@tonic-gate if (optcnt > 1) 2297c478bd9Sstevel@tonic-gate usage(); 2307c478bd9Sstevel@tonic-gate 231*da14cebeSEric Cheng /* 232*da14cebeSEric Cheng * XXX For AC_NET, enabled/disabled should only be "basic" or 233*da14cebeSEric Cheng * "extended" - need to check it here. 234*da14cebeSEric Cheng */ 235074e084fSml93401 if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg)) 2367c478bd9Sstevel@tonic-gate usage(); 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if ((file || xflg || Dflg || Eflg || enabled || disabled) && 2397c478bd9Sstevel@tonic-gate !typestr) { 2407c478bd9Sstevel@tonic-gate warn(gettext("accounting type must be specified\n")); 2417c478bd9Sstevel@tonic-gate usage(); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate if (rflg) { 2457c478bd9Sstevel@tonic-gate printgroups(type); 2467c478bd9Sstevel@tonic-gate return (E_SUCCESS); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate /* 250074e084fSml93401 * If no arguments have been passed then just print out the current 251074e084fSml93401 * state and exit. 2527c478bd9Sstevel@tonic-gate */ 2537c478bd9Sstevel@tonic-gate if (!enabled && !disabled && !file && 254074e084fSml93401 !Eflg && !rflg && !Dflg && !sflg && !xflg) { 255074e084fSml93401 aconf_print(stdout, type); 2567c478bd9Sstevel@tonic-gate return (E_SUCCESS); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 259074e084fSml93401 /* 260074e084fSml93401 * smf(5) start method. The FMRI to operate on is retrieved from the 261074e084fSml93401 * SMF_FMRI environment variable that the restarter provides. 262074e084fSml93401 */ 263074e084fSml93401 if (sflg) { 264074e084fSml93401 if ((fmri = getenv("SMF_FMRI")) != NULL) 265074e084fSml93401 return (aconf_setup(fmri)); 266074e084fSml93401 267074e084fSml93401 warn(gettext("-s option should only be invoked by smf(5)\n")); 2687c478bd9Sstevel@tonic-gate return (E_ERROR); 2697c478bd9Sstevel@tonic-gate } 2707c478bd9Sstevel@tonic-gate 271*da14cebeSEric Cheng assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW || 272*da14cebeSEric Cheng type == AC_NET); 273074e084fSml93401 274*da14cebeSEric Cheng if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID) 275074e084fSml93401 die(gettext("%s accounting cannot be configured in " 276074e084fSml93401 "non-global zones\n"), ac_type_name(type)); 277074e084fSml93401 278074e084fSml93401 fmri = aconf_type2fmri(type); 279074e084fSml93401 if (aconf_scf_init(fmri) == -1) 280074e084fSml93401 die(gettext("cannot connect to repository for %s\n"), fmri); 281074e084fSml93401 282074e084fSml93401 /* 283074e084fSml93401 * Since the sys_acct the privilege allows use of acctctl() regardless 284074e084fSml93401 * of the accounting type, we check the smf(5) authorizations granted 285074e084fSml93401 * to the user to determine whether the user is allowed to change the 286074e084fSml93401 * configuration for this particular accounting type. 287074e084fSml93401 */ 288074e084fSml93401 if (!aconf_have_smf_auths()) 289074e084fSml93401 die(gettext("insufficient authorization to change %s extended " 290074e084fSml93401 "accounting configuration\n"), ac_type_name(type)); 291074e084fSml93401 2927c478bd9Sstevel@tonic-gate if (xflg) { 2937c478bd9Sstevel@tonic-gate /* 2947c478bd9Sstevel@tonic-gate * Turn off the specified accounting and close its file 2957c478bd9Sstevel@tonic-gate */ 296*da14cebeSEric Cheng 297*da14cebeSEric Cheng /* 298*da14cebeSEric Cheng * Stop net logging before turning it off so that the last 299*da14cebeSEric Cheng * set of logs can be written. 300*da14cebeSEric Cheng */ 301*da14cebeSEric Cheng if (type & AC_NET) { 302*da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 303*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 304*da14cebeSEric Cheng (void) dladm_stop_usagelog(DLADM_LOGTYPE_FLOW); 305*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 306*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 307*da14cebeSEric Cheng } 3087c478bd9Sstevel@tonic-gate state = AC_OFF; 309074e084fSml93401 310074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 3117c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) 312074e084fSml93401 die(gettext("cannot disable %s accounting"), 313074e084fSml93401 ac_type_name(type)); 3147c478bd9Sstevel@tonic-gate if (acctctl(type | AC_FILE_SET, NULL, 0) == -1) 315074e084fSml93401 die(gettext("cannot close %s accounting file\n"), 316074e084fSml93401 ac_type_name(type)); 317074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 318074e084fSml93401 319074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) 320074e084fSml93401 die(gettext("cannot update %s property\n"), 321074e084fSml93401 AC_PROP_STATE); 322074e084fSml93401 if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1) 323074e084fSml93401 die(gettext("cannot update %s property\n"), 324074e084fSml93401 AC_PROP_FILE); 3257c478bd9Sstevel@tonic-gate modified++; 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if (enabled || disabled) { 3297c478bd9Sstevel@tonic-gate char *tracked, *untracked; 3307c478bd9Sstevel@tonic-gate ac_res_t *buf; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * Enable/disable resources 3347c478bd9Sstevel@tonic-gate */ 3357c478bd9Sstevel@tonic-gate if ((buf = malloc(AC_BUFSIZE)) == NULL) 3367c478bd9Sstevel@tonic-gate die(gettext("not enough memory\n")); 3377c478bd9Sstevel@tonic-gate (void) memset(buf, 0, AC_BUFSIZE); 3387c478bd9Sstevel@tonic-gate if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) { 3397c478bd9Sstevel@tonic-gate free(buf); 3407c478bd9Sstevel@tonic-gate die(gettext("cannot obtain list of resources\n")); 3417c478bd9Sstevel@tonic-gate } 342*da14cebeSEric Cheng if (disabled) { 343*da14cebeSEric Cheng /* 344*da14cebeSEric Cheng * Stop net logging before turning it off so that the 345*da14cebeSEric Cheng * last set of logs can be written. 346*da14cebeSEric Cheng */ 347*da14cebeSEric Cheng if (type & AC_NET) { 348*da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 349*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 350*da14cebeSEric Cheng (void) dladm_stop_usagelog(strncmp(disabled, 351*da14cebeSEric Cheng "basic", strlen("basic")) == 0 ? 352*da14cebeSEric Cheng DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW); 353*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 354*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 355*da14cebeSEric Cheng } 3567c478bd9Sstevel@tonic-gate str2buf(buf, disabled, AC_OFF, type); 357*da14cebeSEric Cheng } 3587c478bd9Sstevel@tonic-gate if (enabled) 3597c478bd9Sstevel@tonic-gate str2buf(buf, enabled, AC_ON, type); 360074e084fSml93401 361074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 3627c478bd9Sstevel@tonic-gate if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) { 3637c478bd9Sstevel@tonic-gate free(buf); 364074e084fSml93401 die(gettext("cannot enable/disable %s accounting " 365074e084fSml93401 "resources\n"), ac_type_name(type)); 3667c478bd9Sstevel@tonic-gate } 367074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 368074e084fSml93401 3697c478bd9Sstevel@tonic-gate tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type); 3707c478bd9Sstevel@tonic-gate untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type); 371074e084fSml93401 if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1) 372074e084fSml93401 die(gettext("cannot update %s property\n"), 373074e084fSml93401 AC_PROP_TRACKED); 374074e084fSml93401 if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1) 375074e084fSml93401 die(gettext("cannot update %s property\n"), 376074e084fSml93401 AC_PROP_UNTRACKED); 377*da14cebeSEric Cheng /* 378*da14cebeSEric Cheng * We will enable net logging after turning it on so that 379*da14cebeSEric Cheng * it can immediately start writing log. 380*da14cebeSEric Cheng */ 381*da14cebeSEric Cheng if (type & AC_NET && enabled != NULL) { 382*da14cebeSEric Cheng /* 383*da14cebeSEric Cheng * Default logging interval for AC_NET is 20. 384*da14cebeSEric Cheng * XXX need to find the right place to 385*da14cebeSEric Cheng * configure it. 386*da14cebeSEric Cheng */ 387*da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 388*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 389*da14cebeSEric Cheng (void) dladm_start_usagelog(strncmp(enabled, "basic", 390*da14cebeSEric Cheng strlen("basic")) == 0 ? DLADM_LOGTYPE_LINK : 391*da14cebeSEric Cheng DLADM_LOGTYPE_FLOW, 20); 392*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 393*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 394*da14cebeSEric Cheng } 3957c478bd9Sstevel@tonic-gate free(tracked); 3967c478bd9Sstevel@tonic-gate free(untracked); 3977c478bd9Sstevel@tonic-gate free(buf); 3987c478bd9Sstevel@tonic-gate modified++; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate if (file) { 4027c478bd9Sstevel@tonic-gate /* 4037c478bd9Sstevel@tonic-gate * Open new accounting file 4047c478bd9Sstevel@tonic-gate */ 405074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 406074e084fSml93401 if (open_exacct_file(file, type) == -1) 407074e084fSml93401 exit(E_ERROR); 408074e084fSml93401 if (aconf_set_string(AC_PROP_FILE, file) == -1) 409074e084fSml93401 die(gettext("cannot update %s property\n"), 410074e084fSml93401 AC_PROP_FILE); 4117c478bd9Sstevel@tonic-gate state = AC_ON; 412074e084fSml93401 4137c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) 414074e084fSml93401 die(gettext("cannot enable %s accounting"), 415074e084fSml93401 ac_type_name(type)); 416074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 417074e084fSml93401 418074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) 419074e084fSml93401 die(gettext("cannot update %s property\n"), 420074e084fSml93401 AC_PROP_STATE); 4217c478bd9Sstevel@tonic-gate modified++; 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate if (Dflg) { 4257c478bd9Sstevel@tonic-gate /* 4267c478bd9Sstevel@tonic-gate * Disable accounting 4277c478bd9Sstevel@tonic-gate */ 428*da14cebeSEric Cheng 429*da14cebeSEric Cheng /* 430*da14cebeSEric Cheng * Stop net logging before turning it off so that the last 431*da14cebeSEric Cheng * set of logs can be written. 432*da14cebeSEric Cheng */ 433*da14cebeSEric Cheng if (type & AC_NET) { 434*da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 435*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 436*da14cebeSEric Cheng (void) dladm_stop_usagelog(DLADM_LOGTYPE_FLOW); 437*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 438*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 439*da14cebeSEric Cheng } 4407c478bd9Sstevel@tonic-gate state = AC_OFF; 441074e084fSml93401 442074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 4437c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) 444074e084fSml93401 die(gettext("cannot disable %s accounting"), 445074e084fSml93401 ac_type_name(type)); 446074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 447074e084fSml93401 448074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1) 449074e084fSml93401 die(gettext("cannot update %s property\n"), 450074e084fSml93401 AC_PROP_STATE); 4517c478bd9Sstevel@tonic-gate modified++; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate if (Eflg) { 4557c478bd9Sstevel@tonic-gate /* 4567c478bd9Sstevel@tonic-gate * Enable accounting 4577c478bd9Sstevel@tonic-gate */ 4587c478bd9Sstevel@tonic-gate state = AC_ON; 459074e084fSml93401 460074e084fSml93401 (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 4617c478bd9Sstevel@tonic-gate if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1) 462074e084fSml93401 die(gettext("cannot enable %s accounting"), 463074e084fSml93401 ac_type_name(type)); 464074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL); 465074e084fSml93401 466074e084fSml93401 if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1) 467074e084fSml93401 die(gettext("cannot update %s property\n"), 468074e084fSml93401 AC_PROP_STATE); 4697c478bd9Sstevel@tonic-gate modified++; 470*da14cebeSEric Cheng if (type & AC_NET) { 471*da14cebeSEric Cheng /* 472*da14cebeSEric Cheng * Default logging interval for AC_NET is 20, 473*da14cebeSEric Cheng * XXX need to find the right place to configure it. 474*da14cebeSEric Cheng */ 475*da14cebeSEric Cheng (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 476*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 477*da14cebeSEric Cheng (void) dladm_start_usagelog(DLADM_LOGTYPE_FLOW, 20); 478*da14cebeSEric Cheng (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 479*da14cebeSEric Cheng PRIV_SYS_DL_CONFIG, NULL); 480*da14cebeSEric Cheng } 4817c478bd9Sstevel@tonic-gate } 482074e084fSml93401 (void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL); 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate if (modified) { 485074e084fSml93401 char *smf_state; 4867c478bd9Sstevel@tonic-gate 487074e084fSml93401 if (aconf_save() == -1) 488074e084fSml93401 die(gettext("cannot save %s accounting " 489074e084fSml93401 "configuration\n"), ac_type_name(type)); 490074e084fSml93401 491074e084fSml93401 /* 492074e084fSml93401 * Enable or disable the instance depending on the effective 493074e084fSml93401 * configuration. If the effective configuration results in 494074e084fSml93401 * extended accounting being 'on', the instance is enabled so 495074e084fSml93401 * the configuration is applied at the next boot. 496074e084fSml93401 */ 497074e084fSml93401 smf_state = smf_get_state(fmri); 498074e084fSml93401 aconf_init(&ac, type); 499074e084fSml93401 500074e084fSml93401 if (ac.state == AC_ON || 501074e084fSml93401 strcmp(ac.file, AC_STR_NONE) != 0 || 502074e084fSml93401 strcmp(ac.tracked, AC_STR_NONE) != 0) { 503074e084fSml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0) 504074e084fSml93401 if (smf_enable_instance(fmri, 0) == -1) 505074e084fSml93401 die(gettext("cannot enable %s\n"), 506074e084fSml93401 fmri); 507074e084fSml93401 } else { 508074e084fSml93401 if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0) 509074e084fSml93401 if (smf_disable_instance(fmri, 0) == -1) 510074e084fSml93401 die(gettext("cannot disable %s\n"), 511074e084fSml93401 fmri); 512074e084fSml93401 } 513074e084fSml93401 free(smf_state); 514074e084fSml93401 } 515074e084fSml93401 aconf_scf_fini(); 5167c478bd9Sstevel@tonic-gate return (E_SUCCESS); 5177c478bd9Sstevel@tonic-gate } 518