Пример #1
0
void
audit_ftpd_logout(void)
{
	int	rd;		/* audit record descriptor */
	uid_t	euid;
	gid_t	egid;
	uid_t	uid;
	gid_t	gid;
	pid_t	pid;
	struct auditinfo_addr info;

	if (cannot_audit(0)) {
		return;
	}

	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);

	/* see if terminal id already set */
	if (getaudit_addr(&info, sizeof (info)) < 0) {
		perror("getaudit");
	}

	/* determine if we're preselected */
	if (au_preselect(AUE_ftpd_logout, &info.ai_mask, AU_PRS_SUCCESS,
	    AU_PRS_USECACHE) == 0) {
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT,
		    NULL);
		return;
	}

	euid = geteuid();
	egid = getegid();
	uid = getuid();
	gid = getgid();
	pid = getpid();

	rd = au_open();

	/* add subject token */
	(void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
	    egid, uid, gid, pid, pid, &info.ai_termid));

	if (is_system_labeled())
		(void) au_write(rd, au_to_mylabel());

	/* add return token */
	errno = 0;
#ifdef _LP64
	(void) au_write(rd, au_to_return64(0, (int64_t)0));
#else
	(void) au_write(rd, au_to_return32(0, (int32_t)0));
#endif

	/* write audit record */
	if (au_close(rd, 1, AUE_ftpd_logout) < 0) {
		(void) au_close(rd, 0, 0);
	}
	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT, NULL);
}
Пример #2
0
/*
 * To successfully handle some of link/root requests, some
 * file system operations need to be performed. These operations
 * should take place on behalf of the connected user (typically
 * Administrator) and to do so we need to have an infrastructure
 * in place so that smbd can act as a client and sends request to
 * the kernel. Right now, we lack this infrastructure, so we make
 * a compromise by temporarily enabling some privileges for smbd
 * to be able to fulfill various link/root requests.
 */
void
dfs_setpriv(priv_op_t op)
{
	(void) priv_set(op, PRIV_EFFECTIVE,
	    PRIV_FILE_DAC_READ,
	    PRIV_FILE_DAC_WRITE,
	    PRIV_FILE_DAC_EXECUTE,
	    PRIV_FILE_DAC_SEARCH, NULL);
}
Пример #3
0
const char *
get_ldap_secret()
{
FILE	*f;
size_t	 len;

	/* We require DAC_READ to open the secret file. */
	if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL) == -1) {
		perror("get_ldap_secret: priv failure\n");
		return NULL;
	}

	if ((f = fopen(SECRET, "r")) == NULL) {
		perror("cannot open LDAP secret");
		goto err;
	}

	if (priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, NULL) == -1) {
		(void) fprintf(stderr, "get_ldap_secret: priv failure\n");
		_exit(1);
	}

	if (fgets(ldap_secret, sizeof ldap_secret, f) == NULL) {
		perror("cannot read LDAP secret");
		goto err;
	}

	(void) fclose(f);

	len = strlen(ldap_secret);
	if (len && ldap_secret[len - 1] == '\n')
		ldap_secret[len - 1] = '\0';

	return ldap_secret;

