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 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 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 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