err:
	if (f)
		(void) fclose(f);
	return NULL;
}
Пример #4
0
static void
setup_privs()
{
	priv_set_t *privset;

	if (seteuid(getuid()) == -1 || setegid(getgid()) == -1)
		die(gettext("seteuid()/setegid() failed"));

	/*
	 * Add our privileges and remove unneeded 'basic' privileges from the
	 * permitted set.
	 */
	if ((privset = priv_str_to_set("basic", ",", NULL)) == NULL)
		die(gettext("cannot setup privileges"));

	(void) priv_addset(privset, PRIV_SYS_ACCT);
	(void) priv_addset(privset, PRIV_FILE_DAC_WRITE);
	(void) priv_addset(privset, PRIV_SYS_DL_CONFIG);
	(void) priv_delset(privset, PRIV_FILE_LINK_ANY);
	(void) priv_delset(privset, PRIV_PROC_EXEC);
	(void) priv_delset(privset, PRIV_PROC_FORK);
	(void) priv_delset(privset, PRIV_PROC_INFO);
	(void) priv_delset(privset, PRIV_PROC_SESSION);
	priv_inverse(privset);
	if (setppriv(PRIV_OFF, PRIV_PERMITTED, privset) == -1)
		die(gettext("cannot setup privileges"));
	priv_freeset(privset);

	/*
	 * Clear the Inheritable and Limit sets.
	 */
	if ((privset = priv_allocset()) == NULL)
		die(gettext("cannot setup privileges"));
	priv_emptyset(privset);
	if (setppriv(PRIV_SET, PRIV_INHERITABLE, privset) == -1 ||
	    setppriv(PRIV_SET, PRIV_LIMIT, privset) == -1)
		die(gettext("cannot setup privileges"));

	/*
	 * Turn off the sys_acct, file_dac_write and dl_config privileges
	 * until needed.
	 */
	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE,
	    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);
}
Пример #5
0
static int
daemonSetupPrivs(void)
{
    chown("/var/run/libvirt", SYSTEM_UID, SYSTEM_UID);

    if (__init_daemon_priv(PU_RESETGROUPS | PU_CLEARLIMITSET,
                           SYSTEM_UID, SYSTEM_UID, PRIV_XVM_CONTROL, NULL)) {
        VIR_ERROR(_("additional privileges are required"));
        return -1;
    }

    if (priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_FILE_LINK_ANY, PRIV_PROC_INFO,
                 PRIV_PROC_SESSION, PRIV_PROC_EXEC, PRIV_PROC_FORK, NULL)) {
        VIR_ERROR(_("failed to set reduced privileges"));
        return -1;
    }

    return 0;
}
Пример #6
0
static int
rmvolmgr(int argc, char **argv)
{
	const char	*opts = "chnsv";
	DBusError	error;
	boolean_t	daemonize;
	rmm_error_t	rmm_error;
	int		c;

	while ((c = getopt(argc, argv, opts)) != EOF) {
		switch (c) {
		case 'c':
			opt_c = B_TRUE;
			break;
		case 'n':
			opt_n = B_TRUE;
			break;
		case 's':
			opt_s = B_TRUE;
			break;
		case 'v':
			rmm_debug = 1;
			break;
		case '?':
		case 'h':
			usage();
			return (0);
		default:
			usage();
			return (1);
		}
	}

	if (opt_s) {
		if (geteuid() != 0) {
			(void) fprintf(stderr,
			    gettext("system instance must have euid 0\n"));
			return (1);
		}

		get_smf_properties();

		if (opt_c) {
			rmm_vold_actions_enabled = B_FALSE;
		}
		if (opt_n) {
			rmm_vold_mountpoints_enabled = B_FALSE;
		}


		/*
		 * Drop unused privileges. Remain root for HAL interaction
		 * and to create legacy symlinks.
		 *
		 * Need PRIV_FILE_DAC_WRITE to write to users'
		 * /tmp/.removable/notify* files.
		 */
		if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET,
		    0, 0,
		    rmm_vold_actions_enabled ? PRIV_FILE_DAC_WRITE : NULL,
		    NULL) == -1) {
			(void) fprintf(stderr,
			    gettext("failed to drop privileges"));
			return (1);
		}
		/* basic privileges we don't need */
		(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_PROC_EXEC,
		    PRIV_PROC_INFO, PRIV_FILE_LINK_ANY, PRIV_PROC_SESSION,
		    NULL);

	} else {
		if (opt_c) {
			rmm_vold_actions_enabled = B_FALSE;
		}
		if (opt_n) {
			rmm_vold_mountpoints_enabled = B_FALSE;
		}
	}

	daemonize = (getenv("RMVOLMGR_NODAEMON") == NULL);

	if (daemonize && daemon(0, 0) < 0) {
		dprintf("daemonizing failed: %s", strerror(errno));
		return (1);
	}

	if (opt_s) {
		__fini_daemon_priv(PRIV_PROC_FORK, NULL);
	}

	/*
	 * signal mainloop integration using pipes
	 */
	if (pipe(sigexit_pipe) != 0) {
		dprintf("pipe failed %s\n", strerror(errno));
		return (1);
	}
	sigexit_ioch = g_io_channel_unix_new(sigexit_pipe[0]);
	if (sigexit_ioch == NULL) {
		dprintf("g_io_channel_unix_new failed\n");
		return (1);
	}
	g_io_add_watch(sigexit_ioch, G_IO_IN, sigexit_ioch_func, NULL);
	signal(SIGTERM, sigexit);
	signal(SIGINT, sigexit);
	signal(SIGHUP, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);

	if ((hal_ctx = rmm_hal_init(rmm_device_added, rmm_device_removed,
	    rmm_property_modified, rmm_device_condition,
	    &error, &rmm_error)) == NULL) {
		dbus_error_free(&error);
		return (1);
	}

	/* user instance should claim devices */
	if (!opt_s) {
		if (!rmm_hal_claim_branch(hal_ctx, HAL_BRANCH_LOCAL)) {
			(void) fprintf(stderr,
			    gettext("cannot claim branch\n"));
			return (1);
		}
	}

	rmm_mount_all();

	if ((mainloop = g_main_loop_new(NULL, B_FALSE)) == NULL) {
		dprintf("Cannot create main loop\n");
		return (1);
	}

	g_main_loop_run(mainloop);

	return (0);
}
Пример #7
0
int
main(int argc, char **argv)
{
	int	s;
	int	c;

	(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define	TEXT_DOMAIN "SYS_TEST"
#endif
	static const char daemon_dir[] = DAEMON_DIR;

	(void) textdomain(TEXT_DOMAIN);

	while ((c = getopt(argc, argv, ":V?d(debug)")) != -1) {
		switch ((char)c) {
		case '?': Usage(argv[0]);
			/* not reached */
			break;
		case 'V': print_version(argv[0]);
			/* not reached */
			break;
		case 'd': ilbd_enable_debug();
			break;
		default: Usage(argv[0]);
			/* not reached */
			break;
		}
	}

	/*
	 * Whenever the daemon starts, it needs to start with a clean
	 * slate in the kernel. We need sys_ip_config privilege for
	 * this.
	 */
	ilbd_reset_kernel_state();

	/* Increase the limit on the number of file descriptors. */
	set_rlim();

	/*
	 * ilbd daemon starts off as root, just so it can create
	 * /var/run/daemon if one does not exist. After that is done
	 * the daemon switches to "daemon" uid. This is similar to what
	 * rpcbind does.
	 */
	if (mkdir(daemon_dir, DAEMON_DIR_MODE) == 0 || errno == EEXIST) {
		(void) chmod(daemon_dir, DAEMON_DIR_MODE);
		(void) chown(daemon_dir, DAEMON_UID, DAEMON_GID);
	} else {
		perror("main: mkdir failed");
		exit(errno);
	}
	/*
	 * Now lets switch ilbd as uid = daemon, gid = daemon with a
	 * trimmed down privilege set
	 */
	if (__init_daemon_priv(PU_RESETGROUPS | PU_LIMITPRIVS | PU_INHERITPRIVS,
	    DAEMON_UID, DAEMON_GID, PRIV_PROC_OWNER, PRIV_PROC_AUDIT,
	    PRIV_NET_ICMPACCESS, PRIV_SYS_IP_CONFIG, NULL) == -1) {
		(void) fprintf(stderr, "Insufficient privileges\n");
		exit(EXIT_FAILURE);
	}

	/*
	 * Opens a PF_UNIX socket to the client. No privilege needed
	 * for this.
	 */
	s = ilbd_create_client_socket();

	/*
	 * Daemonify if ilbd is not running with -d option
	 * Need proc_fork privilege for this
	 */
	if (!is_debugging_on()) {
		logdebug("daemonizing...");
		if (daemon(0, 0) != 0) {
			logperror("daemon failed");
			exit(EXIT_FAILURE);
		}
	}
	(void) priv_set(PRIV_OFF, PRIV_INHERITABLE, PRIV_PROC_OWNER,
	    PRIV_PROC_AUDIT, NULL);

	/* if daemonified then set up syslog */
	if (!is_debugging_on())
		openlog("ilbd", LOG_PID, LOG_DAEMON);

	i_ilbd_setup_lists();

	main_loop(s);

	/*
	 * if we come here, then we experienced an error or a shutdown
	 * indicator, so clean up after ourselves.
	 */
	logdebug("main(): terminating");

	(void) remove(SOCKET_PATH);
	ilbd_reset_kernel_state();

	return (0);
}
Пример #8
0
int
main(int argc, char *argv[])
{
	int c;			/* options character */
	int type = 0;		/* type of accounting */
	int modified = 0;	/* have we modified any properties? */
	acctconf_t ac;		/* current configuration */
	char *typestr = NULL;	/* type of accounting argument string */
	char *enabled = NULL;	/* enabled resources string */
	char *disabled = NULL;	/* disabled resources string */
	char *file = NULL;
	int Eflg = 0;
	int Dflg = 0;
	int rflg = 0;
	int sflg = 0;
	int xflg = 0;
	int optcnt = 0;
	int state;
	const char *fmri;	/* FMRI for this instance */
	int err = 0;

	setup_privs();

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);
	(void) setpname(argv[0]);

	for (; optind < argc; optind++) {
		while ((c = getopt(argc, argv, OPTS)) != (int)EOF) {
			switch (c) {
			case 'd':
				disabled = optarg;
				break;
			case 'e':
				enabled = optarg;
				break;
			case 'D':
				Dflg = 1;
				optcnt++;
				break;
			case 'E':
				Eflg = 1;
				optcnt++;
				break;
			case 'f':
				file = optarg;
				optcnt++;
				break;
			case 'r':
				rflg = 1;
				optcnt++;
				break;
			case 's':
				sflg = 1;
				optcnt++;
				break;
			case 'x':
				xflg = 1;
				optcnt++;
				break;
			case '?':
			default:
				usage();
			}
		}

		/*
		 * Permanently give up euid 0, egid 0 and privileges we
		 * don't need for the specified options.
		 */
		if (!(file || sflg)) {
			if (setreuid(getuid(), getuid()) == -1 ||
			    setregid(getgid(), getgid()) == -1)
				die(gettext("setreuid()/setregid() failed"));
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_FILE_DAC_WRITE, NULL);
		}
		if (!(disabled || enabled || Dflg || Eflg || file || sflg ||
		    xflg))
			(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
			    PRIV_SYS_ACCT, PRIV_SYS_DL_CONFIG, NULL);

		if (optind < argc) {
			if (typestr != NULL) {
				warn(gettext("illegal argument -- %s\n"),
				    argv[optind]);
				usage();
			} else {
				typestr = argv[optind];
			}
		}
	}
	if (typestr != NULL) {
		if (strcmp(typestr, "process") == 0 ||
		    strcmp(typestr, "proc") == 0)
			type |= AC_PROC;
		else if (strcmp(typestr, "task") == 0)
			type |= AC_TASK;
		else if (strcmp(typestr, "flow") == 0)
			type |= AC_FLOW;
		else if (strcmp(typestr, "net") == 0)
			type |= AC_NET;
		else {
			warn(gettext("unknown accounting type -- %s\n"),
			    typestr);
			usage();
		}
	} else
		type = AC_PROC | AC_TASK | AC_FLOW | AC_NET;

	/*
	 * Drop the DL config privilege if we are not working with
	 * net.
	 */
	if ((type & AC_NET) == 0) {
		(void) priv_set(PRIV_OFF, PRIV_PERMITTED,
		    PRIV_SYS_DL_CONFIG, NULL);
	}
	/*
	 * check for invalid options
	 */
	if (optcnt > 1)
		usage();

	/*
	 * XXX For AC_NET, enabled/disabled should only be "basic" or
	 * "extended" - need to check it here.
	 */
	if ((enabled || disabled) && (rflg || Dflg || sflg || xflg || Eflg))
		usage();

	if ((file || xflg || Dflg || Eflg || enabled || disabled) &&
	    !typestr) {
		warn(gettext("accounting type must be specified\n"));
		usage();
	}

	if (rflg) {
		printgroups(type);
		return (E_SUCCESS);
	}

	/*
	 * If no arguments have been passed then just print out the current
	 * state and exit.
	 */
	if (!enabled && !disabled && !file &&
	    !Eflg && !rflg && !Dflg && !sflg && !xflg) {
		aconf_print(stdout, type);
		return (E_SUCCESS);
	}

	/* Open the libdladm handle */
	if (dladm_open(&dld_handle) != DLADM_STATUS_OK)
		die(gettext("failed to open dladm handle\n"));

	/*
	 * smf(5) start method.  The FMRI to operate on is retrieved from the
	 * SMF_FMRI environment variable that the restarter provides.
	 */
	if (sflg) {
		if ((fmri = getenv("SMF_FMRI")) != NULL) {
			int ret = aconf_setup(fmri);
			dladm_close(dld_handle);
			return (ret);
		}

		die(gettext("-s option should only be invoked by smf(5)\n"));
	}

	assert(type == AC_PROC || type == AC_TASK || type == AC_FLOW ||
	    type == AC_NET);

	if ((type == AC_FLOW || type == AC_NET) && getzoneid() != GLOBAL_ZONEID)
		die(gettext("%s accounting cannot be configured in "
		    "non-global zones\n"), ac_type_name(type));

	fmri = aconf_type2fmri(type);
	if (aconf_scf_init(fmri) == -1)
		die(gettext("cannot connect to repository for %s\n"), fmri);

	/*
	 * Since the sys_acct the privilege allows use of acctctl() regardless
	 * of the accounting type, we check the smf(5) authorizations granted
	 * to the user to determine whether the user is allowed to change the
	 * configuration for this particular accounting type.
	 */
	if (!aconf_have_smf_auths())
		die(gettext("insufficient authorization to change %s extended "
		    "accounting configuration\n"), ac_type_name(type));

	if (xflg) {
		/*
		 * Turn off the specified accounting and close its file
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging network "
				    "information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		if (acctctl(type | AC_FILE_SET, NULL, 0) == -1)
			die(gettext("cannot close %s accounting file\n"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		if (aconf_set_string(AC_PROP_FILE, AC_STR_NONE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		modified++;
	}

	if (enabled || disabled) {
		char *tracked, *untracked;
		ac_res_t *buf;

		/*
		 * Enable/disable resources
		 */
		if ((buf = malloc(AC_BUFSIZE)) == NULL)
			die(gettext("not enough memory\n"));
		(void) memset(buf, 0, AC_BUFSIZE);
		if (acctctl(type | AC_RES_GET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot obtain list of resources\n"));
		}
		if (disabled) {
			/*
			 * Stop net logging before turning it off so that the
			 * last set of logs can be written.
			 */
			if (type & AC_NET) {
				(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				err = dladm_stop_usagelog(dld_handle,
				    strcmp(disabled, "basic") == 0 ?
				    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW);
				(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
				    PRIV_SYS_DL_CONFIG, NULL);
				if (err != DLADM_STATUS_OK) {
					die(gettext("failed to stop logging "
					    "network information, error %d\n"),
					    errno);
				}
			}
			str2buf(buf, disabled, AC_OFF, type);
		} else if (enabled) {
			str2buf(buf, enabled, AC_ON, type);
		}
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_RES_SET, buf, AC_BUFSIZE) == -1) {
			free(buf);
			die(gettext("cannot enable/disable %s accounting "
			    "resources\n"), ac_type_name(type));
		}
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		tracked = buf2str(buf, AC_BUFSIZE, AC_ON, type);
		untracked = buf2str(buf, AC_BUFSIZE, AC_OFF, type);
		if (aconf_set_string(AC_PROP_TRACKED, tracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_TRACKED);
		if (aconf_set_string(AC_PROP_UNTRACKED, untracked) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_UNTRACKED);
		free(tracked);
		free(untracked);
		free(buf);
		modified++;
	}

	if (file) {
		/*
		 * Open new accounting file
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (open_exacct_file(file, type) == -1) {
			dladm_close(dld_handle);
			exit(E_ERROR);
		}
		if (aconf_set_string(AC_PROP_FILE, file) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_FILE);
		state = AC_ON;

		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	/*
	 * Let's get network logging started. We do this after turning on
	 * accounting and opening the file so that we can start writing
	 * immediately.
	 */
	if (enabled && (type & AC_NET)) {
		/*
		 * Default logging interval for AC_NET is
		 * ACCTADM_NET_LOG_INTERVAL.
		 */
		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		err = dladm_start_usagelog(dld_handle,
		    strcmp(enabled, "basic") == 0 ?
		    DLADM_LOGTYPE_LINK : DLADM_LOGTYPE_FLOW,
		    ACCTADM_NET_LOG_INTERVAL);
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
		    PRIV_SYS_DL_CONFIG, NULL);
		if (err != DLADM_STATUS_OK) {
			die(gettext("failed to start logging "
			    "network information, error %d\n"),
			    errno);
		}
	}

	if (Dflg) {
		/*
		 * Disable accounting
		 */

		/*
		 * Stop net logging before turning it off so that the last
		 * set of logs can be written.
		 */
		if (type & AC_NET) {
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_stop_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to stop logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_OFF;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot disable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_FALSE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}

	if (Eflg) {
		/*
		 * Enable accounting
		 */

		/*
		 * Let's get network logging started.
		 */
		if (type & AC_NET) {
			/*
			 * Default logging interval for AC_NET is
			 * ACCTADM_NET_LOG_INTERVAL.
			 */
			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			err = dladm_start_usagelog(dld_handle,
			    DLADM_LOGTYPE_FLOW, ACCTADM_NET_LOG_INTERVAL);
			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
			    PRIV_SYS_DL_CONFIG, NULL);
			if (err != DLADM_STATUS_OK) {
				die(gettext("failed to start logging "
				    "network information, error %d\n"), errno);
			}
		}
		state = AC_ON;

		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);
		if (acctctl(type | AC_STATE_SET, &state, sizeof (int)) == -1)
			die(gettext("cannot enable %s accounting"),
			    ac_type_name(type));
		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_SYS_ACCT, NULL);

		if (aconf_set_bool(AC_PROP_STATE, B_TRUE) == -1)
			die(gettext("cannot update %s property\n"),
			    AC_PROP_STATE);
		modified++;
	}
	(void) priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_SYS_ACCT, NULL);

	if (modified) {
		char *smf_state;

		if (aconf_save() == -1)
			die(gettext("cannot save %s accounting "
			    "configuration\n"), ac_type_name(type));

		/*
		 * Enable or disable the instance depending on the effective
		 * configuration.  If the effective configuration results in
		 * extended accounting being 'on', the instance is enabled so
		 * the configuration is applied at the next boot.
		 */
		smf_state = smf_get_state(fmri);
		aconf_init(&ac, type);

		if (ac.state == AC_ON ||
		    strcmp(ac.file, AC_STR_NONE) != 0 ||
		    strcmp(ac.tracked, AC_STR_NONE) != 0) {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) != 0)
				if (smf_enable_instance(fmri, 0) == -1)
					die(gettext("cannot enable %s\n"),
					    fmri);
		} else {
			if (strcmp(smf_state, SCF_STATE_STRING_ONLINE) == 0)
				if (smf_disable_instance(fmri, 0) == -1)
					die(gettext("cannot disable %s\n"),
					    fmri);
		}
		free(smf_state);
	}
	aconf_scf_fini();
	dladm_close(dld_handle);
	return (E_SUCCESS);
}