changeset 12930:32a41a5f8110

PSARC/2009/636 Obsolete getacinfo(3bsm) PSARC/2009/642 audit_control(4) EOL and removal PSARC/2010/218 Audit subsystem Rights Profiles PSARC/2010/220 svc:/system/auditset service 6875456 Solaris Audit configuration in SMF - phase 2 (PSARC/2009/636, PSARC/2009/642) 6942035 audit_binfile(5) leaves unfinished audit logs. 6942041 auditd(1) says "auditd refreshed" on startup. 6943275 audit_remote(5) leaks memory on audit service refresh 6955077 adt_get_mask_from_user() should regard _SC_GETPW_R_SIZE_MAX 6955117 $SRC/lib/libbsm/common/audit_ftpd.c shouldn't hardcode the lenght of usernames (8) 6956169 adt_audit_state() returns non-boolean values
author Jan Friedel <Jan.Friedel@Sun.COM>
date Tue, 27 Jul 2010 14:38:47 +0200
parents a80abc0db3a2
children db25553c7f2e
files exception_lists/interface_cmp usr/src/cmd/Makefile usr/src/cmd/audit/Makefile usr/src/cmd/audit/audit.c usr/src/cmd/audit_warn/audit_warn.sh usr/src/cmd/auditconfig/Makefile usr/src/cmd/auditconfig/audit_scf.c usr/src/cmd/auditconfig/audit_scf.h usr/src/cmd/auditconfig/audit_scf_shared.c usr/src/cmd/auditconfig/auditconfig.c usr/src/cmd/auditconfig/auditconfig_impl.h usr/src/cmd/auditd/Makefile usr/src/cmd/auditd/audit_sig_infc.h usr/src/cmd/auditd/auditd.c usr/src/cmd/auditd/auditd.xml usr/src/cmd/auditd/doorway.c usr/src/cmd/auditd/plugin.h usr/src/cmd/auditd/svc-auditd usr/src/cmd/auditrecord/audit_record_attr.txt usr/src/cmd/auditset/Makefile usr/src/cmd/auditset/auditset.xml usr/src/cmd/auditset/svc-auditset.c usr/src/head/secdb.h usr/src/lib/auditd_plugins/binfile/binfile.c usr/src/lib/auditd_plugins/remote/audit_remote.c usr/src/lib/libbc/libc/gen/common/getacinfo.c usr/src/lib/libbc/sparc/Makefile usr/src/lib/libbsm/Makefile usr/src/lib/libbsm/Makefile.com usr/src/lib/libbsm/audit_control.txt usr/src/lib/libbsm/audit_event.txt usr/src/lib/libbsm/common/adt.c usr/src/lib/libbsm/common/au_usermask.c usr/src/lib/libbsm/common/audit_ftpd.c usr/src/lib/libbsm/common/audit_plugin.c usr/src/lib/libbsm/common/audit_policy.h usr/src/lib/libbsm/common/audit_rexd.c usr/src/lib/libbsm/common/audit_rexecd.c usr/src/lib/libbsm/common/audit_rshd.c usr/src/lib/libbsm/common/audit_scf.c usr/src/lib/libbsm/common/audit_scf.h usr/src/lib/libbsm/common/getacinfo.c usr/src/lib/libbsm/common/getacval.c usr/src/lib/libbsm/common/getfaudflgs.c usr/src/lib/libbsm/common/libbsm.h usr/src/lib/libbsm/common/llib-lbsm usr/src/lib/libbsm/common/mapfile-vers usr/src/lib/libsecdb/auth_attr.txt usr/src/lib/libsecdb/common/mapfile-vers usr/src/lib/libsecdb/common/secdb.c usr/src/lib/libsecdb/exec_attr.txt usr/src/lib/libsecdb/help/auths/AuditConfig.html usr/src/lib/libsecdb/help/auths/AuditHeader.html usr/src/lib/libsecdb/help/auths/AuditRead.html usr/src/lib/libsecdb/help/auths/Makefile usr/src/lib/libsecdb/help/auths/SmfManageAudit.html usr/src/lib/libsecdb/help/auths/SmfValueAudit.html usr/src/lib/libsecdb/help/profiles/Makefile usr/src/lib/libsecdb/help/profiles/RtAuditCfg.html usr/src/lib/libsecdb/help/profiles/RtAuditCtrl.html usr/src/lib/libsecdb/help/profiles/RtAuditReview.html usr/src/lib/libsecdb/prof_attr.txt usr/src/pkg/manifests/SUNWcs.mf usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf usr/src/uts/common/c2/audit.h usr/src/uts/common/c2/audit_event.c usr/src/uts/common/c2/audit_io.c usr/src/uts/common/c2/audit_kernel.h usr/src/uts/common/c2/audit_kevents.h usr/src/uts/common/syscall/auditsys.c
diffstat 70 files changed, 3463 insertions(+), 3442 deletions(-) [+]
line wrap: on
line diff
--- a/exception_lists/interface_cmp	Tue Jul 27 16:58:46 2010 +0800
+++ b/exception_lists/interface_cmp	Tue Jul 27 14:38:47 2010 +0200
@@ -62,6 +62,14 @@
 DELSYM	^(endauuser|getauuserent|getauusernam|setauuser)$	\
 	^SUNW_(0\.[7-8]|1\.[1-2])$	\
 	^MACH(lib)/libbsm\.so\.1$
+#
+# - Removed interfaces: setac, getacna, getacmin, getacflg, getacdir, endac
+#	6875456 Solaris Audit configuration in SMF - phase 2
+#		(PSARC/2009/636, PSARC/2009/642)
+#
+DELSYM	^(setac|getacna|getacmin|getacflg|getacdir|endac)$	\
+	^SUNW_(0\.[7-8]|1\.[1-2])$	\
+	^MACH(lib)/libbsm\.so\.1$
 
 
 ## libmalloc / libmapmalloc
--- a/usr/src/cmd/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -515,8 +515,10 @@
 	asa		\
 	audio		\
 	audit		\
+	auditconfig	\
 	auditd		\
 	auditrecord	\
+	auditset	\
 	auths		\
 	autopush	\
 	avs		\
@@ -799,6 +801,7 @@
 	auditd		\
 	auditrecord	\
 	auditreduce	\
+	auditset	\
 	auditstat	\
 	praudit		\
 	bsmconv		\
--- a/usr/src/cmd/audit/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/audit/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 PROG = audit
@@ -32,13 +31,13 @@
 
 LDLIBS += -lbsm -lsecdb -lscf 
 
-AUDITD = ../auditd
+LIBBSM = $(SRC)/lib/libbsm/common
 
 OBJS = audit.o
 SRCS = $(OBJS:.o=.c)
 MSGFILES = $(SRCS)
 
-CPPFLAGS += -I$(AUDITD)
+CPPFLAGS += -I$(LIBBSM)
 
 .KEEP_STATE:
 
--- a/usr/src/cmd/audit/audit.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/audit/audit.c	Tue Jul 27 14:38:47 2010 +0200
@@ -30,6 +30,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/file.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <signal.h>
@@ -38,8 +39,8 @@
 #include <bsm/audit.h>
 #include <bsm/libbsm.h>
 #include <locale.h>
-#include <audit_sig_infc.h>
 #include <zone.h>
+#include <audit_scf.h>
 
 #if !defined(TEXT_DOMAIN)
 #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
@@ -49,14 +50,16 @@
 
 /* GLOBALS */
 static char	*progname = "audit";
-static char	*usage = "audit [-n] | [-s] | [-t] | [-v filepath]";
+static char	*usage = "audit [-n] | [-s] | [-t] | [-v]";
 static int	silent = 0;
 
 static void	display_smf_error();
 
-static boolean_t is_audit_control_ok(char *);	/* file validation  */
+static boolean_t is_audit_config_ok();		/* config validation  */
 static boolean_t is_valid_zone(boolean_t);	/* operation ok in this zone? */
-static int	start_auditd();			/* start audit daemon */
+static boolean_t contains_valid_dirs(char *);	/* p_dir contents validation */
+static boolean_t validate_path(char *);		/* is it path to dir? */
+static void	start_auditd();			/* start audit daemon */
 static int	sig_auditd(int);		/* send signal to auditd */
 
 /*
@@ -65,18 +68,18 @@
  *
  * input:
  *	audit -s
- *		- signal audit daemon to read audit_control file and
+ *		- signal audit daemon to read audit configuration and
  *		  start auditd if needed.
  *	audit -n
- *		- signal audit daemon to use next audit_control audit directory.
+ *		- signal audit daemon to use next audit_binfile directory.
  *	audit -t
  *		- signal audit daemon to disable auditing.
  *	audit -T
  *		- signal audit daemon to temporarily disable auditing reporting
  *		  no errors.
- *	audit -v filepath
- *		- validate audit_control parameters but use filepath for
- *		  the name.  Emit errors or "syntax ok"
+ *	audit -v
+ *		- validate audit configuration parameters;
+ *		  Print errors or "configuration ok".
  *
  *
  * output:
@@ -88,67 +91,67 @@
 int
 main(int argc, char *argv[])
 {
-	char	c;
-	char	*first_option;
+	int	c;
 
 	/* Internationalization */
 	(void) setlocale(LC_ALL, "");
 	(void) textdomain(TEXT_DOMAIN);
 
-	/* first option required */
-	if ((c = getopt(argc, argv, "nstTv:")) == -1) {
+	/* second or more options not allowed; please pick one */
+	if (argc > 2) {
 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
-		exit(3);
+		exit(1);
 	}
-	first_option = optarg;
-	/* second or more options not allowed; please pick one */
-	if (getopt(argc, argv, "nstTv:") != -1) {
+
+	/* first option required */
+	if ((c = getopt(argc, argv, "nstTv")) == -1) {
 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
-		exit(5);
+		exit(1);
 	}
+
 	switch (c) {
 	case 'n':
 		if (!is_valid_zone(1))	/* 1 == display error if any */
-			exit(10);
+			exit(1);
 
-		if (sig_auditd(AU_SIG_NEXT_DIR) != 0)
+		if (sig_auditd(SIGUSR1) != 0)
 			exit(1);
 		break;
 	case 's':
 		if (!is_valid_zone(1))	/* 1 == display error if any */
-			exit(10);
-		else if (!is_audit_control_ok(NULL))
-			exit(7);
+			exit(1);
+		else if (!is_audit_config_ok())
+			exit(1);
 
-		return (start_auditd());
+		start_auditd();
+		return (0);
 	case 't':
 		if (!is_valid_zone(0))	/* 0 == no error message display */
-			exit(10);
+			exit(1);
 		if (smf_disable_instance(AUDITD_FMRI, 0) != 0) {
 			display_smf_error();
-			exit(11);
+			exit(1);
 		}
 		break;
 	case 'T':
 		silent = 1;
 		if (!is_valid_zone(0))	/* 0 == no error message display */
-			exit(10);
-
+			exit(1);
 		if (smf_disable_instance(AUDITD_FMRI, SMF_TEMPORARY) != 0) {
-			exit(11);
+			exit(1);
 		}
 		break;
 	case 'v':
-		if (is_audit_control_ok(first_option)) {
-			(void) fprintf(stderr, gettext("syntax ok\n"));
+		if (is_audit_config_ok()) {
+			(void) fprintf(stderr, gettext("configuration ok\n"));
 			exit(0);
 		} else {
-			exit(8);
+			exit(1);
 		}
 		break;
 	default:
 		(void) fprintf(stderr, gettext("usage: %s\n"), usage);
-		exit(6);
+		exit(1);
 	}
 
 	return (0);
@@ -190,112 +193,79 @@
 }
 
 /*
- * perform reasonableness check on audit_control or its standin; goal
- * is that "audit -s" (1) not crash the system and (2) c2audit/auditd
- * actually generates data.
- *
- * A NULL input is ok -- it is used to tell _openac() to use the
- * real audit_control file, not a substitute.
+ * perform reasonableness check on audit configuration
  */
-#define	TRADITIONAL_MAX	1024
 
 static boolean_t
-is_audit_control_ok(char *filename) {
-	char		buf[TRADITIONAL_MAX];
-	int		outputs = 0;
-	int		state = 1;	/* 1 is ok, 0 is not */
-	int		rc;
-	int		min;
-	kva_t		*kvlist;
-	char		*plugin_name;
-	char		*plugin_dir;
-	au_acinfo_t	*ach;
-
-	ach = _openac(filename);	/* open audit_control */
-	if (ach == NULL) {
-		perror(progname);
-		exit(9);
-	}
-	/*
-	 * There must be at least one directory or one plugin
-	 * defined.
-	 */
-	if ((rc = _getacdir(ach, buf, TRADITIONAL_MAX)) == 0) {
-		outputs++;
-	} else if (rc < -1) {	/* -1 is not found, others are errors */
-		(void) fprintf(stderr,
-			gettext("%s: audit_control \"dir:\" spec invalid\n"),
-				progname);
-		state = 0;	/* is_not_ok */
-	}
+is_audit_config_ok() {
+	int			state = B_TRUE;	/* B_TRUE/B_FALSE = ok/not_ok */
+	char			*cval_str;
+	int			cval_int;
+	kva_t			*kvlist;
+	scf_plugin_kva_node_t   *plugin_kva_ll;
+	scf_plugin_kva_node_t   *plugin_kva_ll_head;
+	boolean_t		one_plugin_enabled = B_FALSE;
 
 	/*
-	 * _getacplug -- all that is of interest is the return code.
+	 * There must be at least one active plugin configured; if the
+	 * configured plugin is audit_binfile(5), then the p_dir must not be
+	 * empty.
 	 */
-	_rewindac(ach);	/* rewind audit_control */
-	while ((rc = _getacplug(ach, &kvlist)) == 0) {
-		plugin_name = kva_match(kvlist, "name");
-		if (plugin_name == NULL) {
-			(void) fprintf(stderr, gettext("%s: audit_control "
-			    "\"plugin:\" missing name\n"), progname);
-			state = 0;	/* is_not_ok */
-		} else {
-			if (strcmp(plugin_name, "audit_binfile.so") == 0) {
-				plugin_dir = kva_match(kvlist, "p_dir");
-				if ((plugin_dir == NULL) && (outputs == 0)) {
-					(void) fprintf(stderr,
-					    gettext("%s: audit_control "
-					    "\"plugin:\" missing p_dir\n"),
-					    progname);
-					state = 0;	/* is_not_ok */
-				} else {
-					outputs++;
-				}
+	if (!do_getpluginconfig_scf(NULL, &plugin_kva_ll)) {
+		(void) fprintf(stderr,
+		    gettext("Could not get plugin configuration.\n"));
+		exit(1);
+	}
+
+	plugin_kva_ll_head = plugin_kva_ll;
+
+	while (plugin_kva_ll != NULL) {
+		kvlist = plugin_kva_ll->plugin_kva;
+
+		if (!one_plugin_enabled) {
+			cval_str = kva_match(kvlist, "active");
+			if (atoi(cval_str) == 1) {
+				one_plugin_enabled = B_TRUE;
 			}
 		}
-		_kva_free(kvlist);
-	}
-	if (rc < -1) {
-		(void) fprintf(stderr,
-			gettext("%s: audit_control \"plugin:\" spec invalid\n"),
-				progname);
-		state = 0;	/* is_not_ok */
-	}
-	if (outputs == 0) {
-		(void) fprintf(stderr,
-			gettext("%s: audit_control must have either a "
-				"valid \"dir:\" entry or a valid \"plugin:\" "
-				"entry with \"p_dir:\" specified.\n"),
-				progname);
-		state = 0;	/* is_not_ok */
+
+		if (strcmp((char *)&(*plugin_kva_ll).plugin_name,
+		    "audit_binfile") == 0) {
+			cval_str = kva_match(kvlist, "p_dir");
+			if (*cval_str == '\0' || cval_str == NULL) {
+				(void) fprintf(stderr,
+				    gettext("%s: audit_binfile(5) \"p_dir:\" "
+				    "attribute empty\n"), progname);
+				state = B_FALSE;
+			} else if (!contains_valid_dirs(cval_str)) {
+				(void) fprintf(stderr,
+				    gettext("%s: audit_binfile(5) \"p_dir:\" "
+				    "attribute invalid\n"), progname);
+				state = B_FALSE;
+			}
+
+			cval_str = kva_match(kvlist, "p_minfree");
+			cval_int = atoi(cval_str);
+			if (cval_int < 0 || cval_int > 100) {
+				(void) fprintf(stderr,
+				    gettext("%s: audit_binfile(5) "
+				    "\"p_minfree:\" attribute invalid\n"),
+				    progname);
+				state = B_FALSE;
+			}
+		}
+
+		plugin_kva_ll = plugin_kva_ll->next;
 	}
-	/* minfree is not required */
-	_rewindac(ach);
-	if ((rc = _getacmin(ach, &min)) < -1) {
-		(void) fprintf(stderr,
-			gettext(
-			    "%s: audit_control \"minfree:\" spec invalid\n"),
-			    progname);
-		state = 0;	/* is_not_ok */
+
+	plugin_kva_ll_free(plugin_kva_ll_head);
+
+	if (!one_plugin_enabled) {
+		(void) fprintf(stderr, gettext("%s: no active plugin found\n"),
+		    progname);
+		state = B_FALSE;
 	}
-	/* flags is not required */
-	_rewindac(ach);
-	if ((rc = _getacflg(ach, buf, TRADITIONAL_MAX)) < -1) {
-		(void) fprintf(stderr,
-			gettext("%s: audit_control \"flags:\" spec invalid\n"),
-				progname);
-		state = 0;	/* is_not_ok */
-	}
-	/* naflags is not required */
-	_rewindac(ach);
-	if ((rc = _getacna(ach, buf, TRADITIONAL_MAX)) < -1) {
-		(void) fprintf(stderr,
-			gettext(
-			    "%s: audit_control \"naflags:\" spec invalid\n"),
-			    progname);
-		state = 0;	/* is_not_ok */
-	}
-	_endac(ach);
+
 	return (state);
 }
 
@@ -337,11 +307,79 @@
 }
 
 /*
+ * Verify, whether the dirs_str contains at least one currently valid path to
+ * the directory. All invalid paths are reported. In case no valid directory
+ * path is found function returns B_FALSE, otherwise B_TRUE.
+ */
+
+static boolean_t
+contains_valid_dirs(char *dirs_str)
+{
+	boolean_t	rc = B_FALSE;
+	boolean_t	rc_validate_path = B_TRUE;
+	char		*tok_ptr;
+	char		*tok_lasts;
+
+	if (dirs_str == NULL) {
+		return (rc);
+	}
+
+	if ((tok_ptr = strtok_r(dirs_str, ",", &tok_lasts)) != NULL) {
+		if (validate_path(tok_ptr)) {
+			rc = B_TRUE;
+		} else {
+			rc_validate_path = B_FALSE;
+		}
+		while ((tok_ptr = strtok_r(NULL, ",", &tok_lasts)) != NULL) {
+			if (validate_path(tok_ptr)) {
+				rc = B_TRUE;
+			} else {
+				rc_validate_path = B_FALSE;
+			}
+		}
+	}
+
+	if (rc && !rc_validate_path) {
+		(void) fprintf(stderr, gettext("%s: at least one valid "
+		    "directory path found\n"), progname);
+	}
+
+	return (rc);
+}
+
+/*
+ * Verify, that the dir_path is path to a directory.
+ */
+
+static boolean_t
+validate_path(char *dir_path)
+{
+	boolean_t	rc = B_FALSE;
+	struct stat	statbuf;
+
+	if (dir_path == NULL) {
+		return (rc);
+	}
+
+	if (stat(dir_path, &statbuf) == -1) {
+		(void) fprintf(stderr, gettext("%s: %s error: %s\n"), progname,
+		    dir_path, strerror(errno));
+	} else if (statbuf.st_mode & S_IFDIR) {
+			rc = B_TRUE;
+	} else {
+		(void) fprintf(stderr, gettext("%s: %s is not a directory\n"),
+		    progname, dir_path);
+	}
+
+	return (rc);
+}
+
+/*
  * if auditd isn't running, start it.  Otherwise refresh.
  * First check to see if c2audit is loaded via the auditon()
  * system call, then check SMF state.
  */
-static int
+static void
 start_auditd()
 {
 	int	audit_state;
@@ -349,27 +387,26 @@
 
 	if (auditon(A_GETCOND, (caddr_t)&audit_state,
 	    sizeof (audit_state)) != 0)
-		return (12);
+		exit(1);
 
 	if ((state = smf_get_state(AUDITD_FMRI)) == NULL) {
 		display_smf_error();
-		return (13);
+		exit(1);
 	}
 	if (strcmp(SCF_STATE_STRING_ONLINE, state) != 0) {
 		if (smf_enable_instance(AUDITD_FMRI, 0) != 0) {
 			display_smf_error();
 			free(state);
-			return (14);
+			exit(1);
 		}
 	} else {
 		if (smf_refresh_instance(AUDITD_FMRI) != 0) {
 			display_smf_error();
 			free(state);
-			return (15);
+			exit(1);
 		}
 	}
 	free(state);
-	return (0);
 }
 
 static void
--- a/usr/src/cmd/audit_warn/audit_warn.sh	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/audit_warn/audit_warn.sh	Tue Jul 27 14:38:47 2010 +0200
@@ -20,8 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 # This shell script warns the administrator when there are problems or
@@ -88,7 +87,7 @@
 
 	"soft" )	# Check soft arg
 			# One audit filesystem has filled to the soft limit
-			# set up in audit_control.
+			# that is configured in the audit service.
 
 			if [ ! -n "$2" ]
 			then
@@ -107,7 +106,7 @@
 
 	"allsoft" )	# Check all soft arg
 			# All the audit filesystems have filled to the soft
-			# limit set up in audit_control.
+			# limit set up in the audit service configuration.
 
 			# Set message
 			MESSAGE="Soft limit exceeded on all filesystems."
@@ -239,33 +238,6 @@
 			break
 			;;
 
-	"getacdir" )	# Check getacdir arg
-			# There is a problem getting the directory list from
-			# /etc/security/audit_control.  Auditd is
-			# going to hang in a sleep loop until the file is
-			# fixed.
-
-			if [ ! -n "$2" ]
-			then
-				$DEBUG_OUT "$0: Need count arg with 'getacdir'!"
-				exit 1
-			else
-				COUNT=$2
-				if [ $COUNT -eq 1 ]; then
-					S=""
-				else
-					S="s"
-				fi
-			fi
-
-			# Set message
-			MESSAGE="There is a problem getting the directory\
- list or plugin list from audit_control(4).  The audit daemon will hang
- until this file is fixed.  This message has been displayed $COUNT time$S."
-			send_msg
-			break
-			;;
-
 	"plugin" )	# Check plugin arg
 
 			# There is a problem loading a plugin or a plugin
--- a/usr/src/cmd/auditconfig/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditconfig/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -18,8 +18,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 #
 # Makefile for auditconfig
@@ -29,18 +28,16 @@
 include $(SRC)/cmd/Makefile.cmd
 
 LIBBSM = $(SRC)/lib/libbsm/common
-AUDITCONFIG = $(SRC)/cmd/auditconfig
-AUDITD = $(SRC)/cmd/auditd
 
-LDLIBS += -lnsl -lbsm -lscf
+LDLIBS += -lnsl -lbsm -lsecdb
 
-OBJS = audit_scf.o audit_scf_shared.o auditconfig.o 
+OBJS = auditconfig.o 
 SRCS = $(OBJS:%.o=%.c)
 
 POFILE = $(PROG).po
 MSGFILES = $(SRCS)
 
-CPPFLAGS += -I$(LIBBSM) -I$(AUDITD) -I$(AUDITCONFIG) 
+CPPFLAGS += -I$(LIBBSM)
 
 .KEEP_STATE:
 
--- a/usr/src/cmd/auditconfig/audit_scf.c	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,351 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/* auditd smf(5)/libscf(3LIB) interface - set and display audit parameters */
-#include <audit_scf.h>
-#include <auditconfig_impl.h>
-
-/* propvec array must be NULL terminated */
-extern scf_propvec_t    prop_vect[MAX_PROPVECS + 1];
-
-static boolean_t set_val_scf(scf_propvec_t *, char *);
-
-/*
- * do_getqbufsz_scf() - get the qbufsz audit service property value
- */
-boolean_t
-do_getqbufsz_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
-		return (B_FALSE);
-	}
-
-	*cval = (size_t)cval_l;
-
-	return (B_TRUE);
-}
-
-/*
- * do_getqdelay_scf() - get the qdelay audit service property value
- */
-boolean_t
-do_getqdelay_scf(clock_t *cval)
-{
-	uint64_t	cval_l;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
-		return (B_FALSE);
-	}
-
-	*cval = (clock_t)cval_l;
-
-	return (B_TRUE);
-}
-
-/*
- * do_getqhiwater_scf() - get the qhiwater audit service property value
- */
-boolean_t
-do_getqhiwater_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
-		return (B_FALSE);
-	}
-
-	*cval = (size_t)cval_l;
-
-	return (B_TRUE);
-}
-
-/*
- * do_getqlowater_scf() - get the qlowater audit service property value
- */
-boolean_t
-do_getqlowater_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
-		return (B_FALSE);
-	}
-
-	*cval = (size_t)cval_l;
-
-	return (B_TRUE);
-}
-
-/*
- * do_setpolicy_scf() - sets the policy flags in audit service configuration
- */
-boolean_t
-do_setpolicy_scf(uint32_t policy)
-{
-	int		i;
-	char		*cur_policy_str;
-	scf_propvec_t	*prop_vect_ptr;
-	boolean_t	bool_arr[POLICY_TBL_SZ];
-	boolean_t	*bool_arr_ptr;
-
-	prop_vect_ptr = prop_vect;
-	bool_arr_ptr = bool_arr;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	bzero(bool_arr, sizeof (bool_arr));
-
-	for (i = 0; i < POLICY_TBL_SZ; i++) {
-
-		cur_policy_str = policy_table[i].policy_str;
-
-		/* Do some basic policy dependent checks */
-		if (!chk_policy_context(cur_policy_str)) {
-			continue;
-		}
-
-		if (policy_table[i].policy_mask & policy) {
-			*bool_arr_ptr = B_TRUE;
-		} else {
-			*bool_arr_ptr = B_FALSE;
-		}
-
-		DPRINT((dbfp, "%s%s\n", (*bool_arr_ptr == B_TRUE ? "+" : "-"),
-		    cur_policy_str));
-
-		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
-		    SCF_TYPE_BOOLEAN, (void *)bool_arr_ptr++);
-
-	}
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_POLICY));
-}
-
-/*
- * do_setqctrl_scf() - set the values of qctrl properties of the audit service
- */
-boolean_t
-do_setqctrl_scf(struct au_qctrl *cval)
-{
-	scf_propvec_t		*prop_vect_ptr;
-	scf_qctrl_t		cval_scf;
-
-	if (!CHK_BDRY_QHIWATER(cval->aq_lowater, cval->aq_hiwater) &&
-	    cval->aq_hiwater != 0) {
-		(void) printf(gettext("Specified audit queue hiwater mark "
-		    " out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-	if (!CHK_BDRY_QLOWATER(cval->aq_lowater, cval->aq_hiwater) &&
-	    cval->aq_lowater != 0) {
-		(void) printf(gettext("Specified audit queue lowater mark is "
-		    " out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-	if (!CHK_BDRY_QBUFSZ(cval->aq_bufsz) && cval->aq_bufsz != 0) {
-		(void) printf(gettext("Specified audit queue buffer size is "
-		    "out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-	if (!CHK_BDRY_QDELAY(cval->aq_delay) && cval->aq_delay != 0) {
-		(void) printf(gettext("Specified audit queue delay is "
-		    "out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-
-	cval_scf.scf_qhiwater = (uint64_t)cval->aq_hiwater;
-	cval_scf.scf_qlowater = (uint64_t)cval->aq_lowater;
-	cval_scf.scf_qbufsz = (uint64_t)cval->aq_bufsz;
-	cval_scf.scf_qdelay = (uint64_t)cval->aq_delay;
-
-	bzero(prop_vect, sizeof (prop_vect));
-
-	prop_vect_ptr = prop_vect;
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_scf.scf_qhiwater);
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_scf.scf_qlowater);
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT,
-	    (void *)&cval_scf.scf_qbufsz);
-	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY, SCF_TYPE_COUNT,
-	    (void *)&cval_scf.scf_qdelay);
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
-}
-
-/*
- * do_setqbufsz_scf() - set the qbufsz property value of the audit service
- */
-boolean_t
-do_setqbufsz_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-
-	if (!CHK_BDRY_QBUFSZ(*cval) && *cval != 0) {
-		(void) printf(gettext("Specified audit queue buffer size is "
-		    "out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-
-	cval_l = (uint64_t)*cval;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
-}
-
-/*
- * do_setqdelay_scf() - set the qdelay property value of the audit service
- */
-boolean_t
-do_setqdelay_scf(clock_t *cval)
-{
-	uint64_t	cval_l;
-
-	if (!CHK_BDRY_QDELAY(*cval) && *cval != 0) {
-		(void) printf(gettext("Specified audit queue delay is "
-		    " out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-
-	cval_l = (uint64_t)*cval;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
-}
-
-/*
- * do_setqhiwater_scf() - set the qhiwater property value of the audit service
- */
-boolean_t
-do_setqhiwater_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-	size_t		cval_lowater;
-
-	if (!do_getqlowater_scf(&cval_lowater)) {
-		(void) printf(gettext("Could not get configured value of "
-		    "queue lowater mark.\n"));
-		return (B_FALSE);
-	}
-	if (cval_lowater == 0) {
-		cval_lowater = AQ_MINLOW;
-	}
-	if (!CHK_BDRY_QHIWATER(cval_lowater, *cval) && *cval != 0) {
-		(void) printf(gettext("Specified audit queue hiwater mark "
-		    "is out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-
-	cval_l = (uint64_t)*cval;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
-}
-
-/*
- * do_setqlowater_scf() - set the qlowater property value of the audit service
- */
-boolean_t
-do_setqlowater_scf(size_t *cval)
-{
-	uint64_t	cval_l;
-	size_t		cval_hiwater;
-
-	if (!do_getqhiwater_scf(&cval_hiwater)) {
-		(void) printf(gettext("Could not get configured value of "
-		    "queue hiwater mark.\n"));
-		return (B_FALSE);
-	}
-	if (cval_hiwater == 0) {
-		cval_hiwater = AQ_MAXHIGH;
-	}
-	if (!CHK_BDRY_QLOWATER(*cval, cval_hiwater) && *cval != 0) {
-		(void) printf(gettext("Specified audit queue lowater mark is "
-		    "out of allowed boundaries.\n"));
-		return (B_FALSE);
-	}
-
-	cval_l = (uint64_t)*cval;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
-	    (void *)&cval_l);
-
-	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
-}
-
-/*
- * set_val_scf() - set property values of the audit service.
- *
- * arguments:	vector = pointers to the head end of array of property vectors
- * 		pgroup_str = property group of property in AUDITD_FMRI
- *
- */
-static boolean_t
-set_val_scf(scf_propvec_t *vector, char *pgroup_str)
-{
-	scf_propvec_t	*bad_prop_vec = NULL;
-
-	/* for documentation on property vectors see <libscf_priv.h> */
-	if (scf_write_propvec(AUDITD_FMRI, pgroup_str,
-	    vector, (scf_propvec_t **)&bad_prop_vec) != SCF_SUCCESS) {
-		prt_scf_err();
-		if (bad_prop_vec != NULL) {
-			prt_error(gettext("Setting the %s property in the %s "
-			    "property group failed.\n"), bad_prop_vec->pv_prop,
-			    pgroup_str);
-		}
-		prt_error(gettext("Unable to set property value."));
-		return (B_FALSE);
-	}
-
-	return (B_TRUE);
-}
--- a/usr/src/cmd/auditconfig/audit_scf.h	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef _AUDIT_SCF_H
-#define	_AUDIT_SCF_H
-
-/*
- * auditd smf(5)/libscf(3LIB) interface - set and display audit parameters
- */
-
-#include <audit_plugin.h>
-#include <audit_sig_infc.h>
-#include <bsm/libbsm.h>
-#include <libintl.h>
-#include <libscf_priv.h>
-#include <strings.h>
-#include <sys/varargs.h>
-#include <zone.h>
-
-/* gettext() obfuscation routine for lint */
-#ifdef __lint
-#define	gettext(x)	x
-#endif
-
-#ifndef DEBUG
-#define	DEBUG	0
-#endif
-
-#if DEBUG
-FILE	*dbfp;		  /* debug file pointer */
-#define	DPRINT(x)	{ if (dbfp == NULL) dbfp = __auditd_debug_file_open(); \
-			    (void) fprintf x; (void) fflush(dbfp); }
-#else	/* ! DEBUG */
-#define	DPRINT(x)
-#endif
-
-/*
- * (ASI) Audit service instance (svc:/system/auditd:default) related
- * configuration parameters.
- */
-#define	ASI_PGROUP_POLICY	"policy"
-struct policy_sw {
-	char		*policy;
-	boolean_t	flag;
-};
-typedef struct policy_sw policy_sw_t;
-
-#define	ASI_PGROUP_QUEUECTRL	"queuectrl"
-#define	QUEUECTRL_QBUFSZ	"qbufsz"
-#define	QUEUECTRL_QDELAY	"qdelay"
-#define	QUEUECTRL_QHIWATER	"qhiwater"
-#define	QUEUECTRL_QLOWATER	"qlowater"
-struct scf_qctrl {
-	uint64_t	scf_qhiwater;
-	uint64_t	scf_qlowater;
-	uint64_t	scf_qbufsz;
-	uint64_t	scf_qdelay;
-};
-typedef struct scf_qctrl scf_qctrl_t;
-
-/* Boundary checking macros for the queuectrl parameters. */
-#define	AQ_MINLOW	1
-#define	CHK_BDRY_QBUFSZ(x)	!((x) < AQ_BUFSZ || (x) > AQ_MAXBUFSZ)
-#define	CHK_BDRY_QDELAY(x)	!((x) == 0 || (x) > AQ_MAXDELAY)
-#define	CHK_BDRY_QLOWATER(low, high)	!((low) < AQ_MINLOW || (low) >= (high))
-#define	CHK_BDRY_QHIWATER(low, high)	!((high) <= (low) || \
-					    (high) < AQ_LOWATER || \
-					    (high) > AQ_MAXHIGH)
-
-/*
- * MAX_PROPVECS	maximum number of audit properties that will
- * 		fit in the uint32_t audit policy mask.
- */
-#define	MAX_PROPVECS	32
-
-/* defined in audit_scf_shared.c; used in auditd.c and auditconfig.c */
-void add_prop_vect_scf(scf_propvec_t *, const char *, scf_type_t, void *);
-boolean_t chk_policy_context(char *);
-boolean_t do_getqctrl_scf(struct au_qctrl *);
-boolean_t do_getpolicy_scf(uint32_t *);
-uint32_t get_policy(char *);
-boolean_t get_val_scf(scf_propvec_t *, char *);
-void prt_error(char *, ...);
-void prt_error_va(char *, va_list);
-void prt_scf_err(void);
-
-/* defined in audit_scf.c; used only in auditconfig.c */
-boolean_t do_getqbufsz_scf(size_t *);
-boolean_t do_getqdelay_scf(clock_t *);
-boolean_t do_getqhiwater_scf(size_t *);
-boolean_t do_getqlowater_scf(size_t *);
-boolean_t do_setpolicy_scf(uint32_t);
-boolean_t do_setqctrl_scf(struct au_qctrl *);
-boolean_t do_setqbufsz_scf(size_t *);
-boolean_t do_setqdelay_scf(clock_t *);
-boolean_t do_setqhiwater_scf(size_t *);
-boolean_t do_setqlowater_scf(size_t *);
-
-#endif	/* _AUDIT_SCF_H */
--- a/usr/src/cmd/auditconfig/audit_scf_shared.c	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/* auditd smf(5)/libscf(3LIB) interface - set and display audit parameters */
-#include <audit_scf.h>
-#include <auditconfig_impl.h>
-
-/* propvec array must be NULL terminated */
-scf_propvec_t    prop_vect[MAX_PROPVECS + 1];
-
-/*
- * do_getqctrl_scf() - get the values of qctrl properties of the audit service
- */
-boolean_t
-do_getqctrl_scf(struct au_qctrl *cval)
-{
-	scf_propvec_t   	*prop_vect_ptr;
-	scf_qctrl_t		cval_scf;
-
-	bzero(prop_vect, sizeof (prop_vect));
-
-	prop_vect_ptr = prop_vect;
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER,
-	    SCF_TYPE_COUNT, (void *)&cval_scf.scf_qhiwater);
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER,
-	    SCF_TYPE_COUNT, (void *)&cval_scf.scf_qlowater);
-	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ,
-	    SCF_TYPE_COUNT, (void *)&cval_scf.scf_qbufsz);
-	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY,
-	    SCF_TYPE_COUNT, (void *)&cval_scf.scf_qdelay);
-
-	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
-		return (B_FALSE);
-	}
-
-	cval->aq_hiwater = (size_t)cval_scf.scf_qhiwater;
-	cval->aq_lowater = (size_t)cval_scf.scf_qlowater;
-	cval->aq_bufsz = (size_t)cval_scf.scf_qbufsz;
-	cval->aq_delay = (clock_t)cval_scf.scf_qdelay;
-
-	return (B_TRUE);
-}
-
-/*
- * do_getpolicy_scf() - get the audit policy flags from service
- */
-boolean_t
-do_getpolicy_scf(uint32_t *policy_mask)
-{
-	int			i;
-	scf_propvec_t		*prop_vect_ptr;
-	char			*cur_policy_str;
-	policy_sw_t		policy_arr[POLICY_TBL_SZ + 1];
-	policy_sw_t		*policy_arr_ptr;
-
-	prop_vect_ptr = prop_vect;
-	policy_arr_ptr = policy_arr;
-
-	bzero(prop_vect, sizeof (prop_vect));
-	bzero(policy_arr, sizeof (policy_arr));
-
-	/* prepare the smf(5) query */
-	for (i = 0; i < POLICY_TBL_SZ; i++) {
-
-		cur_policy_str = policy_table[i].policy_str;
-
-		/* Do some basic policy dependent checks */
-		if (!chk_policy_context(cur_policy_str)) {
-			continue;
-		}
-		DPRINT((dbfp, "will be queried\n"));
-
-		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
-		    SCF_TYPE_BOOLEAN, (void *)&policy_arr_ptr->flag);
-
-		policy_arr_ptr->policy = cur_policy_str;
-		policy_arr_ptr++;
-
-	}
-	if (!get_val_scf(prop_vect, ASI_PGROUP_POLICY)) {
-		return (B_FALSE);
-	}
-
-	/* set the policy mask */
-	policy_arr_ptr = policy_arr;
-	*policy_mask = 0;
-	while (policy_arr_ptr->policy != NULL) {
-		if (policy_arr_ptr->flag) {
-			*policy_mask |= get_policy(policy_arr_ptr->policy);
-		}
-		policy_arr_ptr++;
-	}
-
-	return (B_TRUE);
-}
-
-/*
- * get_policy() - get policy mask entry
- */
-uint32_t
-get_policy(char *policy)
-{
-	int i;
-
-	for (i = 0; i < POLICY_TBL_SZ; i++) {
-		if (strcasecmp(policy, policy_table[i].policy_str) == 0) {
-			return (policy_table[i].policy_mask);
-		}
-	}
-
-	return (0);
-}
-
-/*
- * chk_policy_context() - does some policy based checks, checks the context
- * (zone, smf) in which the policy could make some sense.
- */
-boolean_t
-chk_policy_context(char *policy_str)
-{
-
-	/*
-	 * "all" and "none" policy flags, since they represent
-	 * sub/set of auditing policies, are not stored in the
-	 * AUDITD_FMRI service instance configuration.
-	 */
-	DPRINT((dbfp, "Walking policy - %s: ", policy_str));
-	if (strcmp("all", policy_str) == 0 ||
-	    strcmp("none", policy_str) == 0) {
-		DPRINT((dbfp, "skipped\n"));
-		return (B_FALSE);
-	}
-	/*
-	 * In the local zone (!= GLOBAL_ZONEID) we do not touch
-	 * "ahlt" and "perzone" policy flags, since these are
-	 * relevant only in the global zone.
-	 */
-	if ((getzoneid() != GLOBAL_ZONEID) &&
-	    (strcmp("ahlt", policy_str) == 0 ||
-	    strcmp("perzone", policy_str) == 0)) {
-		DPRINT((dbfp, "skipped\n"));
-		return (B_FALSE);
-	}
-
-	return (B_TRUE);
-}
-
-/*
- * prt_error() - prt_error_va() wrapper; see prt_error_va() for more contextual
- * information. Inputs - program error format and message.
- *
- */
-/*PRINTFLIKE1*/
-void
-prt_error(char *fmt, ...)
-{
-	va_list 	args;
-
-	va_start(args, fmt);
-	prt_error_va(fmt, args);
-	va_end(args);
-}
-
-/*
- * prt_error_va() - prints an error message along with corresponding system
- * error number. Inputs - program error format and the va_list already prepared
- * by the preceding functions.
- *
- */
-/*PRINTFLIKE1*/
-void
-prt_error_va(char *fmt, va_list args)
-{
-	(void) vfprintf(stderr, fmt, args);
-	(void) fputc('\n', stderr);
-	if (errno)
-		(void) fprintf(stderr, gettext("error: %s(%d)\n"),
-		    strerror(errno), errno);
-	(void) fflush(stderr);
-}
-
-/*
- * add_prop_vect_scf() - adds vector to the array of vectors later passed to
- * get_/set_val_scf(). The first argument (vector) points to particular position
- * in the vector of properties.
- */
-void
-add_prop_vect_scf(scf_propvec_t *vector, const char *prop_str,
-    scf_type_t prop_type, void *prop_val_ptr)
-{
-	vector->pv_prop = prop_str;
-	vector->pv_type = prop_type;
-	vector->pv_ptr = prop_val_ptr;
-}
-
-/*
- * get_val_scf() - get a property values from the audit service
- *
- * Arguments:	vector = pointers to the head end of array of property vectors
- * 		pgroup_str = property group of property in AUDITD_FMRI
- *
- */
-boolean_t
-get_val_scf(scf_propvec_t *vector, char *pgroup_str)
-{
-	scf_propvec_t	*bad_prop_vec = NULL;
-
-	/*
-	 * Get the property vector from the editing snapshot (B_FALSE).
-	 * For documentation on property vectors see <libscf_priv.h>.
-	 */
-	if (scf_read_propvec(AUDITD_FMRI, pgroup_str, B_FALSE,
-	    vector, (scf_propvec_t **)&bad_prop_vec) != SCF_SUCCESS) {
-		prt_scf_err();
-		if (bad_prop_vec != NULL) {
-			prt_error(gettext("Reading the %s property in the %s "
-			    "property group failed.\n"), bad_prop_vec->pv_prop,
-			    pgroup_str);
-		}
-		prt_error(gettext("Unable to get property value."));
-		return (B_FALSE);
-	}
-
-	return (B_TRUE);
-}
-
-/*
- * prt_scf_err() - scf_error()/scf_strerror() wrapper.
- */
-void
-prt_scf_err(void)
-{
-	(void) fprintf(stderr, "error: %s\n", scf_strerror(scf_error()));
-}
--- a/usr/src/cmd/auditconfig/auditconfig.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditconfig/auditconfig.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -52,8 +51,8 @@
 #include <libscf_priv.h>
 #include <tsol/label.h>
 #include <bsm/libbsm.h>
-#include "auditconfig_impl.h"
-#include "audit_scf.h"
+#include <audit_policy.h>
+#include <audit_scf.h>
 
 enum	commands {
 	AC_ARG_ACONF,
@@ -69,9 +68,12 @@
 	AC_ARG_GETCOND,
 	AC_ARG_GETCWD,
 	AC_ARG_GETESTATE,
+	AC_ARG_GETFLAGS,
 	AC_ARG_GETKAUDIT,
 	AC_ARG_GETKMASK,
+	AC_ARG_GETNAFLAGS,
 	AC_ARG_GETPINFO,
+	AC_ARG_GETPLUGIN,
 	AC_ARG_GETPOLICY,
 	AC_ARG_GETQBUFSZ,
 	AC_ARG_GETQCTRL,
@@ -86,8 +88,11 @@
 	AC_ARG_SETAUDIT,
 	AC_ARG_SETAUID,
 	AC_ARG_SETCLASS,
+	AC_ARG_SETFLAGS,
 	AC_ARG_SETKAUDIT,
 	AC_ARG_SETKMASK,
+	AC_ARG_SETNAFLAGS,
+	AC_ARG_SETPLUGIN,
 	AC_ARG_SETPMASK,
 	AC_ARG_SETPOLICY,
 	AC_ARG_SETQBUFSZ,
@@ -134,9 +139,12 @@
 	{ "-getcond",	"",			AC_ARG_GETCOND,	B_FALSE},
 	{ "-getcwd",	"",			AC_ARG_GETCWD,	B_FALSE},
 	{ "-getestate",	" event",		AC_ARG_GETESTATE, B_FALSE},
+	{ "-getflags",	"",			AC_ARG_GETFLAGS, B_FALSE},
 	{ "-getkaudit",	"",			AC_ARG_GETKAUDIT, B_FALSE},
 	{ "-getkmask",	"",			AC_ARG_GETKMASK, B_FALSE},
+	{ "-getnaflags", "",			AC_ARG_GETNAFLAGS, B_FALSE},
 	{ "-getpinfo",	" pid",			AC_ARG_GETPINFO, B_FALSE},
+	{ "-getplugin",	" [plugin]",		AC_ARG_GETPLUGIN, B_FALSE},
 	{ "-getpolicy",	"",			AC_ARG_GETPOLICY, B_TRUE},
 	{ "-getqbufsz",	"",			AC_ARG_GETQBUFSZ, B_TRUE},
 	{ "-getqctrl",	"",			AC_ARG_GETQCTRL, B_TRUE},
@@ -152,8 +160,12 @@
 						AC_ARG_SETAUDIT, B_FALSE},
 	{ "-setauid",	" auid [cmd]",		AC_ARG_SETAUID,	B_FALSE},
 	{ "-setclass",	" event audit_flags",	AC_ARG_SETCLASS, B_FALSE},
+	{ "-setflags",	" audit_flags",		AC_ARG_SETFLAGS, B_FALSE},
 	{ "-setkaudit",	" type IP_address",	AC_ARG_SETKAUDIT, B_FALSE},
 	{ "-setkmask",	" audit_flags",		AC_ARG_SETKMASK, B_FALSE},
+	{ "-setnaflags", " audit_naflags",	AC_ARG_SETNAFLAGS, B_FALSE},
+	{ "-setplugin",	" name active|inactive [attributes [qsize]]",
+						AC_ARG_SETPLUGIN, B_FALSE},
 	{ "-setpmask",	" pid audit_flags",	AC_ARG_SETPMASK, B_FALSE},
 	{ "-setpolicy",	" [+|-]policy_flags",	AC_ARG_SETPOLICY, B_TRUE},
 	{ "-setqbufsz",	" bufsz",		AC_ARG_SETQBUFSZ, B_TRUE},
@@ -186,17 +198,18 @@
 static int str2type(char *s, uint_t *type);
 static int str2policy(char *policy_str, uint32_t *policy_mask);
 static int str2ipaddr(char *s, uint32_t *addr, uint32_t type);
-static int strisflags(char *s);
 static int strisipaddr(char *s);
 static int strisnum(char *s);
 static arg_entry_t *get_arg_ent(char *arg_str);
 static uid_t get_user_id(char *user);
+static void chk_arg_len(char *argv, uint_t len);
 static void chk_event_num(int etype, au_event_t event);
 static void chk_event_str(int etype, char *event_str);
+static void chk_known_plugin(char *plugin_str);
 static void chk_retval(char *retval_str);
 static void chk_sorf(char *sorf_str);
 static void do_aconf(void);
-static void do_args(char **argv);
+static void do_args(char **argv, au_mask_t *mask);
 static void do_audit(char *, char, int, char *);
 static void do_chkaconf(void);
 static void do_chkconf(void);
@@ -210,8 +223,11 @@
 static void do_getclass(char *event_str);
 static void do_getcond(void);
 static void do_getcwd(void);
+static void do_getflags(void);
 static void do_getkmask(void);
+static void do_getnaflags(void);
 static void do_getpinfo(char *pid_str);
+static void do_getplugin(char *plugin_str);
 static void do_getpolicy(void);
 static void do_getqbufsz(void);
 static void do_getqctrl(void);
@@ -226,11 +242,15 @@
 static void do_setaudit(char *user_str, char *mask_str, char *tid_str,
     char *sid_str, char **argv);
 static void do_setauid(char *user, char **argv);
-static void do_setclass(char *event_str, char *audit_flags);
-static void do_setkmask(char *audit_flags);
-static void do_setpmask(char *pid_str, char *audit_flags);
-static void do_setsmask(char *asid_str, char *audit_flags);
-static void do_setumask(char *auid_str, char *audit_flags);
+static void do_setclass(char *event_str, au_mask_t *mask);
+static void do_setflags(char *audit_flags, au_mask_t *amask);
+static void do_setkmask(au_mask_t *pmask);
+static void do_setnaflags(char *audit_naflags, au_mask_t *namask);
+static void do_setpmask(char *pid_str, au_mask_t *mask);
+static void do_setsmask(char *asid_str, au_mask_t *mask);
+static void do_setumask(char *auid_str, au_mask_t *mask);
+static void do_setplugin(char *plugin_str, boolean_t plugin_state,
+    char *plugin_attr, int plugin_qsize);
 static void do_setpolicy(char *policy_str);
 static void do_setqbufsz(char *bufsz);
 static void do_setqctrl(char *hiwater, char *lowater, char *bufsz, char *delay);
@@ -238,25 +258,25 @@
 static void do_setqhiwater(char *hiwater);
 static void do_setqlowater(char *lowater);
 static void do_setstat(void);
-static void str2mask(char *mask_str, au_mask_t *mp);
 static void str2tid(char *tid_str, au_tid_addr_t *tp);
-static void strsplit(char *s, char *p1, char *p2, char c);
 
 static void eauditon(int cmd, caddr_t data, int length);
+static void echkflags(char *auditflags, au_mask_t *mask);
 static void egetaudit(auditinfo_addr_t *ai, int size);
-static void egetkaudit(auditinfo_addr_t *ai, int size);
-static void esetkaudit(auditinfo_addr_t *ai, int size);
 static void egetauditflagsbin(char *auditflags, au_mask_t *pmask);
 static void egetauid(au_id_t *auid);
+static void egetkaudit(auditinfo_addr_t *ai, int size);
 static void esetaudit(auditinfo_addr_t *ai, int size);
 static void esetauid(au_id_t *auid);
+static void esetkaudit(auditinfo_addr_t *ai, int size);
 static void execit(char **argv);
 static void exit_error(char *fmt, ...);
 static void exit_usage(int status);
-static void parse_args(int argc, char **argv);
+static void parse_args(int argc, char **argv, au_mask_t *mask);
 static void print_asid(au_asid_t asid);
 static void print_auid(au_id_t auid);
 static void print_mask(char *desc, au_mask_t *pmp);
+static void print_plugin(char *plugin_name, kva_t *plugin_kva);
 static void print_tid_ex(au_tid_addr_t *tidp);
 
 #if !defined(TEXT_DOMAIN)
@@ -266,6 +286,8 @@
 int
 main(int argc, char **argv)
 {
+	au_mask_t mask;			/* for options manipulating flags */
+
 	(void) setlocale(LC_ALL, "");
 	(void) textdomain(TEXT_DOMAIN);
 
@@ -280,8 +302,8 @@
 		exit_usage(0);
 	}
 
-	parse_args(argc, argv);
-	do_args(argv);
+	parse_args(argc, argv, &mask);
+	do_args(argv, &mask);
 
 	return (0);
 }
@@ -295,11 +317,10 @@
  *              parse_args() returns without a value.
  */
 static void
-parse_args(int argc, char **argv)
+parse_args(int argc, char **argv, au_mask_t *mask)
 {
 	arg_entry_t *ae;
 
-	au_mask_t mask;
 	uint_t type;
 	uint_t addr[4];
 
@@ -359,7 +380,24 @@
 		case AC_ARG_GETCAR:
 		case AC_ARG_GETCOND:
 		case AC_ARG_GETCWD:
+		case AC_ARG_GETFLAGS:
 		case AC_ARG_GETKMASK:
+		case AC_ARG_GETNAFLAGS:
+			break;
+
+		case AC_ARG_GETPLUGIN:
+			if (*++argv == NULL) {
+				--argv;
+				break;
+			}
+			if (get_arg_ent(*argv) != NULL) {
+				--argv;
+			} else {
+				chk_arg_len(*argv, PLUGIN_MAXBUF);
+				chk_known_plugin(*argv);
+			}
+			break;
+
 		case AC_ARG_GETPOLICY:
 		case AC_ARG_GETQBUFSZ:
 		case AC_ARG_GETQCTRL:
@@ -413,14 +451,55 @@
 			++argv;
 			if (!*argv)
 				exit_usage(1);
-			str2mask(*argv, &mask);
+			echkflags(*argv, mask);
+			break;
+
+		case AC_ARG_SETFLAGS:
+			++argv;
+			if (!*argv)
+				exit_usage(1);
+			chk_arg_len(*argv, PRESELECTION_MAXBUF);
+			echkflags(*argv, mask);
 			break;
 
 		case AC_ARG_SETKMASK:
 			++argv;
 			if (!*argv)
 				exit_usage(1);
-			str2mask(*argv, &mask);
+			echkflags(*argv, mask);
+			break;
+
+		case AC_ARG_SETNAFLAGS:
+			++argv;
+			if (!*argv)
+				exit_usage(1);
+			chk_arg_len(*argv, PRESELECTION_MAXBUF);
+			echkflags(*argv, mask);
+			break;
+
+		case AC_ARG_SETPLUGIN:
+			if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
+				exit_usage(1);
+			}
+			chk_known_plugin(*argv);
+			chk_arg_len(*argv, PLUGIN_MAXBUF);
+			if (*++argv == NULL || strcmp(*argv, "active") != 0 &&
+			    strcmp(*argv, "inactive") != 0) {
+				exit_usage(1);
+			}
+			if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
+				--argv;
+				break;
+			}
+			chk_arg_len(*argv, PLUGIN_MAXATT);
+			if (*++argv == NULL || get_arg_ent(*argv) != NULL) {
+				--argv;
+				break;
+			}
+			if (atoi(*argv) < 0) {
+				exit_error(gettext("Incorrect qsize specified "
+				    "(%s)."), *argv);
+			}
 			break;
 
 		case AC_ARG_SETPOLICY:
@@ -445,7 +524,7 @@
 			++argv;
 			if (!*argv)
 				exit_usage(1);
-			str2mask(*argv, &mask);
+			echkflags(*argv, mask);
 			break;
 
 		case AC_ARG_SETQBUFSZ:
@@ -517,7 +596,7 @@
 			++argv;
 			if (!*argv)
 				exit_usage(1);
-			str2mask(*argv, &mask);
+			echkflags(*argv, mask);
 			break;
 
 		case AC_ARG_SET_TEMPORARY:
@@ -545,7 +624,7 @@
  * otherwise.
  */
 static void
-do_args(char **argv)
+do_args(char **argv, au_mask_t *mask)
 {
 	arg_entry_t	*ae;
 
@@ -623,10 +702,37 @@
 			do_getcwd();
 			break;
 
+		case AC_ARG_GETFLAGS:
+			do_getflags();
+			break;
+
 		case AC_ARG_GETKMASK:
 			do_getkmask();
 			break;
 
+		case AC_ARG_GETNAFLAGS:
+			do_getnaflags();
+			break;
+
+		case AC_ARG_GETPLUGIN:
+			{
+				char	*plugin_str = NULL;
+
+				++argv;
+				if (*argv != NULL) {
+					if (get_arg_ent(*argv) != NULL) {
+						--argv;
+					} else {
+						plugin_str = *argv;
+					}
+				} else {
+					--argv;
+				}
+
+				do_getplugin(plugin_str);
+			}
+			break;
+
 		case AC_ARG_GETPOLICY:
 			do_getpolicy();
 			break;
@@ -722,17 +828,58 @@
 
 		case AC_ARG_SETCLASS:
 			{
-				char *event_str, *audit_flags;
-
-				++argv; event_str = *argv;
-				++argv; audit_flags = *argv;
-				do_setclass(event_str, audit_flags);
+				char *event_str;
+
+				++argv;
+				event_str = *argv;
+				do_setclass(event_str, mask);
+
+				++argv;
 			}
 			break;
 
+		case AC_ARG_SETFLAGS:
+			++argv;
+			do_setflags(*argv, mask);
+			break;
+
 		case AC_ARG_SETKMASK:
 			++argv;
-			do_setkmask(*argv);
+			do_setkmask(mask);
+			break;
+
+		case AC_ARG_SETNAFLAGS:
+			++argv;
+			do_setnaflags(*argv, mask);
+			break;
+
+		case AC_ARG_SETPLUGIN:
+			{
+				char		*plugin_str = NULL;
+				boolean_t	plugin_state = B_FALSE;
+				char 		*plugin_att = NULL;
+				int 		plugin_qsize = -1;
+
+				plugin_str = *++argv;
+				if (strcmp(*++argv, "active") == 0) {
+					plugin_state = B_TRUE;
+				}
+				if (*++argv != NULL &&
+				    get_arg_ent(*argv) == NULL) {
+					plugin_att = *argv;
+					if (*++argv != NULL &&
+					    get_arg_ent(*argv) == NULL) {
+						plugin_qsize = atoi(*argv);
+					} else {
+						--argv;
+					}
+				} else {
+					--argv;
+				}
+
+				do_setplugin(plugin_str, plugin_state,
+				    plugin_att, plugin_qsize);
+			}
 			break;
 
 		case AC_ARG_SETPOLICY:
@@ -753,13 +900,12 @@
 		case AC_ARG_SETPMASK:
 			{
 				char *pid_str;
-				char *audit_flags;
 
 				++argv;
 				pid_str = *argv;
+				do_setpmask(pid_str, mask);
+
 				++argv;
-				audit_flags = *argv;
-				do_setpmask(pid_str, audit_flags);
 			}
 			break;
 
@@ -801,25 +947,23 @@
 		case AC_ARG_SETSMASK:
 			{
 				char *asid_str;
-				char *audit_flags;
 
 				++argv;
 				asid_str = *argv;
+				do_setsmask(asid_str, mask);
+
 				++argv;
-				audit_flags = *argv;
-				do_setsmask(asid_str, audit_flags);
 			}
 			break;
 		case AC_ARG_SETUMASK:
 			{
 				char *auid_str;
-				char *audit_flags;
 
 				++argv;
 				auid_str = *argv;
+				do_setumask(auid_str, mask);
+
 				++argv;
-				audit_flags = *argv;
-				do_setumask(auid_str, audit_flags);
 			}
 			break;
 		case AC_ARG_SET_TEMPORARY:
@@ -916,7 +1060,7 @@
 			++i;
 			ec.ec_number = evp->ae_number;
 			ec.ec_class = evp->ae_class;
-			eauditon(A_SETCLASS, (caddr_t)&ec, (int)sizeof (ec));
+			eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
 		}
 	}
 	endauevent();
@@ -932,35 +1076,33 @@
 static void
 do_chkaconf(void)
 {
-	char 		buf[1024];
+	char		*namask_cfg;
 	au_mask_t 	pmask, kmask;
 
-	if (getacna(buf, sizeof (buf)) < 0) {
-		(void) fprintf(stderr,
-		    gettext("bad non-attributable flags in audit_control\n"));
-		exit(1);
+	if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
+		exit_error(gettext("Could not get configured value."));
 	}
-
-	if (getauditflagsbin(buf, &pmask) < 0) {
-		(void) fprintf(stderr,
-		    gettext("bad audit flag value encountered\n"));
-		exit(1);
-	}
-
-	eauditon(A_GETKMASK, (caddr_t)&kmask, (int)sizeof (kmask));
+	egetauditflagsbin(namask_cfg, &pmask);
+
+	eauditon(A_GETKMASK, (caddr_t)&kmask, sizeof (kmask));
 
 	if ((pmask.am_success != kmask.am_success) ||
 	    (pmask.am_failure != kmask.am_failure)) {
 		char kbuf[2048];
 		if (getauditflagschar(kbuf, &kmask, 0) < 0) {
+			free(namask_cfg);
 			(void) fprintf(stderr,
 			    gettext("bad kernel non-attributable mask\n"));
 			exit(1);
 		}
-		(void) printf(gettext("non-attributable event mismatch "));
-		(void) printf(gettext("audit_control(%s) kernel(%s)\n"),
-		    buf, kbuf);
+		(void) printf(
+		    gettext("non-attributable event flags mismatch:\n"));
+		(void) printf(gettext("active non-attributable audit flags "
+		    "= %s\n"), kbuf);
+		(void) printf(gettext("configured non-attributable audit flags "
+		    "= %s\n"), namask_cfg);
 	}
+	free(namask_cfg);
 }
 
 /*
@@ -970,23 +1112,17 @@
 static void
 do_aconf(void)
 {
-	char buf[2048];
-	au_mask_t pmask;
-
-	if (getacna(buf, sizeof (buf)) < 0) {
-		(void) fprintf(stderr,
-		    gettext("bad non-attributable flags in audit_control\n"));
-		exit(1);
+	au_mask_t 	namask;
+	char		*namask_cfg;
+
+	if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
+		exit_error(gettext("Could not get configured value."));
 	}
-
-	if (getauditflagsbin(buf, &pmask) < 0) {
-		(void) fprintf(stderr,
-		    gettext("bad audit flag value encountered\n"));
-		exit(1);
-	}
-
-	eauditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
-	(void) printf(gettext("Configured non-attributable events.\n"));
+	egetauditflagsbin(namask_cfg, &namask);
+	free(namask_cfg);
+
+	eauditon(A_SETKMASK, (caddr_t)&namask, sizeof (namask));
+	(void) printf(gettext("Configured non-attributable event mask.\n"));
 }
 
 /*
@@ -1140,7 +1276,7 @@
 {
 	char path[MAXPATHLEN];
 
-	eauditon(A_GETCAR, (caddr_t)path, (int)sizeof (path));
+	eauditon(A_GETCAR, (caddr_t)path, sizeof (path));
 	(void) printf(gettext("current active root = %s\n"), path);
 }
 
@@ -1198,11 +1334,32 @@
 {
 	char path[MAXPATHLEN];
 
-	eauditon(A_GETCWD, (caddr_t)path, (int)sizeof (path));
+	eauditon(A_GETCWD, (caddr_t)path, sizeof (path));
 	(void) printf(gettext("current working directory = %s\n"), path);
 }
 
 /*
+ * do_getflags() - the printed value is for the global zone unless AUDIT_PERZONE
+ * is set.
+ */
+static void
+do_getflags(void)
+{
+	au_mask_t	amask;
+	char		*amask_cfg;
+
+	eauditon(A_GETAMASK, (caddr_t)&amask, sizeof (amask));
+	print_mask(gettext("active user default audit flags"), &amask);
+
+	if (!do_getflags_scf(&amask_cfg) || amask_cfg == NULL) {
+		exit_error(gettext("Could not get configured value."));
+	}
+	egetauditflagsbin(amask_cfg, &amask);
+	print_mask(gettext("configured user default audit flags"), &amask);
+	free(amask_cfg);
+}
+
+/*
  * do_getkmask() - the printed value is for the global zone unless AUDIT_PERZONE
  * is set.
  */
@@ -1211,8 +1368,29 @@
 {
 	au_mask_t pmask;
 
-	eauditon(A_GETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
-	print_mask(gettext("audit flags for non-attributable events"), &pmask);
+	eauditon(A_GETKMASK, (caddr_t)&pmask, sizeof (pmask));
+	print_mask(gettext("active non-attributable audit flags"), &pmask);
+}
+
+/*
+ * do_getnaflags() - the printed value is for the global zone unless
+ * AUDIT_PERZONE is set.
+ */
+static void
+do_getnaflags(void)
+{
+	au_mask_t	namask;
+	char		*namask_cfg;
+
+	eauditon(A_GETKMASK, (caddr_t)&namask, sizeof (namask));
+	print_mask(gettext("active non-attributable audit flags"), &namask);
+
+	if (!do_getnaflags_scf(&namask_cfg) || namask_cfg == NULL) {
+		exit_error(gettext("Could not get configured value."));
+	}
+	egetauditflagsbin(namask_cfg, &namask);
+	print_mask(gettext("configured non-attributable audit flags"), &namask);
+	free(namask_cfg);
 }
 
 /*
@@ -1263,6 +1441,32 @@
 }
 
 /*
+ * do_getplugin() - print plugin configuration.
+ */
+static void
+do_getplugin(char *plugin_str)
+{
+	scf_plugin_kva_node_t	*plugin_kva_ll;
+	scf_plugin_kva_node_t	*plugin_kva_ll_head;
+
+	if (!do_getpluginconfig_scf(plugin_str, &plugin_kva_ll)) {
+		exit_error(gettext("Could not get plugin configuration."));
+	}
+
+	plugin_kva_ll_head = plugin_kva_ll;
+
+	while (plugin_kva_ll != NULL) {
+		print_plugin(plugin_kva_ll->plugin_name,
+		    plugin_kva_ll->plugin_kva);
+		plugin_kva_ll = plugin_kva_ll->next;
+		if (plugin_kva_ll != NULL) {
+			(void) printf("\n");
+		}
+	}
+	plugin_kva_ll_free(plugin_kva_ll_head);
+}
+
+/*
  * do_getqbufsz() - print the active and configured audit queue write buffer
  * size relative to the current zone.
  */
@@ -1583,7 +1787,7 @@
 	auditinfo_addr_t ai;
 
 	ai.ai_auid = (au_id_t)get_user_id(user_str);
-	str2mask(mask_str, &ai.ai_mask),
+	egetauditflagsbin(mask_str, &ai.ai_mask),
 	    str2tid(tid_str, &ai.ai_termid);
 	ai.ai_asid = (au_asid_t)atol(sid_str);
 
@@ -1609,18 +1813,20 @@
  * per zone if AUDIT_PERZONE is set, else only in global zone.
  */
 static void
-do_setpmask(char *pid_str, char *audit_flags)
+do_setpmask(char *pid_str, au_mask_t *mask)
 {
 	struct auditpinfo ap;
 
-	if (strisnum(pid_str))
+	if (strisnum(pid_str)) {
 		ap.ap_pid = (pid_t)atoi(pid_str);
-	else
+	} else {
 		exit_usage(1);
-
-	str2mask(audit_flags, &ap.ap_mask);
-
-	eauditon(A_SETPMASK, (caddr_t)&ap, (int)sizeof (ap));
+	}
+
+	ap.ap_mask.am_success = mask->am_success;
+	ap.ap_mask.am_failure = mask->am_failure;
+
+	eauditon(A_SETPMASK, (caddr_t)&ap, sizeof (ap));
 }
 
 /*
@@ -1629,18 +1835,20 @@
  * zone.
  */
 static void
-do_setsmask(char *asid_str, char *audit_flags)
+do_setsmask(char *asid_str, au_mask_t *mask)
 {
 	struct auditinfo ainfo;
 
-	if (strisnum(asid_str))
+	if (strisnum(asid_str)) {
 		ainfo.ai_asid = (au_asid_t)atoi(asid_str);
-	else
+	} else {
 		exit_usage(1);
-
-	str2mask(audit_flags, &ainfo.ai_mask);
-
-	eauditon(A_SETSMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
+	}
+
+	ainfo.ai_mask.am_success = mask->am_success;
+	ainfo.ai_mask.am_failure = mask->am_failure;
+
+	eauditon(A_SETSMASK, (caddr_t)&ainfo, sizeof (ainfo));
 }
 
 /*
@@ -1649,18 +1857,20 @@
  * global zone.
  */
 static void
-do_setumask(char *auid_str, char *audit_flags)
+do_setumask(char *auid_str, au_mask_t *mask)
 {
 	struct auditinfo ainfo;
 
-	if (strisnum(auid_str))
+	if (strisnum(auid_str)) {
 		ainfo.ai_auid = (au_id_t)atoi(auid_str);
-	else
+	} else {
 		exit_usage(1);
-
-	str2mask(audit_flags, &ainfo.ai_mask);
-
-	eauditon(A_SETUMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
+	}
+
+	ainfo.ai_mask.am_success = mask->am_success;
+	ainfo.ai_mask.am_failure = mask->am_failure;
+
+	eauditon(A_SETUMASK, (caddr_t)&ainfo, sizeof (ainfo));
 }
 
 /*
@@ -1684,55 +1894,91 @@
 	as.as_wblocked	= (uint_t)-1;
 	as.as_written	= (uint_t)-1;
 
-	eauditon(A_SETSTAT, (caddr_t)&as, (int)sizeof (as));
+	eauditon(A_SETSTAT, (caddr_t)&as, sizeof (as));
 	(void) printf("%s\n", gettext("audit stats reset"));
 }
 
 /*
  * do_setclass() - map the kernel event event_str to the classes specified by
- * audit flags audit_flags; valid per zone if AUDIT_PERZONE is set, else only in
+ * audit flags (mask); valid per zone if AUDIT_PERZONE is set, else only in
  * global zone.
  */
 static void
-do_setclass(char *event_str, char *audit_flags)
+do_setclass(char *event_str, au_mask_t *mask)
 {
 	au_event_t event;
-	int mask;
-	au_mask_t pmask;
 	au_evclass_map_t ec;
 	au_event_ent_t *evp;
 
-	if (strisnum(event_str))
+	if (strisnum(event_str)) {
 		event = (uint_t)atol(event_str);
-	else {
-		if ((evp = egetauevnam(event_str)) != NULL)
+	} else {
+		if ((evp = egetauevnam(event_str)) != NULL) {
 			event = evp->ae_number;
-	}
-
-	if (strisnum(audit_flags))
-		mask = atoi(audit_flags);
-	else {
-		str2mask(audit_flags, &pmask);
-		mask = pmask.am_success | pmask.am_failure;
+		}
 	}
 
 	ec.ec_number = event;
-	ec.ec_class = mask;
-	eauditon(A_SETCLASS, (caddr_t)&ec, (int)sizeof (ec));
+	ec.ec_class = (mask->am_success | mask->am_failure);
+
+	eauditon(A_SETCLASS, (caddr_t)&ec, sizeof (ec));
+}
+
+/*
+ * do_setflags() - set configured and active default user preselection masks;
+ * valid per zone if AUDIT_PERZONE is set, else only in global zone.
+ */
+static void
+do_setflags(char *audit_flags, au_mask_t *amask)
+{
+	eauditon(A_SETAMASK, (caddr_t)amask, sizeof (*amask));
+
+	if (!do_setflags_scf(audit_flags)) {
+		print_mask(gettext("active user default audit flags"), amask);
+		exit_error(gettext("Could not store configuration value."));
+	}
+	print_mask(gettext("user default audit flags"), amask);
 }
 
 /*
- * do_setkmask() - set non-attributes selection flags of machine; valid per zone
+ * do_setkmask() - set non-attributable audit flags of machine; valid per zone
  * if AUDIT_PERZONE is set, else only in global zone.
  */
 static void
-do_setkmask(char *audit_flags)
+do_setkmask(au_mask_t *pmask)
+{
+	eauditon(A_SETKMASK, (caddr_t)pmask, sizeof (*pmask));
+	print_mask(gettext("active non-attributable audit flags"), pmask);
+}
+
+/*
+ * do_setnaflags() - set configured and active non-attributable selection flags
+ * of machine; valid per zone if AUDIT_PERZONE is set, else only in global zone.
+ */
+static void
+do_setnaflags(char *audit_naflags, au_mask_t *namask)
 {
-	au_mask_t pmask;
-
-	str2mask(audit_flags, &pmask);
-	eauditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
-	print_mask(gettext("audit flags for non-attributable events"), &pmask);
+	eauditon(A_SETKMASK, (caddr_t)namask, sizeof (*namask));
+
+	if (!do_setnaflags_scf(audit_naflags)) {
+		print_mask(
+		    gettext("active non-attributable audit flags"), namask);
+		exit_error(gettext("Could not store configuration value."));
+	}
+	print_mask(gettext("non-attributable audit flags"), namask);
+}
+
+/*
+ * do_setplugin() - set the given plugin plugin_str configuration values.
+ */
+static void
+do_setplugin(char *plugin_str, boolean_t plugin_state, char *plugin_attr,
+    int plugin_qsize)
+{
+	if (!do_setpluginconfig_scf(plugin_str, plugin_state, plugin_attr,
+	    plugin_qsize)) {
+		exit_error(gettext("Could not set plugin configuration."));
+	}
 }
 
 /*
@@ -1961,10 +2207,10 @@
 static void
 egetauditflagsbin(char *auditflags, au_mask_t *pmask)
 {
-	pmask->am_success = pmask->am_failure = 0;
-
-	if (strcmp(auditflags, "none") == 0)
+	if (strcmp(auditflags, "none") == 0) {
+		pmask->am_success = pmask->am_failure = 0;
 		return;
+	}
 
 	if (getauditflagsbin(auditflags, pmask) < 0) {
 		exit_error(gettext("Could not get audit flags (%s)"),
@@ -1972,6 +2218,23 @@
 	}
 }
 
+static void
+echkflags(char *auditflags, au_mask_t *mask)
+{
+	char		*err = "";
+	char		*err_ptr;
+
+	if (!__chkflags(auditflags, mask, B_FALSE, &err)) {
+		err_ptr = err;
+		while (*err_ptr != ',' && *err_ptr != '\0') {
+			err_ptr++;
+		}
+		*err_ptr = '\0';
+		exit_error(gettext("Unknown audit flags and/or prefixes "
+		    "encountered: %s"), err);
+	}
+}
+
 static au_event_ent_t *
 egetauevnum(au_event_t event_number)
 {
@@ -2063,47 +2326,6 @@
 }
 
 /*
- * Convert mask of the following forms:
- *
- *    audit_flags (ie. +lo,-ad,pc)
- *    0xffffffff,0xffffffff
- *    ffffffff,ffffffff
- *    20,20
- */
-static void
-str2mask(char *mask_str, au_mask_t *mp)
-{
-
-	char sp[256];
-	char fp[256];
-
-	mp->am_success = 0;
-	mp->am_failure = 0;
-
-	/*
-	 * a mask of the form +aa,bb,cc,-dd or
-	 * a mask of the form 0xffffffff,0xffffffff or 1,1
-	 */
-	if (strisflags(mask_str)) {
-		egetauditflagsbin(mask_str, mp);
-	} else {
-		strsplit(mask_str, sp, fp, ',');
-
-		if (strlen(sp) > (size_t)2 && !strncasecmp(sp, "0x", 2)) {
-			(void) sscanf(sp + 2, "%x", &mp->am_success);
-		} else {
-			(void) sscanf(sp, "%u", &mp->am_success);
-		}
-
-		if (strlen(fp) > (size_t)2 && !strncasecmp(fp, "0x", 2)) {
-			(void) sscanf(fp + 2, "%x", &mp->am_failure);
-		} else {
-			(void) sscanf(fp, "%u", &mp->am_failure);
-		}
-	}
-}
-
-/*
  * tid_str is major,minor,host  -- host is a name or an ip address
  */
 static void
@@ -2189,7 +2411,7 @@
 {
 	uint_t cond;
 
-	eauditon(A_GETCOND, (caddr_t)&cond, (int)sizeof (cond));
+	eauditon(A_GETCOND, (caddr_t)&cond, sizeof (cond));
 
 	switch (cond) {
 
@@ -2363,21 +2585,6 @@
 }
 
 static int
-strisflags(char *s)
-{
-	if (s == NULL || !*s)
-		return (0);
-
-	for (; *s; s++) {
-		if (!isalpha(*s) &&
-		    (*s != '+' && *s != '-' && *s != '^' && *s != ','))
-			return (0);
-	}
-
-	return (1);
-}
-
-static int
 strisipaddr(char *s)
 {
 	int dot = 0;
@@ -2406,18 +2613,12 @@
 }
 
 static void
-strsplit(char *s, char *p1, char *p2, char c)
+chk_arg_len(char *argv, uint_t len)
 {
-	*p1 = *p2 = '\0';
-
-	while (*s != '\0' && *s != c)
-		*p1++ = *s++;
-	*p1 = '\0';
-	s++;
-
-	while (*s != '\0')
-		*p2++ = *s++;
-	*p2 = '\0';
+	if ((strlen(argv) + 1) > len) {
+		*(argv + len - 1) = '\0';
+		exit_error(gettext("Argument too long (%s..)."), argv);
+	}
 }
 
 static void
@@ -2467,6 +2668,19 @@
 }
 
 static void
+chk_known_plugin(char *plugin_str)
+{
+	if ((strlen(plugin_str) + 1) > PLUGIN_MAXBUF) {
+		exit_error(gettext("Plugin name too long.\n"));
+	}
+
+	if (!plugin_avail_scf(plugin_str)) {
+		exit_error(gettext("No such plugin configured: %s"),
+		    plugin_str);
+	}
+}
+
+static void
 chk_sorf(char *sorf_str)
 {
 	if (!strisnum(sorf_str))
@@ -2569,6 +2783,48 @@
 }
 
 static void
+print_plugin(char *plugin_name, kva_t *plugin_kva)
+{
+	char		att_str[PLUGIN_MAXATT];
+	boolean_t	plugin_active;
+	char		*active_str;
+	char		*qsize_ptr;
+	int		qsize;
+
+	if ((active_str = kva_match(plugin_kva, "active")) == NULL) {
+		(void) printf(gettext("Audit service configuration error: "
+		    "\"active\" property not found\n"));
+		return;
+	}
+
+	plugin_active = (boolean_t)atoi(active_str);
+	qsize_ptr = kva_match(plugin_kva, "qsize");
+	qsize = atoi(qsize_ptr == NULL ? "-1" : qsize_ptr);
+
+	(void) printf(gettext("Plugin: %s (%s)\n"), plugin_name,
+	    plugin_active ? "active" : "inactive");
+
+	free_static_att_kva(plugin_kva);
+
+	switch (_kva2str(plugin_kva, att_str, PLUGIN_MAXATT, "=", ";")) {
+	case 0:
+		(void) printf(gettext("\tAttributes: %s\n"), att_str);
+		break;
+	case 1:
+		exit_error(gettext("Internal error - buffer size too small."));
+		break;
+	default:
+		exit_error(gettext("Internal error."));
+		break;
+	}
+
+	if (qsize != 0) {
+		(void) printf(gettext("\tQueue size: %d %s\n"), qsize,
+		    qsize == -1 ? "(internal error: value not available)" : "");
+	}
+}
+
+static void
 print_tid_ex(au_tid_addr_t *tidp)
 {
 	struct hostent *phe;
--- a/usr/src/cmd/auditconfig/auditconfig_impl.h	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef	_AUDITCONFIG_IMPL_H
-#define	_AUDITCONFIG_IMPL_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <bsm/audit.h>
-#include <bsm/libbsm.h>
-
-#define	ALL_POLICIES   (AUDIT_AHLT|\
-			AUDIT_ARGE|\
-			AUDIT_ARGV|\
-			AUDIT_CNT|\
-			AUDIT_GROUP|\
-			AUDIT_SEQ|\
-			AUDIT_TRAIL|\
-			AUDIT_PATH|\
-			AUDIT_PUBLIC|\
-			AUDIT_ZONENAME|\
-			AUDIT_PERZONE|\
-			AUDIT_WINDATA_DOWN|\
-			AUDIT_WINDATA_UP)
-
-#define	NO_POLICIES  (0)
-
-struct policy_entry {
-	char *policy_str;
-	uint32_t policy_mask;
-	char *policy_desc;
-};
-typedef struct policy_entry policy_entry_t;
-
-static policy_entry_t policy_table[] = {
-	{"ahlt",  AUDIT_AHLT,   "halt machine if it can not record an "
-	    "async event"},
-	{"all",   ALL_POLICIES,	"all policies"},
-	{"arge",  AUDIT_ARGE,   "include exec environment args in audit recs"},
-	{"argv",  AUDIT_ARGV,   "include exec command line args in audit recs"},
-	{"cnt",   AUDIT_CNT,    "when no more space, drop recs and keep a cnt"},
-	{"group", AUDIT_GROUP,	"include supplementary groups in audit recs"},
-	{"none",  NO_POLICIES,	"no policies"},
-	{"path",  AUDIT_PATH,	"allow multiple paths per event"},
-	{"perzone", AUDIT_PERZONE,      "use a separate queue and auditd per "
-	    "zone"},
-	{"public",  AUDIT_PUBLIC,    "audit public files"},
-	{"seq",   AUDIT_SEQ,    "include a sequence number in audit recs"},
-	{"trail", AUDIT_TRAIL,	"include trailer token in audit recs"},
-	{"windata_down", AUDIT_WINDATA_DOWN,  "include downgraded window "
-	    "information in audit recs"},
-	{"windata_up",  AUDIT_WINDATA_UP,     "include upgraded window "
-	    "information in audit recs"},
-	{"zonename", AUDIT_ZONENAME,    "include zonename token in audit recs"}
-};
-
-#define	POLICY_TBL_SZ (sizeof (policy_table) / sizeof (policy_entry_t))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* _AUDITCONFIG_IMPL_H */
--- a/usr/src/cmd/auditd/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 PROG = auditd
@@ -33,16 +32,15 @@
 ROOTMANIFESTDIR = $(ROOTSVCSYSTEM)
 
 LIBBSM = $(SRC)/lib/libbsm/common
-AUDITCONFIG = $(SRC)/cmd/auditconfig
 AUDITD = $(SRC)/cmd/auditd
 
 CPPFLAGS += -D_REENTRANT
-CPPFLAGS += -I$(LIBBSM) -I$(AUDITCONFIG) -I$(AUDITD)
+CPPFLAGS += -I$(LIBBSM) -I$(AUDITD)
 
-LDLIBS += -lbsm -lsecdb -lscf
+LDLIBS += -lbsm -lsecdb
 
-OBJS = audit_scf_shared.o auditd.o doorway.o queue.o
-SRCS = $(AUDITCONFIG)/audit_scf_shared.c auditd.c doorway.c queue.c
+OBJS = auditd.o doorway.o queue.o
+SRCS = $(OBJS:%.o=%.c)
 
 POFILE =	$(PROG).po
 MSGFILES =	$(SRCS)
@@ -58,9 +56,6 @@
 		$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
 		$(POST_PROCESS)
 
-audit_scf%.o:
-		$(COMPILE.c) $(AUDITCONFIG)/$(@:%.o=%.c)
-
 lint:		lint_SRCS
 
 $(POFILE): $(MSGFILES)
--- a/usr/src/cmd/auditd/audit_sig_infc.h	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
- * defines auditd interface for cmd/audit; project private.
- */
-
-#ifndef	_AUDIT_SIG_INFC_H
-#define	_AUDIT_SIG_INFC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <signal.h>
-
-/*
- * SMF definitions
- */
-
-#define	AUDITD_FMRI \
-	"svc:/system/auditd:default"
-
-/*
- * Signals
- */
-#define	AU_SIG_NEXT_DIR		SIGUSR1	/* audit -n */
-#define	AU_SIG_READ_CONTROL	SIGHUP	/* audit -s */
-#define	AU_SIG_DISABLE		SIGTERM	/* audit -t */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* _AUDIT_SIG_INFC_H */
--- a/usr/src/cmd/auditd/auditd.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/auditd.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Audit daemon server */
@@ -30,14 +29,12 @@
  * audit records (usually one or more per buffer, potentially less than
  * one) and passes them to one or more plugins for processing.
  *
- * The major interrupts are AU_SIG_READ_CONTROL (start over),
- * AU_SIG_DISABLE (start shutting down), SIGALRM (quit), and
- * AU_SIG_NEXT_DIR (start a new audit log file). SIGTERM (the implementation
- * value of AU_SIG_DISABLE) is also used for the child to tell the parent
- * that audit is ready.
+ * The major interrupts are SIGHUP (start over), SIGTERM (start shutting down),
+ * SIGALRM (quit), and SIGUSR1 (start a new audit log file). SIGTERM is also
+ * used for the child to tell the parent that audit is ready.
  *
- * Configuration data comes from /etc/security/audit_control and the auditon
- * system call.
+ * Configuration data comes from audit service configuration
+ * (AUDITD_FMRI/smf(5)) and the auditon system call.
  *
  * The major errors are EBUSY (auditing is already in use) and EINTR
  * (one of the above signals was received).  File space errors are
@@ -76,7 +73,6 @@
 #include <termios.h>
 #include <unistd.h>
 #include "plugin.h"
-#include "audit_sig_infc.h"
 #include <audit_plugin.h>
 #include <audit_scf.h>
 
@@ -84,10 +80,10 @@
 #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
 #endif
 /*
- * After we get a AU_SIG_DISABLE, we want to set a timer for 2 seconds
+ * After we get a SIGTERM, we want to set a timer for 2 seconds
  * and let c2audit write as many records as it can until the timer
- * goes off(at which point it returns to auditd with SIGALRM).  If any
- * other signals are received during that time, we call
+ * goes off (at which point it returns to auditd with SIGALRM).
+ * If any other signals are received during that time, we call
  * __audit_dowarn() to indicate that the queue may not have been fully
  * flushed.
  */
@@ -109,11 +105,11 @@
 pthread_mutex_t		plugin_mutex;	/* for plugin_t list */
 
 static int	caught_alrm = 0;	/* number of SIGALRMs pending */
-static int	caught_readc = 0;	/* number of AU_SIG_READ_CONTROLs */
-static int	caught_term = 0;	/* number of AU_SIG_DISABLEs pending */
-static int	caught_nextd = 0;	/* number of AU_SIG_NEXT_DIRs pending */
+static int	caught_readc = 0;	/* number of SIGHUPs pending */
+static int	caught_term = 0;	/* number of SIGTERMs pending */
+static int	caught_nextd = 0;	/* number of SIGUSR1s pending */
 
-static int	reset_list = 1;	/* 1 to re-read audit_control */
+static int	reset_list = 1;	/* 1 to re-read audit configuration */
 static int	reset_file = 1; /* 1 to close/open binary log */
 
 static int	auditing_set = 0;	/* 1 if auditon(A_SETCOND, on... */
@@ -125,7 +121,6 @@
 static int	do_sethost();
 
 static void	conf_to_kernel();
-static void	aconf_to_kernel();
 static void	scf_to_kernel_qctrl();
 static void	scf_to_kernel_policy();
 
@@ -164,7 +159,7 @@
 
 	if (auditing_set)
 		(void) auditon(A_SETCOND, (caddr_t)&turn_audit_off,
-		    (int)sizeof (int));
+		    sizeof (int));
 
 #if DEBUG
 	(void) fclose(dbfp);
@@ -220,7 +215,7 @@
 	/*
 	 * Set the audit state flag to AUDITING.
 	 */
-	if (auditon(A_SETCOND, (caddr_t)&turn_audit_on, (int)sizeof (int)) !=
+	if (auditon(A_SETCOND, (caddr_t)&turn_audit_on, sizeof (int)) !=
 	    0) {
 		DPRINT((dbfp, "auditon(A_SETCOND...) failed (exit)\n"));
 		__audit_dowarn("nostart", "", 0);
@@ -237,9 +232,9 @@
 		int		signal_caught = 0;
 
 		(void) sigemptyset(&set);
-		(void) sigaddset(&set, AU_SIG_DISABLE);
+		(void) sigaddset(&set, SIGTERM);
 
-		while (signal_caught != AU_SIG_DISABLE)
+		while (signal_caught != SIGTERM)
 			signal_caught = sigwait(&set);
 
 		DPRINT((dbfp, "init complete:  parent can now exit\n"));
@@ -279,18 +274,19 @@
 	 */
 	(void) umask(007);
 
-	if (__logpost("")) {	/* Cannot unlink pointer to audit.log file. */
+	if (__logpost("")) {	/* Cannot unlink pointer to audit.log(4) file */
 		DPRINT((dbfp, "logpost failed\n"));
 		auditd_exit(1);
 	}
 	/*
-	 * Here is the main body of the audit daemon.  running == 0 means that
-	 * after flushing out the audit queue, it is time to exit in response to
-	 * AU_SIG_DISABLE
+	 * Here is the main body of the audit daemon. running == 0 means that
+	 * after flushing out the audit queue, it is time to exit in response
+	 * to SIGTERM.
 	 */
 	while (running) {
 		/*
-		 * Read audit_control and create plugin lists.
+		 * Read auditd / auditd plugins related configuration from
+		 * smf(5) repository and create plugin lists.
 		 *
 		 * loadauditlist() and auditd_thread_init() are called
 		 * while under the plugin_mutex lock to avoid a race
@@ -299,7 +295,6 @@
 		if (reset_list || reset_file) {
 			if (reset_list) {
 				conf_to_kernel();
-				aconf_to_kernel();
 				scf_to_kernel_qctrl();
 				scf_to_kernel_policy();
 				(void) pthread_mutex_lock(&plugin_mutex);
@@ -313,13 +308,15 @@
 				/* continue; wait for audit -s */
 			}
 			(void) pthread_mutex_unlock(&plugin_mutex);
-			reset_list = 0;
 
 			if (reset_list && reset_file) {
 				(void) printf(gettext("auditd started\n"));
 			} else {
 				(void) printf(gettext("auditd refreshed\n"));
 			}
+
+			reset_list = 0;
+			reset_file = 0;
 		}
 		/*
 		 * tell parent I'm running whether or not the initialization
@@ -327,14 +324,14 @@
 		 * audit -n or audit -s to fix the problem.
 		 */
 		if (pid != 0) {
-			(void) kill(pid, AU_SIG_DISABLE);
+			(void) kill(pid, SIGTERM);
 			pid = 0;
 		}
 		/*
 		 * thread_signal() signals main (this thread) when
 		 * it has received a signal.
 		 */
-		DPRINT((dbfp, "main thread is waiting\n"));
+		DPRINT((dbfp, "main thread is waiting for signal\n"));
 		(void) pthread_mutex_lock(&(main_thr.thd_mutex));
 
 		if (!(caught_readc || caught_term || caught_alrm ||
@@ -400,19 +397,20 @@
 			 * if both hup and usr1 are caught, the logic in
 			 * loadauditlist() results in hup winning.  The
 			 * result will be that the audit file is not rolled
-			 * over unless audit_control actually changed.
+			 * over unless audit configuration actually changed.
 			 *
-			 * They want to reread the audit_control file.
-			 * Set reset_list which will return us to the
-			 * main while loop in the main routine.
+			 * They want to reread the audit configuration from
+			 * smf(5) repository (AUDITD_FMRI). Set reset_list
+			 * which will return us to the main while loop in the
+			 * main routine.
 			 */
 			caught_readc = 0;
 			reset_list = 1;
 		} else if (caught_nextd) {
 			/*
-			 * This is a special case for the binfile
-			 * plugin. (audit -n)  NULL out kvlist
-			 * so binfile won't re-read audit_control
+			 * This is a special case for the binfile plugin.
+			 * (audit -n)  NULL out kvlist so binfile won't
+			 * re-read audit configuration.
 			 */
 			caught_nextd = 0;
 			reset_file = 1;
@@ -450,14 +448,14 @@
 	(void) pthread_mutex_unlock(&(main_thr.thd_mutex));
 
 	if (caught_term) {
-		DPRINT((dbfp, "normal AU_SIG_DISABLE exit\n"));
+		DPRINT((dbfp, "normal SIGTERM exit\n"));
 		/*
 		 * Exit, as requested.
 		 */
 		auditd_thread_close();
 	}
 	if (caught_readc)
-		reset_list = 1;		/* Reread the audit_control file */
+		reset_list = 1;		/* Reread the audit configuration */
 
 	caught_readc = 0;
 	caught_nextd = 0;
@@ -487,11 +485,11 @@
 }
 
 /*
- * init_plugin first searches the existing plugin list to see
- * if the plugin already has been defined; if not, it creates it
- * and links it into the list.  It returns a pointer to the found
- * or created struct.  A change of path in audit_control for a
- * given plugin will cause a miss.
+ * init_plugin first searches the existing plugin list to see if the plugin
+ * already has been defined; if not, it creates it and links it into the list.
+ * It returns a pointer to the found or created struct. Note, that
+ * (manual/unsupported) change of path property in audit service configuration
+ * for given plugin will cause a miss.
  */
 /*
  * for 64 bits, the path name can grow 3 bytes (minus 5 for the
@@ -530,7 +528,10 @@
 				p->plg_cnt = cnt_flag;
 
 				_kva_free(p->plg_kvlist);
-				p->plg_kvlist = list;
+				p->plg_kvlist = _kva_dup(list);
+				if (list != NULL && p->plg_kvlist == NULL) {
+					err_exit(NULL);
+				}
 				p->plg_reopen = 1;
 				DPRINT((dbfp, "reusing %s\n", p->plg_path));
 				return (p);
@@ -564,48 +565,37 @@
 	p->plg_sequence = 1;
 	p->plg_last_seq_out = 0;
 	p->plg_path = strdup(path);
-	p->plg_kvlist = list;
+	p->plg_kvlist = _kva_dup(list);
 	p->plg_cnt = cnt_flag;
 	p->plg_retry_time = SLEEP_TIME;
 	p->plg_qmax = 0;
 	p->plg_save_q_copy = NULL;
 
+	if (list != NULL && p->plg_kvlist == NULL || p->plg_path == NULL) {
+		err_exit(NULL);
+	}
+
 	DPRINT((dbfp, "created plugin:  %s\n", path));
 	return (p);
 }
 
 /*
- * loadauditlist - read the directory list from the audit_control file.
- *		   to determine if a binary file is to be written.
- *		 - read the plugin entries from the audit_control file
- *
- * globals -
- *
- *	plugin queues
- *
- * success is when at least one plug in is defined.
- *
- * set cnt policy here based on auditconfig setting.  future could
- * have a policy = {+|-}cnt entry per plugin with auditconfig providing the
- * default.
+ * loadauditlist() - read the auditd plugin configuration from smf(5) and
+ * prepare appropriate plugin related structures (plugin_t). Set cnt policy here
+ * based on currently active policy settings. (future could have a policy =
+ * {+|-}cnt entry per plugin with auditconfig providing the default)
  */
-
 static void
 loadauditlist()
 {
-	char		buf[MAXPATHLEN];
-	char		*value;
-	plugin_t	*p;
-	int		acresult;
-	int		wait_count = 0;
-	kva_t		*kvlist;
-	uint32_t	policy;
-	int		cnt_flag;
-	struct au_qctrl	kqmax;
-	au_acinfo_t	*ach = NULL;
-	int		got_dir = 0;
-	int		have_plugin = 0;
-	char		*endptr;
+	char			*value;
+	char			*endptr;
+	plugin_t		*p;
+	uint32_t		policy;
+	int			cnt_flag;
+	struct au_qctrl		kqmax;
+	scf_plugin_kva_node_t	*plugin_kva_ll;
+	scf_plugin_kva_node_t	*plugin_kva_ll_head;
 
 	if (auditon(A_GETPOLICY, (char *)&policy, 0) == -1) {
 		DPRINT((dbfp, "auditon(A_GETPOLICY...) failed (exit)\n"));
@@ -614,14 +604,17 @@
 		auditd_exit(1);
 	}
 	cnt_flag = ((policy & AUDIT_CNT) != 0) ? 1 : 0;
-	DPRINT((dbfp, "loadauditlist:  policy is to %s\n", (cnt_flag == 1) ?
+	DPRINT((dbfp, "loadauditlist: policy is to %s\n", (cnt_flag == 1) ?
 	    "continue" : "block"));
 
 #if DEBUG
-	if (auditon(A_GETCOND, (caddr_t)&acresult, (int)sizeof (int)) != 0)
-		DPRINT((dbfp, "auditon(A_GETCOND...) failed (exit)\n"));
-
-	DPRINT((dbfp, "audit cond = %d (1 is on)\n", acresult));
+	{
+		int	acresult;
+		if (auditon(A_GETCOND, (caddr_t)&acresult, sizeof (int)) != 0) {
+			DPRINT((dbfp, "auditon(A_GETCOND...) failed (exit)\n"));
+		}
+		DPRINT((dbfp, "audit cond = %d (1 is on)\n", acresult));
+	}
 #endif
 
 
@@ -633,7 +626,7 @@
 		auditd_exit(1);
 	}
 	kqmax.aq_hiwater *= 5;		/* RAM is cheaper in userspace */
-	DPRINT((dbfp, "auditd: reading audit_control\n"));
+	DPRINT((dbfp, "auditd: reading audit configuration\n"));
 
 	p = plugin_head;
 	/*
@@ -642,107 +635,61 @@
 	 * active.
 	 */
 	while (p != NULL) {
-		DPRINT((dbfp, "loadauditlist:  %p, %s previously created\n",
+		DPRINT((dbfp, "loadauditlist: %p, %s previously created\n",
 		    (void *)p, p->plg_path));
 		p->plg_to_be_removed = 1;	/* tentative removal */
 		p = p->plg_next;
 	}
-	/*
-	 * have_plugin may over count by one if both a "dir" entry
-	 * and a "plugin" entry for binfile are found.  All that
-	 * matters is that it be zero if no plugin or dir entries
-	 * are found.
-	 */
-	have_plugin = 0;
-	for (;;) {
-		/* NULL == use standard path for audit_control */
-		ach = _openac(NULL);
-		/*
-		 * loop until a directory entry is found (0) or eof (-1)
-		 */
-		while (((acresult = _getacdir(ach, buf, sizeof (buf))) != 0) &&
-		    acresult != -1) {
+
+	if (!do_getpluginconfig_scf(NULL, &plugin_kva_ll)) {
+		DPRINT((dbfp, "Could not get plugin configuration.\n"));
+		auditd_thread_close();
+		auditd_exit(1);
+	}
+	plugin_kva_ll_head = plugin_kva_ll;
+
+	while (plugin_kva_ll != NULL) {
+		DPRINT((dbfp, "loadauditlist: starting with %s",
+		    plugin_kva_ll->plugin_name));
+
+		/* skip inactive plugins */
+		value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_ACTIVE);
+		if (strcmp(value, "1") != 0) {
+			DPRINT((dbfp, " (inactive:%s) skipping..\n", value));
+			plugin_kva_ll = plugin_kva_ll->next;
+			continue;
 		}
-		if (acresult == 0) {
-			DPRINT((dbfp,
-			    "loadauditlist: "
-			    "got binfile via old config syntax\n"));
-			/*
-			 * A directory entry was found.
-			 */
-			got_dir = 1;
-			kvlist = _str2kva("name=audit_binfile.so.1",
-			    "=", ";");
+		DPRINT((dbfp, " (active)\n"));
+
+		value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_PATH);
+		DPRINT((dbfp, "loadauditlist: have an entry for %s (%s)\n",
+		    plugin_kva_ll->plugin_name, value));
 
-			p = init_plugin("audit_binfile.so.1", kvlist, cnt_flag);
+		p = init_plugin(value, plugin_kva_ll->plugin_kva, cnt_flag);
+		if (p == NULL) {
+			DPRINT((dbfp, "Unsuccessful plugin_t "
+			    "initialization.\n"));
+			my_sleep();
+			continue;
+		}
 
-			if (p != NULL) {
-				binfile = p;
-				p->plg_qmax = kqmax.aq_hiwater;
-				have_plugin++;
+		if (strcmp(plugin_kva_ll->plugin_name, "audit_binfile") == 0) {
+			binfile = p;
+		}
+
+		p->plg_qmax = kqmax.aq_hiwater; /* default */
+		value = kva_match(plugin_kva_ll->plugin_kva, PLUGIN_QSIZE);
+		if (value != NULL) {
+			long	tmp;
+			tmp = strtol(value, &endptr, 10);
+			if (*endptr == '\0' && tmp != 0) {
+				p->plg_qmax = tmp;
 			}
 		}
-		/*
-		 * collect plugin entries.  If there is an entry for
-		 * binfile.so.1, the parameters from the plugin line
-		 * override those set above.  For binfile, p_dir is
-		 * required only if dir wasn't specified elsewhere in
-		 * audit_control
-		 */
-		_rewindac(ach);
-		while ((acresult = _getacplug(ach, &kvlist)) == 0) {
-			value = kva_match(kvlist, "name");
-			if (value == NULL)
-				break;
-			DPRINT((dbfp, "loadauditlist: have an entry for %s\n",
-			    value));
-			p = init_plugin(value, kvlist, cnt_flag);
-			if (p == NULL)
-				continue;
+		DPRINT((dbfp, "%s queue max = %d\n", p->plg_path, p->plg_qmax));
 
-			if (strstr(value, "/audit_binfile.so") != NULL) {
-				binfile = p;
-				if (!got_dir &&
-				    (kva_match(kvlist, "p_dir") ==
-				    NULL)) {
-					__audit_dowarn("getacdir", "",
-					    wait_count);
-				}
-			}
-			p->plg_qmax = kqmax.aq_hiwater; /* default */
-			value = kva_match(kvlist, "qsize");
-			if (value != NULL) {
-				long	tmp;
-
-				tmp = strtol(value, &endptr, 10);
-				if (*endptr == '\0')
-					p->plg_qmax = tmp;
-			}
-			DPRINT((dbfp, "%s queue max = %d\n", p->plg_path,
-			    p->plg_qmax));
-
-			have_plugin++;
-		}
-		_endac(ach);
-		if (have_plugin != 0)
-			break;
-		/*
-		 * there was a problem getting the directory
-		 * list or remote host info from the audit_control file
-		 */
-		wait_count++;
-#if DEBUG
-		if (wait_count < 2)
-			DPRINT((dbfp,
-			    "auditd: problem getting directory "
-			    "/ or plugin list from audit_control.\n"));
-#endif	/* DEBUG */
-		__audit_dowarn("getacdir", "", wait_count);
-		/*
-		 * sleep for SLEEP_TIME seconds.
-		 */
-		my_sleep();
-	}    /* end for(;;) */
+		plugin_kva_ll = plugin_kva_ll->next;
+	}
 
 	p = plugin_head;
 	while (p != NULL) {
@@ -751,6 +698,8 @@
 		p->plg_removed = p->plg_to_be_removed;
 		p = p->plg_next;
 	}
+
+	plugin_kva_ll_free(plugin_kva_ll_head);
 }
 
 /*
@@ -787,9 +736,9 @@
 
 	(void) sigemptyset(&set);
 	(void) sigaddset(&set, SIGALRM);
-	(void) sigaddset(&set, AU_SIG_DISABLE);
-	(void) sigaddset(&set, AU_SIG_READ_CONTROL);
-	(void) sigaddset(&set, AU_SIG_NEXT_DIR);
+	(void) sigaddset(&set, SIGTERM);
+	(void) sigaddset(&set, SIGHUP);
+	(void) sigaddset(&set, SIGUSR1);
 
 	for (;;) {
 		signal_caught = sigwait(&set);
@@ -798,17 +747,17 @@
 			caught_alrm++;
 			DPRINT((dbfp, "caught SIGALRM\n"));
 			break;
-		case AU_SIG_DISABLE:
+		case SIGTERM:
 			caught_term++;
-			DPRINT((dbfp, "caught AU_SIG_DISABLE\n"));
+			DPRINT((dbfp, "caught SIGTERM\n"));
 			break;
-		case AU_SIG_READ_CONTROL:
+		case SIGHUP:
 			caught_readc++;
-			DPRINT((dbfp, "caught AU_SIG_READ_CONTROL\n"));
+			DPRINT((dbfp, "caught SIGHUP\n"));
 			break;
-		case AU_SIG_NEXT_DIR:
+		case SIGUSR1:
 			caught_nextd++;
-			DPRINT((dbfp, "caught AU_SIG_NEXT_DIR\n"));
+			DPRINT((dbfp, "caught SIGUSR1\n"));
 			break;
 		default:
 			DPRINT((dbfp, "caught unexpected signal:  %d\n",
@@ -891,7 +840,7 @@
 			ec.ec_class = evp->ae_class;
 
 			if (auditon(A_SETCLASS, (caddr_t)&ec,
-			    (int)sizeof (ec)) != 0) {
+			    sizeof (ec)) != 0) {
 				(void) asprintf(&msg,
 				    gettext("Could not configure kernel audit "
 				    "event to class mappings."));
@@ -905,38 +854,6 @@
 }
 
 /*
- * aconf_to_kernel() - set the non-attributable audit mask from the
- * audit_control(4); see also auditconfig(1M) -aconf option.
- */
-static void
-aconf_to_kernel(void)
-{
-	char		*msg;
-	char		buf[2048];
-	au_mask_t	pmask;
-
-	if (getacna(buf, sizeof (buf)) < 0) {
-		(void) asprintf(&msg,
-		    gettext("bad non-attributable flags in audit_control(4)"));
-		err_exit(msg);
-	}
-
-	if (getauditflagsbin(buf, &pmask) < 0) {
-		(void) asprintf(&msg,
-		    gettext("bad audit flag value encountered"));
-		err_exit(msg);
-	}
-
-	if (auditon(A_SETKMASK, (caddr_t)&pmask, (int)sizeof (pmask)) != 0) {
-		(void) asprintf(&msg,
-		    gettext("Could not configure non-attributable events."));
-		err_exit(msg);
-	}
-
-	DPRINT((dbfp, "configured non-attributable events.\n"));
-}
-
-/*
  * scf_to_kernel_qctrl() - update the kernel queue control parameters
  */
 static void
--- a/usr/src/cmd/auditd/auditd.xml	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/auditd.xml	Tue Jul 27 14:38:47 2010 +0200
@@ -1,8 +1,7 @@
 <?xml version="1.0"?>
 <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 <!--
- Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- Use is subject to license terms.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 
  CDDL HEADER START
 
@@ -77,7 +76,6 @@
 		<service_fmri value='svc:/system/console-login'/>
 	</dependent>
 
-
 	<exec_method
 		type='method'
 		name='start'
@@ -122,13 +120,36 @@
 	<property_group name='general' type='framework'>
 		<!-- to start/stop auditd -->
 		<propval name='action_authorization' type='astring'
-			value='solaris.audit.config' />
+			value='solaris.smf.manage.audit' />
 		<propval name='value_authorization' type='astring'
-			value='solaris.audit.config' />
+			value='solaris.smf.manage.audit' />
 	</property_group>
 
+	<instance name='default' enabled='false'>
 
-	<instance name='default' enabled='false'>
+	<!--
+	  System-wide audit preselection flags - see auditconfig(1M)
+	  and audit_flags(5).
+
+	  The 'flags' property is the system-wide default set of
+	  audit classes that is combined with the per-user audit
+	  flags to configure the process audit at login and role
+	  assumption time.
+
+	  The 'naflags' property is the set of audit classes for
+	  audit event selection when an event cannot be attributed
+	  to an authenticated user.
+	-->
+	<property_group name='preselection' type='application'>
+		<propval name='flags' type='astring'
+			value='lo' />
+		<propval name='naflags' type='astring'
+			value='lo' />
+		<propval name='read_authorization' type='astring'
+			value='solaris.smf.value.audit' />
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
+	</property_group>
 
 	<!--
 	  Audit Queue Control Properties - see auditconfig(1M)
@@ -147,7 +168,9 @@
 		<propval name='qlowater' type='count'
 			value='0' />
 		<propval name='read_authorization' type='astring'
-			value='solaris.audit.config' />
+			value='solaris.smf.value.audit' />
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
 	</property_group>
 
 	<!--
@@ -187,14 +210,103 @@
 		<propval name='zonename' type='boolean'
 			value='false' />
 		<propval name='read_authorization' type='astring'
-			value='solaris.audit.config' />
+			value='solaris.smf.value.audit' />
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
+	</property_group>
+
+	<!--
+	  Plugins to configure where to send the audit trail - see
+	  auditconfig(1M), audit_binfile(5), audit_remote(5),
+	  audit_syslog(5) 
+
+	  Each plugin type property group has properties:
+
+	  'active' is a boolean which defines whether or not
+	    to load the plugin.
+
+	  'path' is a string which defines name of the
+	    plugin's shared object in the file system.
+	    Relative paths assume a prefix of
+	    "/usr/lib/security/$ISA"
+
+	  'qsize' is an integer which defines a plugin specific
+	    maximum number of records that auditd will queue
+	    for it. A zero (0) value indicates not defined.
+	    This overrides the system's active queue control
+	    hiwater mark.
+
+	    and various attributes as defined on the plugin's man page
+	-->
+	<property_group name='audit_binfile' type='plugin' >
+		<propval name='active' type='boolean'
+			value='true' />
+		<propval name='path' type='astring'
+			value='audit_binfile.so' />
+		<propval name='qsize' type='count'
+			value='0' />
+		<propval name='p_dir' type='astring'
+			value='/var/audit' />
+		<propval name='p_minfree' type='count'
+			value='0' />
+		<propval name='p_fsize' type='count'
+			value='0' />
+		<property name='read_authorization' type='astring'>
+			<astring_list>
+				<value_node value='solaris.smf.manage.audit' />
+				<value_node value='solaris.smf.value.audit' />
+			</astring_list>
+		</property>
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
+	</property_group>
+
+	<property_group name='audit_syslog' type='plugin' >
+		<propval name='active' type='boolean'
+			value='false' />
+		<propval name='path' type='astring'
+			value='audit_syslog.so' />
+		<propval name='qsize' type='count'
+			value='0' />
+		<propval name='p_flags' type='astring'
+			value='' />
+		<property name='read_authorization' type='astring'>
+			<astring_list>
+				<value_node value='solaris.smf.manage.audit' />
+				<value_node value='solaris.smf.value.audit' />
+			</astring_list>
+		</property>
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
+	</property_group>
+
+	<property_group name='audit_remote' type='plugin' >
+		<propval name='active' type='boolean'
+			value='false' />
+		<propval name='path' type='astring'
+			value='audit_remote.so' />
+		<propval name='qsize' type='count'
+			value='0' />
+		<propval name='p_hosts' type='astring'
+			value='' />
+		<propval name='p_retries' type='count'
+			value='3' />
+		<propval name='p_timeout' type='count'
+			value='5' />
+		<property name='read_authorization' type='astring'>
+			<astring_list>
+				<value_node value='solaris.smf.manage.audit' />
+				<value_node value='solaris.smf.value.audit' />
+			</astring_list>
+		</property>
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.value.audit' />
 	</property_group>
 
 	</instance>
 
 	<stability value='Evolving' />
 
-
 	<template>
 		<common_name>
 			<loctext xml:lang='C'>
@@ -211,6 +323,18 @@
 			<manpage title='auditconfig'
 				section='1M'
 				manpath='/usr/share/man'/>
+			<manpage title='audit_flags'
+				section='5'
+				manpath='/usr/share/man'/>
+			<manpage title='audit_binfile'
+				section='5'
+				manpath='/usr/share/man'/>
+			<manpage title='audit_syslog'
+				section='5'
+				manpath='/usr/share/man'/>
+			<manpage title='audit_remote'
+				section='5'
+				manpath='/usr/share/man'/>
 	         </documentation>
 	</template>
 
--- a/usr/src/cmd/auditd/doorway.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/doorway.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,9 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -66,7 +64,6 @@
 #include <audit_plugin.h>	/* libbsm */
 #include "plugin.h"
 #include <bsm/audit_door_infc.h>
-#include "audit_sig_infc.h"
 #include "queue.h"
 
 #define	DEBUG		0
@@ -430,9 +427,7 @@
  *	- load plugins
  *
  * auditd_thread_init is called at auditd startup with an initial list
- * of plugins and again each time audit catches a AU_SIG_READ_CONTROL
- * or AU_SIG_NEXT_DIR.
- *
+ * of plugins and again each time audit catches a SIGHUP or SIGUSR1.
  */
 int
 auditd_thread_init()
@@ -521,10 +516,8 @@
 		} else if (p->plg_reopen) {
 			DPRINT((dbfp, "reopen %s\n", p->plg_path));
 			error_string = NULL;
-			if ((rc = p->plg_fplugin_open(
-			    p->plg_kvlist,
+			if ((rc = p->plg_fplugin_open(p->plg_kvlist,
 			    &open_params, &error_string)) != AUDITD_SUCCESS) {
-
 				report_error(rc, error_string, p->plg_path);
 				free(error_string);
 				p = unload_plugin(p);
@@ -932,7 +925,7 @@
 			policy_update(*(uint32_t *)kl->aub_buf);
 			break;
 		case AU_DBUF_SHUTDOWN:
-			(void) kill(getpid(), AU_SIG_DISABLE);
+			(void) kill(getpid(), SIGTERM);
 			DPRINT((dbfp, "AU_DBUF_SHUTDOWN message\n"));
 			break;
 		default:
@@ -1049,7 +1042,8 @@
  * time to catch up.
  */
 static void
-wait_a_while() {
+wait_a_while()
+{
 	struct timespec delay = {0, 500000000};	/* 1/2 second */;
 
 	(void) pthread_mutex_lock(&(in_thr.thd_mutex));
@@ -1066,7 +1060,8 @@
  * timed wait as well.
  */
 static void
-adjust_priority() {
+adjust_priority()
+{
 	int		queue_near_full;
 	plugin_t	*p;
 	int		queue_size;
@@ -1105,7 +1100,7 @@
 
 /*
  * input() is a door server; it blocks if any plugins have full queues
- * with the continue policy off. (auditconfig -policy -cnt)
+ * with the continue policy off. (auditconfig -setpolicy -cnt)
  *
  * input() is called synchronously from c2audit and is NOT
  * reentrant due to the (unprotected) static variables in
--- a/usr/src/cmd/auditd/plugin.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/plugin.h	Tue Jul 27 14:38:47 2010 +0200
@@ -19,9 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- *
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_PLUGIN_H
@@ -45,8 +43,8 @@
 	boolean_t	plg_initialized;	/* if threads, pools created */
 	boolean_t	plg_reopen;		/* call auditd_plugin_open */
 	/*
-	 * removed is 1 if last read of audit_control didn't list this
-	 * plugin; it needs to be removed.
+	 * removed is 1 if last read of audit configuration didn't list this
+	 * plugin or the plugin is marked as "inactive"; it needs to be removed.
 	 */
 	boolean_t	plg_removed;		/* plugin removed */
 	boolean_t	plg_to_be_removed;	/* tentative removal state */
--- a/usr/src/cmd/auditd/svc-auditd	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditd/svc-auditd	Tue Jul 27 14:38:47 2010 +0200
@@ -19,14 +19,14 @@
 #
 # CDDL HEADER END
 #
+
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
-
 . /lib/svc/share/smf_include.sh
 
+AUDIT=/usr/sbin/audit
 AUDITCONFIG=/usr/sbin/auditconfig
 AUDITD=/usr/sbin/auditd
 AWK=/usr/bin/awk
@@ -41,7 +41,6 @@
 AUDIT_STARTUP=/etc/security/audit_startup
 AUDITD_FMRI="system/auditd:default"
 
-
 #
 # main - the execution starts there.
 main()
@@ -68,7 +67,6 @@
 	esac
 }
 	
-
 #
 # do_common - executes all the code common to all supported service methods.
 do_common()
@@ -93,14 +91,22 @@
 		$AUDITCONFIG -t -getpolicy | \
 		    $EGREP "perzone|all" 1>/dev/null 2>&1
 		if [ $? -eq 1 ]; then
-			echo "$0:  auditd is not configured to run in a local"
-			echo "   zone, perzone policy not set" \
+			echo "$0: auditd(1M) is not configured to run in"
+			echo "   a local zone, perzone policy not set" \
 			    "(see auditconfig(1M))."
 			$SVCADM disable $AUDITD_FMRI
 			$SLEEP 5 &
 			exit $SMF_EXIT_OK
 		fi
 	fi
+	#
+	# Validate the audit service configuration
+	val_err="`$AUDIT -v 2>&1`"
+	if [ $? -ne 0 ]; then
+		echo "$0: audit service misconfiguration detected (${val_err})"
+		$SVCADM mark maintenance $AUDITD_FMRI
+		exit $SMF_EXIT_MON_OFFLINE
+	fi
 }
 
 #
@@ -183,7 +189,6 @@
 	fi
 }
 
-
 #
 # Call main() to start the own script execution.
 main
--- a/usr/src/cmd/auditrecord/audit_record_attr.txt	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/cmd/auditrecord/audit_record_attr.txt	Tue Jul 27 14:38:47 2010 +0200
@@ -254,6 +254,10 @@
 label=AUE_AUDITON_GESTATE
   skip=Not used
 
+label=AUE_AUDITON_GETAMASK
+  format=kernel
+  syscall=auditon: GETAMASK
+
 label=AUE_AUDITON_GETCAR
   format=kernel
   syscall=auditon: GETCAR
@@ -325,6 +329,12 @@
 label=AUE_AUDITON_SESTATE
   skip=Not used.
 
+label=AUE_AUDITON_SETAMASK
+  format=[arg]1:[arg]2
+    comment=2, "setamask as_success", user default audit preselection mask:
+    comment=2, "setamask as_failure", user default audit preselection mask
+  syscall=auditon: SETAMASK
+
 label=AUE_AUDITON_SETCLASS
   format=[arg]1:[arg]2
     comment=2, "setclass&colon;ec_event", event number:
@@ -344,8 +354,8 @@
 
 label=AUE_AUDITON_SETKMASK
   format=[arg]1:[arg]2
-    comment=2, "setkmask as_success", kernel mask:
-    comment=2, "setkmask as_failure", kernel mask
+    comment=2, "setkmask as_success", kernel non-attributable mask:
+    comment=2, "setkmask as_failure", kernel non-attributable mask
   syscall=auditon: SETKMASK
 #	header,124,2,auditon(2) - set kernel mask,,Mon May 15 09:17:06 2000, + 300000807 msec
 #	argument,2,0x0,setkmask:as_success
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/auditset/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,70 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+#
+# Makefile for auditset
+
+PROG = svc-auditset
+SVCMETHOD = $(PROG)
+
+MANIFEST = auditset.xml
+
+include $(SRC)/cmd/Makefile.cmd
+
+ROOTMANIFESTDIR = $(ROOTSVCSYSTEM)
+
+LIBBSM = $(SRC)/lib/libbsm/common
+
+LDLIBS += -lbsm
+
+OBJS = svc-auditset.o 
+SRCS = $(OBJS:%.o=%.c)
+
+POFILE = $(PROG).po
+MSGFILES = $(SRCS)
+
+CPPFLAGS += -I$(LIBBSM)
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTMANIFEST) $(ROOTSVCMETHOD)
+
+$(PROG): $(SRCS) $(OBJS)
+	$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
+	$(POST_PROCESS)
+
+$(POFILE): $(MSGFILES)
+	$(BUILDPO.msgfiles)
+
+_msg: $(MSGDOMAINPOFILE)
+
+clean:
+	$(RM) $(OBJS)
+
+lint:	lint_SRCS
+
+check:          $(CHKMANIFEST)
+
+include $(SRC)/cmd/Makefile.targ
+include $(SRC)/Makefile.msg.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/auditset/auditset.xml	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+    NOTE:  This service manifest is not editable; its contents will
+    be overwritten by package or patch operations, including
+    operating system upgrade.  Make customizations in a different
+    file.
+-->
+
+<service_bundle type='manifest' name='SUNWcsr:auditset'>
+
+<service
+        name='system/auditset'
+        type='service'
+        version='1'>
+
+	<create_default_instance enabled='true' />
+
+        <single_instance />
+
+	<dependency
+		name='auditset-root'
+		type='service'
+		grouping='optional_all'
+		restart_on='none'>
+		<service_fmri value='svc:/system/filesystem/root' />
+	</dependency>
+
+        <exec_method
+                type='method'
+                name='start'
+                exec='/lib/svc/method/svc-auditset'
+                timeout_seconds='5'>
+                <method_context>
+                        <method_credential user='root' group='root' />
+                </method_context>
+        </exec_method>
+
+        <exec_method
+                type='method'
+                name='stop'
+                exec=':true'
+                timeout_seconds='2'>
+        </exec_method>
+
+	<property_group name='startd' type='framework'>
+		<propval name='duration' type='astring' value='transient' />
+	</property_group>
+
+        <stability value='Unstable' />
+
+        <template>
+                <common_name>
+                        <loctext xml:lang='C'>
+                                Set non-/attributable audit flags
+				in the kernel context.
+                        </loctext>
+                </common_name>
+		<description>
+                        <loctext xml:lang='C'>
+				This service reads the system/auditd
+				application/preselection_flags/flags
+				and naflags values and initializes
+				their values in the kernel.
+                        </loctext>
+		</description>
+        </template>
+
+</service>
+
+</service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/auditset/svc-auditset.c	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,120 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * svc-auditset - auditset transient service (AUDITSET_FMRI) startup method;
+ * sets non-/attributable mask in the kernel context.
+ */
+
+#include <audit_scf.h>
+#include <bsm/adt.h>
+#include <bsm/libbsm.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+
+#if !defined(SMF_EXIT_ERR_OTHER)
+#define	SMF_EXIT_ERR_OTHER	1
+#endif
+
+/*
+ * update_kcontext() - updates the non-/attributable preselection masks in
+ * the kernel context. Returns B_TRUE on success, B_FALSE otherwise.
+ */
+boolean_t
+update_kcontext(int cmd, char *cmask)
+{
+	au_mask_t	bmask;
+
+	(void) getauditflagsbin(cmask, &bmask);
+	if (auditon(cmd, (caddr_t)&bmask, sizeof (bmask)) == -1) {
+		(void) printf("Could not update kernel context (%s).\n",
+		    cmd == A_SETAMASK ? "A_SETAMASK" : "A_SETKMASK");
+		return (B_FALSE);
+	}
+
+#ifdef	DEBUG
+	(void) printf("svc-auditset: %s mask set to %s",
+	    cmd == A_SETAMASK ? "Attributable" : "Non-Attributable", cmask);
+#endif
+
+	return (B_TRUE);
+}
+
+int
+main(void)
+{
+	char		*auditset_fmri;
+	char		*mask_cfg;
+
+	(void) setlocale(LC_ALL, "");
+	(void) textdomain(TEXT_DOMAIN);
+
+	/* allow execution only inside the SMF facility */
+	if ((auditset_fmri = getenv("SMF_FMRI")) == NULL ||
+	    strcmp(auditset_fmri, AUDITSET_FMRI) != 0) {
+		(void) printf(gettext("svc-auditset can be executed only "
+		    "inside the SMF facility.\n"));
+		return (SMF_EXIT_ERR_NOSMF);
+	}
+
+	/* check the c2audit module state */
+	if (adt_audit_state(AUC_DISABLED)) {
+#ifdef	DEBUG
+		if (errno == ENOTSUP) {
+			(void) printf("c2audit module is excluded from "
+			    "the system(4); kernel won't be updated.\n");
+		} else {
+			(void) printf("%s\n", strerror(errno));
+		}
+#endif
+		return (SMF_EXIT_OK);
+	}
+
+	/* update attributable mask */
+	if (!do_getflags_scf(&mask_cfg) || mask_cfg == NULL) {
+		(void) printf("Could not get configured attributable audit "
+		    "flags.\n");
+		return (SMF_EXIT_ERR_OTHER);
+	}
+	if (!update_kcontext(A_SETAMASK, mask_cfg)) {
+		free(mask_cfg);
+		return (SMF_EXIT_ERR_OTHER);
+	}
+	free(mask_cfg);
+
+	/* update non-attributable mask */
+	if (!do_getnaflags_scf(&mask_cfg) || mask_cfg == NULL) {
+		(void) printf("Could not get configured non-attributable "
+		    "audit flags.\n");
+		return (SMF_EXIT_ERR_OTHER);
+	}
+	if (!update_kcontext(A_SETKMASK, mask_cfg)) {
+		free(mask_cfg);
+		return (SMF_EXIT_ERR_OTHER);
+	}
+	free(mask_cfg);
+
+	return (SMF_EXIT_OK);
+}
--- a/usr/src/head/secdb.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/head/secdb.h	Tue Jul 27 14:38:47 2010 +0200
@@ -86,6 +86,7 @@
 extern int _kva2str(kva_t *, char *, int, char *, char *);
 extern kva_t *_kva_dup(kva_t *);
 extern void _kva_free(kva_t *);
+extern void _kva_free_value(kva_t *, char *);
 extern kva_t *_new_kva(int size);
 extern kva_t *_str2kva(char *, char *, char *);
 extern int _enum_auths(const char *, int (*)(const char *, void *, void *),
--- a/usr/src/lib/auditd_plugins/binfile/binfile.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/auditd_plugins/binfile/binfile.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  *
  * write binary audit records directly to a file.
  */
@@ -115,7 +114,8 @@
 static int		minfree = -1;
 static int		minfreeblocks;		/* minfree in blocks */
 
-static dirlist_t	*activeDir = NULL;	/* current directory */
+static dirlist_t	*lastOpenDir = NULL;    /* last activeDir */
+static dirlist_t	*activeDir = NULL;	/* to be current directory */
 static dirlist_t	*startdir;		/* first dir in the ring */
 static int		activeCount = 0;	/* number of dirs in the ring */
 
@@ -156,12 +156,35 @@
 	}
 }
 
+dirlist_t *
+dupdirnode(dirlist_t *node_orig)
+{
+	dirlist_t	*node_new;
+
+	if ((node_new = calloc(1, sizeof (dirlist_t))) == NULL) {
+		return (NULL);
+	}
+
+	if (node_orig->dl_dirname != NULL &&
+	    (node_new->dl_dirname = strdup(node_orig->dl_dirname)) == NULL ||
+	    node_orig->dl_filename != NULL &&
+	    (node_new->dl_filename = strdup(node_orig->dl_filename)) == NULL) {
+		freedirlist(node_new);
+		return (NULL);
+	}
+
+	node_new->dl_next = node_new;
+	node_new->dl_space = node_orig->dl_space;
+	node_new->dl_flags = node_orig->dl_flags;
+	node_new->dl_fd = node_orig->dl_fd;
+
+	return (node_new);
+}
 
 /*
  * add to a linked list of directories available for writing
  *
  */
-
 static int
 growauditlist(dirlist_t **listhead, char *dirlist,
     dirlist_t *endnode, int *count)
@@ -232,113 +255,43 @@
  * error.  (Positive returns are for AUDITD_<error code> values)
  *
  */
-
 static int
 loadauditlist(char *dirstr, char *minfreestr)
 {
-	char		buf[MAXPATHLEN];
-	char		*bs, *be;
-	dirlist_t	 *node, *n1, *n2;
-	dirlist_t	 **node_p;
+	dirlist_t	*n1, *n2;
 	dirlist_t	*listhead = NULL;
 	dirlist_t	*thisdir;
-	int		acresult;
 	int		node_count = 0;
 	int		rc;
 	int		temp_minfree;
-	au_acinfo_t	*ach;
 
 	static dirlist_t	*activeList = NULL;	/* directory list */
 
-	DPRINT((dbfp, "binfile: Loading audit list from auditcontrol\n"));
-
-	/*
-	 * Build new directory list
-	 */
-	/* part 1 -- using pre Sol 10 audit_control directives */
-	node_p = &listhead;
-
-	ach = _openac(NULL);
-	if (ach == NULL)
-		return (-1);
-
-	/* at least one directory is needed */
-	while ((acresult = _getacdir(ach, buf, sizeof (buf))) == 0 ||
-	    acresult == 2 || acresult == -3) {
-		/*
-		 * loop if the result is 0 (success), 2 (a warning
-		 * that the audit_control file has been rewound),
-		 * or -3 (a directory entry was found, but it
-		 * was badly formatted.
-		 */
-		if (acresult == 0) {
-			/*
-			 * A directory entry was found.
-			 */
-			node_count++;
-			node = malloc(sizeof (dirlist_t));
-			if (node == NULL)
-				return (AUDITD_NO_MEMORY);
-
-			node->dl_flags = 0;
-			node->dl_fd = -1;
-			node->dl_space = PLENTY_SPACE;
-			node->dl_filename = NULL;
+	DPRINT((dbfp, "binfile: Loading audit list from audit service "
+	    "(audit_binfile)\n"));
 
-			node->dl_dirname = malloc((unsigned)strlen(buf) + 1);
-			if (node->dl_dirname == NULL)
-				return (AUDITD_NO_MEMORY);
-
-			bs = buf;
-			while ((*bs == ' ') || (*bs == '\t'))
-				bs++;
-			be = bs + strlen(bs) - 1;
-			while (be > bs) {	/* trim trailing blanks */
-				if ((*bs != ' ') && (*bs != '\t'))
-					break;
-				be--;
-			}
-			*(be + 1) = '\0';
-			(void) strlcpy(node->dl_dirname, bs, AUDIT_FNAME_SZ);
-
-			if (listhead != NULL)
-				node->dl_next = listhead;
-			else
-				node->dl_next = node;
-			*node_p = node;
-			node_p = &(node->dl_next);
-		}
-	}   /* end of getacdir while */
-	/*
-	 * part 2 -- use directories and minfree from the (new as of Sol 10)
-	 * plugin directive
-	 */
-	if (dirstr != NULL) {
-		if (node_count == 0) {
-			listhead = NULL;
-			node = NULL;
-		}
-		rc = growauditlist(&listhead, dirstr, node, &node_count);
-		if (rc)
-			return (rc);
+	if (dirstr == NULL || minfreestr == NULL) {
+		DPRINT((dbfp, "binfile: internal error"));
+		return (-1);
+	}
+	if ((rc = growauditlist(&listhead, dirstr, NULL, &node_count)) != 0) {
+		return (rc);
 	}
 	if (node_count == 0) {
 		/*
 		 * there was a problem getting the directory
-		 * list or remote host info from the audit_control file
-		 * even though auditd thought there was at least 1 good
-		 * entry
+		 * list or remote host info from the audit_binfile
+		 * configuration even though auditd thought there was
+		 * at least 1 good entry
 		 */
 		DPRINT((dbfp, "binfile: "
 		    "problem getting directory / libpath list "
-		    "from audit_control.\n"));
-
-		_endac(ach);
+		    "from audit_binfile configuration.\n"));
 		return (-1);
 	}
+
 #if DEBUG
 	/* print out directory list */
-
 	if (listhead != NULL) {
 		(void) fprintf(dbfp, "Directory list:\n\t%s\n",
 		    listhead->dl_dirname);
@@ -350,13 +303,11 @@
 		}
 	}
 #endif	/* DEBUG */
+
 	thisdir = listhead;
-	/*
-	 * See if the list has changed.
-	 * If there was a change  rc = 0 if no change, else 1
-	 */
-	rc = 0;	/* no change */
 
+	/* See if the list has changed (rc = 0 if no change, else 1) */
+	rc = 0;
 	if (node_count == activeCount) {
 		n1 = listhead;
 		n2 = activeList;
@@ -374,14 +325,15 @@
 			n2 = n2->dl_next;
 		} while ((n1 != listhead) && (n2 != activeList));
 	} else {
-		DPRINT((dbfp, "binfile:  old dir count = %d\n"
+		DPRINT((dbfp, "binfile: dir counts differs\n"
+		    "binfile:  old dir count = %d\n"
 		    "binfile:  new dir count = %d\n",
 		    activeCount, node_count));
 		rc = -2;
 	}
 	if (rc == -2) {
 		(void) pthread_mutex_lock(&log_mutex);
-		DPRINT((dbfp, "loadauditlist:  close / open log\n"));
+		DPRINT((dbfp, "loadauditlist:  close / open audit.log(4)\n"));
 		if (open_log(listhead) == 0) {
 			openNewFile = 1;	/* try again later */
 		} else {
@@ -392,17 +344,13 @@
 		activeDir = startdir = thisdir;
 		activeCount = node_count;
 		(void) pthread_mutex_unlock(&log_mutex);
-	} else
+	} else {
 		freedirlist(listhead);
-	/*
-	 * Get the minfree value.  If minfree comes in via the attribute
-	 * list, ignore the possibility it may also be listed on a separate
-	 * audit_control line.
-	 */
+	}
+
+	/* Get the minfree value. */
 	if (minfreestr != NULL)
 		temp_minfree = atoi(minfreestr);
-	else if (!(_getacmin(ach, &temp_minfree) == 0))
-		temp_minfree = 0;
 
 	if ((temp_minfree < 0) || (temp_minfree > 100))
 		temp_minfree = 0;
@@ -413,12 +361,10 @@
 		rc = -2;		/* data change */
 		minfree = temp_minfree;
 	}
-	_endac(ach);
 
 	return (rc);
 }
 
-
 /*
  * getauditdate - get the current time (GMT) and put it in the form
  *		  yyyymmddHHMMSS .
@@ -493,11 +439,12 @@
  *	newname - the name of the new log file (for the trailer)
  */
 static void
-close_log(dirlist_t *currentdir, char *oname, char *newname)
+close_log(dirlist_t **lastOpenDir_ptr, char *oname, char *newname)
 {
-	char	auditdate[AUDIT_DATE_SZ+1];
-	char	*name;
-	char	oldname[AUDIT_FNAME_SZ+1];
+	char		auditdate[AUDIT_DATE_SZ+1];
+	char		*name;
+	char		oldname[AUDIT_FNAME_SZ+1];
+	dirlist_t 	*currentdir = *lastOpenDir_ptr;
 
 	if ((currentdir == NULL) || (currentdir->dl_fd == -1))
 		return;
@@ -537,8 +484,8 @@
 
 	DPRINT((dbfp, "binfile: Log closed %s\n", oldname));
 
-	free(currentdir->dl_filename);
-	currentdir->dl_filename = NULL;
+	freedirlist(currentdir);
+	*lastOpenDir_ptr = NULL;
 }
 
 
@@ -561,19 +508,17 @@
 	char	oldname[AUDIT_FNAME_SZ + 1] = "";
 	char	newname[AUDIT_FNAME_SZ + 1];
 	char	*name;			/* pointer into oldname */
-	int	opened;
+	int	opened = 0;
 	int	error = 0;
 	int	newfd = 0;
 
 	static char		host[MAXHOSTNAMELEN + 1] = "";
 	/* previous directory with open log file */
-	static dirlist_t	*lastOpenDir = NULL;
 
 	if (host[0] == '\0')
 		(void) gethostname(host, MAXHOSTNAMELEN);
 
 	/* Get a filename which does not already exist */
-	opened = 0;
 	while (!opened) {
 		getauditdate(auditdate);
 		(void) snprintf(newname, AUDIT_FNAME_SZ,
@@ -589,6 +534,22 @@
 				    "(will try another)\n", newname));
 				(void) sleep(1);
 				break;
+			case ENOENT: {
+				/* invalid path */
+				char	*msg;
+				(void) asprintf(&msg,
+				    gettext("No such p_dir: %s\n"),
+				    current_dir->dl_dirname);
+				DPRINT((dbfp,
+				    "open_log says about %s: %s\n",
+				    newname, strerror(errno)));
+				__audit_syslog("audit_binfile.so",
+				    LOG_CONS | LOG_NDELAY,
+				    LOG_DAEMON, LOG_ERR, msg);
+				free(msg);
+				current_dir = current_dir->dl_next;
+				return (0);
+			}
 			default:
 				/* open failed */
 				DPRINT((dbfp,
@@ -617,7 +578,7 @@
 		(void) memcpy(name + AUDIT_DATE_SZ + 1, auditdate,
 		    AUDIT_DATE_SZ);
 
-		close_log(lastOpenDir, oldname, newname);
+		close_log(&lastOpenDir, oldname, newname);
 	}
 	error = write_file_token(newfd, oldname);
 	if (error) {
@@ -631,9 +592,27 @@
 		current_dir = current_dir->dl_next;
 		return (0);
 	} else {
-		lastOpenDir = current_dir;
+		if (current_dir->dl_filename != NULL) {
+			free(current_dir->dl_filename);
+		}
+		current_dir->dl_filename = strdup(newname);
 		current_dir->dl_fd = newfd;
-		current_dir->dl_filename = strdup(newname);
+
+		if (lastOpenDir == NULL) {
+			freedirlist(lastOpenDir);
+			if ((lastOpenDir = dupdirnode(current_dir)) == NULL) {
+				__audit_syslog("audit_binfile.so",
+				    LOG_CONS | LOG_NDELAY,
+				    LOG_DAEMON, LOG_ERR, gettext("no memory"));
+				return (0);
+			}
+			DPRINT((dbfp, "open_log created new lastOpenDir "
+			    "(%s, %s [fd: %d])\n",
+			    lastOpenDir->dl_dirname == NULL ? "" :
+			    lastOpenDir->dl_dirname,
+			    lastOpenDir->dl_filename == NULL ? "" :
+			    lastOpenDir->dl_filename, lastOpenDir->dl_fd));
+		}
 
 		/*
 		 * New file opened, so reset file size statistic (used
@@ -953,18 +932,13 @@
 
 
 /*
- * the open function uses getacdir() and getacmin to determine which
- * directories to use and when to switch.  It takes no inputs.
- *
  * It may be called multiple times as auditd handles SIGHUP and SIGUSR1
  * corresponding to the audit(1M) flags -s and -n
  *
- * kvlist is NULL only if auditd caught a SIGUSR1, so after the first
- * time open is called, the reason is -s if kvlist != NULL and -n
- * otherwise.
+ * kvlist is NULL only if auditd caught a SIGUSR1 (audit -n), so after the first
+ * time open is called; the reason is -s if kvlist != NULL and -n otherwise.
  *
  */
-
 auditd_rc_t
 auditd_plugin_open(const kva_t *kvlist, char **ret_list, char **error)
 {
@@ -1052,7 +1026,7 @@
 	*error = NULL;
 
 	(void) pthread_mutex_lock(&log_mutex);
-	close_log(activeDir, "", "");
+	close_log(&lastOpenDir, "", "");
 	freedirlist(activeDir);
 	activeDir = NULL;
 	(void) pthread_mutex_unlock(&log_mutex);
--- a/usr/src/lib/auditd_plugins/remote/audit_remote.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/auditd_plugins/remote/audit_remote.c	Tue Jul 27 14:38:47 2010 +0200
@@ -59,7 +59,6 @@
 
 #include "audit_remote.h"
 
-#define	DEFAULT_RETRIES	3	/* default connection retries */
 #define	DEFAULT_TIMEOUT	5	/* default connection timeout (in secs) */
 #define	NOSUCCESS_DELAY	20	/* unsuccessful delivery to all p_hosts */
 
@@ -68,13 +67,9 @@
 
 static int	nosuccess_cnt;	/* unsuccessful delivery counter */
 
-
-static int	retries = DEFAULT_RETRIES;	/* connection retries */
-int		timeout = DEFAULT_TIMEOUT;	/* connection timeout */
-static int	timeout_p_timeout = -1;		/* p_timeout attr storage */
-
-/* time reset mechanism; x .. timeout_p_timeout */
-#define	RST_TIMEOUT(x)		(x != -1 ? x : DEFAULT_TIMEOUT)
+static int	retries;		/* connection retries */
+int		timeout;		/* connection timeout */
+static int	timeout_p_timeout;	/* p_timeout attr storage */
 
 /* semi-exponential timeout back off; x .. attempts, y .. timeout */
 #define	BOFF_TIMEOUT(x, y)	(x < 3 ? y * 2 * x : y * 8)
@@ -84,6 +79,7 @@
 
 static struct hostlist_s	*current_host;
 static struct hostlist_s	*hosts;
+static struct hostlist_s	*hosts_prev;
 
 extern struct transq_hdr_s	transq_hdr;
 static long			transq_count_max;
@@ -101,7 +97,8 @@
 /*
  * set_transq_count_max() - sets the transq_count_max value based on kernel
  * audit queue high water mark. This is backup solution for a case, when the
- * plugin audit_control(4) option lacks (intentionally) the qsize option.
+ * the default qsize zero value is (intentionally) set in the audit_remote(5)
+ * plugin configuration.
  */
 static auditd_rc_t
 set_transq_count_max()
@@ -180,6 +177,24 @@
 	return (str_ptr);
 }
 
+/*
+ * Frees host list - should be called while keeping auditd_mutex.
+ */
+static void
+freehostlist(hostlist_t **hostlist_ptr)
+{
+	hostlist_t *h, *n;
+
+	h = *hostlist_ptr;
+
+	while (h != NULL)  {
+		n = h->next_host;
+		freehostent(h->host);
+		free(h);
+		h = n;
+	}
+	*hostlist_ptr = NULL;
+}
 
 /*
  * parsehosts() end parses the host string (hosts_str)
@@ -196,6 +211,7 @@
 	gss_OID		mech_oid;
 	char 		*lasts_hpm;
 	hostlist_t 	*lasthost = NULL;
+	hostlist_t 	*hosts_new = NULL;
 	hostlist_t	*newhost;
 	struct hostent 	*hostentry;
 	int		error_num;
@@ -205,8 +221,6 @@
 	int		num_of_hosts = 0;
 #endif
 
-	hosts = lasthost;
-
 	DPRINT((dfile, "parsing %s\n", hosts_str));
 	while ((hostportmech = strtok_r(hosts_str, ",", &lasts_hpm)) != NULL) {
 
@@ -334,41 +348,27 @@
 			lasthost = lasthost->next_host;
 		} else {
 			lasthost = newhost;
-			hosts = newhost;
+			hosts_new = newhost;
 		}
 #if DEBUG
 		num_of_hosts++;
 #endif
 	}
 
+	(void) pthread_mutex_lock(&plugin_mutex);
+	if (hosts_prev == NULL) {
+		hosts_prev = hosts;
+	}
+	hosts = hosts_new;
 	current_host = hosts;
+	(void) pthread_mutex_unlock(&plugin_mutex);
+
 	DPRINT((dfile, "Configured %d hosts.\n", num_of_hosts));
 
 	return (AUDITD_SUCCESS);
 }
 
 
-/*
- * Frees host list
- */
-static void
-freehostlist()
-{
-	hostlist_t *h, *n;
-
-	(void) pthread_mutex_lock(&plugin_mutex);
-	h = hosts;
-	while (h) {
-		n = h->next_host;
-		freehostent(h->host);
-		free(h);
-		h = n;
-	}
-	current_host = NULL;
-	hosts = NULL;
-	(void) pthread_mutex_unlock(&plugin_mutex);
-}
-
 #if DEBUG
 static char *
 auditd_message(auditd_rc_t msg_code) {
@@ -607,19 +607,22 @@
 			DPRINT((dfile, "success\n"));
 			nosuccess_cnt = 0;
 			rc = AUDITD_SUCCESS;
+			if (hosts_prev != NULL) {
+				freehostlist(&hosts_prev);
+				DPRINT((dfile, "stale host list freed\n"));
+			}
 			break;
 		case SEND_RECORD_NEXT:
-			DPRINT((dfile, "retry the same host: %s (penalty)\n",
-			    current_host->host->h_name));
+			DPRINT((dfile, "retry the same host: %s (penalty) "
+			    "rsn:%d\n", current_host->host->h_name, err_rsn));
 			attempts++;
 			break;
 		case SEND_RECORD_RETRY:
-			DPRINT((dfile, "retry the same host: %s (no penalty)\n",
-			    current_host->host->h_name));
+			DPRINT((dfile, "retry the same host: %s (no penalty) "
+			    "rsn:%d\n", current_host->host->h_name, err_rsn));
 			break;
 		}
 
-
 		if (send_record_rc == SEND_RECORD_NEXT) {
 
 			/* warn about unsuccessful auditd record delivery */
@@ -639,7 +642,6 @@
 			free(rsn_msg);
 			free(ext_error);
 
-
 			if (attempts < retries) {
 				/* semi-exponential timeout back off */
 				timeout = BOFF_TIMEOUT(attempts, timeout);
@@ -650,12 +652,11 @@
 				if (current_host == NULL) {
 					current_host = hosts;
 				}
-				timeout = RST_TIMEOUT(timeout_p_timeout);
+				timeout = timeout_p_timeout;
 				DPRINT((dfile, "New timeout=%d\n", timeout));
 				attempts = 0;
 			}
 
-
 			/* one cycle finished */
 			if (current_host == start_host && attempts == 0) {
 				nosuccess_cnt++;
@@ -722,42 +723,53 @@
 	if (kvlist != NULL) {
 		DPRINT((dfile, "Action: initial open or `audit -s`\n"));
 		val_str = kva_match(kv, "p_timeout");
-		if (val_str != NULL) {
-			DPRINT((dfile, "val_str=%s\n", val_str));
-			errno = 0;
-			val = atoi(val_str);
-			if (errno == 0 && val >= 1) {
-				timeout_p_timeout = val;
-				timeout = val;
-			}
+		if (val_str == NULL) {
+			*error = strdup(
+			    gettext("p_timeout attribute not found"));
+			return (AUDITD_RETRY);
+		}
+		DPRINT((dfile, "val_str=%s\n", val_str));
+		errno = 0;
+		val = atoi(val_str);
+		if (errno == 0 && val >= 1) {
+			timeout_p_timeout = val;
+			timeout = val;
+		} else {
+			timeout_p_timeout = DEFAULT_TIMEOUT;
+			timeout = timeout_p_timeout;
+			DPRINT((dfile, "p_timeout set to default value: %d\n",
+			    timeout));
 		}
 
 		val_str = kva_match(kv, "p_retries");
-		if (val_str != NULL) {
-			DPRINT((dfile, "val_str=%s\n", val_str));
-			errno = 0;
-			val = atoi(val_str);
-			if (errno == 0 && val >= 0) {
-				retries = val;
-			}
+		if (val_str == NULL) {
+			*error = strdup(
+			    gettext("p_retries attribute not found"));
+			return (AUDITD_RETRY);
+		}
+		DPRINT((dfile, "val_str=%s\n", val_str));
+		errno = 0;
+		val = atoi(val_str);
+		if (errno == 0 && val >= 0) {
+			retries = val;
 		}
 
 		val_str = kva_match(kv, "qsize");
-		if (val_str != NULL) {
-			DPRINT((dfile, "qsize=%s\n", val_str));
-			errno = 0;
-			val_l = atol(val_str);
-			if (errno == 0 && val_l > 0) {
-				transq_count_max = val_l;
-			}
-
-		} else {
-			DPRINT((dfile, "qsize not in kvlist\n"));
-			if ((rc = set_transq_count_max()) != AUDITD_SUCCESS) {
-				*error = strdup(gettext("cannot get kernel "
-				    "auditd queue high water mark\n"));
-				return (rc);
-			}
+		if (val_str == NULL) {
+			*error = strdup(gettext("qsize attribute not found"));
+			return (AUDITD_RETRY);
+		}
+		DPRINT((dfile, "qsize=%s\n", val_str));
+		errno = 0;
+		val_l = atol(val_str);
+		if (errno == 0 && val_l >= 0) {
+			transq_count_max = val_l;
+		}
+		if (transq_count_max == 0 &&
+		    (rc = set_transq_count_max()) != AUDITD_SUCCESS) {
+			*error = strdup(gettext("cannot get kernel "
+			    "auditd queue high water mark\n"));
+			return (rc);
 		}
 		DPRINT((dfile, "timeout=%d, retries=%d, transq_count_max=%ld\n",
 		    timeout, retries, transq_count_max));
@@ -807,7 +819,11 @@
 		return (AUDITD_RETRY);
 	}
 
-	freehostlist();
+	(void) pthread_mutex_lock(&plugin_mutex);
+	freehostlist(&hosts);
+	freehostlist(&hosts_prev);
+	(void) pthread_mutex_unlock(&plugin_mutex);
+	current_host = NULL;
 	*error = NULL;
 	return (AUDITD_SUCCESS);
 }
--- a/usr/src/lib/libbc/libc/gen/common/getacinfo.c	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/* getacinfo.c  -  get audit control info */
-
-#include <stdio.h>
-#include <string.h>
-
-#define DIROP 0
-#define OTHEROP 1
-
-#define LEN 360		/* maximum audit control entry length */
-
-#define SUCCESS 0
-#define EOF_WARN 1 
-#define REW_WARN 2
-#define EOF_ERR -1 
-#define ERROR   -2 
-#define FORMAT_ERR -3
-
-
-static char *AUDIT_CTRL  = "/etc/security/audit/audit_control";
-static char *MINLABEL    = "minfree:";
-static char *DIRLABEL    = "dir:";
-static char *FLGLABEL    = "flags:";
-static int  LASTOP;
-static int  DIRINIT;
-static FILE *acf;    /* pointer into /etc/security/audit/audit_control */
-
-void	setac(void);
-void	endac(void);
-
-/* getacinfo.c  -  get audit control info
- *
- *	getacdir() - get audit control directories, one at a time
- *	getacflg() - get audit control flags 
- *	getacmin() - get audit control directory min. fill value
- *	setac()    -  rewind the audit control file 
- *	endac()    -  close the audit control file 
- */
-
-
-/* getacdir() - get audit control directories, one at a time
- *
- * input: len  - size of dir buffer
- *
- * output: dir - directory string
- *
- * returns:  0 - entry read ok
- *          -1 - end of file
- *          -2 - error - can't open audit control file for read 
- *          -3 - error - directory entry format error 
- *           1 - directory search started from beginning again 
- *
- * notes:    It is the responsibility of the calling function to 
- * 		check the status of the directory entry.
- */
-
-int
-getacdir(char *dir, int len)
-{
-	int retstat = SUCCESS, gotone = 0, dirlen, dirst;
-	char entry[LEN];
-	
-	/* 
-	 * open file if it is not already opened
-	 */
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "r")) == NULL)
-		retstat = ERROR;
-	else if (LASTOP != DIROP && DIRINIT == 1) {
-		 retstat = REW_WARN;
-		 setac();
-	} else {
-		DIRINIT = 1;
-		LASTOP == DIROP;
-	}
-	if (retstat >= SUCCESS) {
-  		do {
-    			if (fgets(entry, LEN, acf) != NULL) {
-				switch(*entry) {
-        			case '#':
-           				break;
-        			case 'd':
-				/*
-            	 		 * return directory entry 
-			 	 */
-            			if (!strncmp(entry,DIRLABEL,strlen(DIRLABEL))) {
-                			if ((strlen(entry)+1) > len)
-                   				retstat = FORMAT_ERR;
-                			else {
-					/* 
-				 	 * allow zero or one blank 
-					 * between colon and directory 
-				 	 */
-                     			if (entry[strlen(DIRLABEL)] == ' ') {
-                            			dirst = strlen(DIRLABEL)+1;
-                      				dirlen = 
-					  	  strlen(entry) - 
-						    (strlen(DIRLABEL)+2); 
-					} else {
-                           			dirst = strlen(DIRLABEL);
-                           			dirlen = 
-						  strlen(entry) - 
-						    (strlen(DIRLABEL)+1); 
-                       			}
-                			strcpy(dir, entry+dirst);
-                			strcpy(dir+dirlen, "\0");
-                			gotone = 1;    
-                   			}
-				} else
-               				retstat = FORMAT_ERR;
-                		break;
-            			case 'm':
-               				break;
-            			case 'f':
-                			break;
-            			default:
-                			break;
-            			}
-        		} else if ((feof(acf)) == 0)
-        			retstat = ERROR;
-        		else
-            			retstat = EOF_ERR;
-
-    		} while (gotone == 0 && retstat >= SUCCESS);
-	}
-    	return (retstat);
-}
-
-/*
- * getacmin() - get audit control directory min. fill value
- *
- * output: min_val - percentage of directory fill allowed 
- *
- * returns:  0 - entry read ok
- *           1 - end of file
- *          -2 - error; errno contains error number 
- *          -3 - error - directory entry format error 
- */
-
-int
-getacmin(int *min_val)
-{
-	int retstat = SUCCESS, gotone = 0;
-	char entry[LEN];
-
-	/* 
-	 * open file if it is not already opened 
-	 */
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "r")) == NULL)
-	    retstat = ERROR;
-	else
-	    rewind(acf);
-
-	if (retstat == SUCCESS) {
-      		do {
-        		if (fgets(entry, LEN, acf) != NULL) {
-            			switch(*entry) {
-	    			case '#':
-					break;
-				case 'd':
-					break;
-				case 'm':
-					if (!strncmp(entry, MINLABEL, strlen(MINLABEL))) {
-		    			sscanf(entry+strlen(MINLABEL), "%d", min_val);
-		    			gotone = 1;
-					} else
-		    			retstat = FORMAT_ERR;
-					break;
-				case 'f':
-					break;
-				default:
-					break;
-				}
-			} else if ((feof(acf)) == 0)
-				retstat = ERROR;
-			else
-				retstat = EOF_WARN;
-
-		} while (gotone == 0 && retstat == SUCCESS);
-	}
-
-	if (LASTOP == DIROP)
-		LASTOP = OTHEROP;
-	else
-		endac();
-
-	return (retstat);
-}
-
-/* getacflg() - get audit control flags 
- *
- * output: auditstring - character representation of system audit flags 
- *
- * returns:  0 - entry read ok
- *           1 - end of file
- *          -2 - error - errno contains error number 
- *          -3 - error - directory entry format error 
- */
-
-int
-getacflg(char *auditstring, int len)
-{
-	int retstat = SUCCESS, gotone = 0, minst, minlen;
-	char entry[LEN];
-
-	/* 
-	 * open file if it is not already opened 
-	 */
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "r")) == NULL)
-		retstat = ERROR;
-	else
-		rewind(acf);
-
-	if (retstat == SUCCESS) {
-		do {
-			if (fgets(entry, LEN, acf) != NULL) {
-				switch(*entry) {
-				case '#':
-					break;
-				case 'd':
-					break;
-				case 'm':
-					break;
-				case 'f':
-					if ((strncmp(entry, FLGLABEL, strlen(FLGLABEL))) == 0) {
-						if (entry[strlen(FLGLABEL)] == ' ') {
-							minst = strlen(FLGLABEL)+1;
-							minlen = strlen(entry)-(strlen(FLGLABEL)+2); 
-						} else {
-							minst = strlen(FLGLABEL);
-							minlen = strlen(entry)-(strlen(FLGLABEL)+1); 
-						}
-						if (minlen > len)
-							retstat = FORMAT_ERR;
-						else {
-							strcpy(auditstring, entry+minst);
-							strcpy(auditstring+minlen, "\0");
-							gotone = 1;	
-						}
-					} else 
-						retstat = FORMAT_ERR;
-					break;
-				default:
-					break;
-				}
-			} else if ((feof(acf)) == 0)
-				retstat = ERROR;
-			else
-				retstat = EOF_WARN;
-
-		} while (gotone == 0 && retstat == SUCCESS);
-	}
-	if (LASTOP == DIROP)
-		LASTOP = OTHEROP;
-	else
-		endac();
-
-	return (retstat);
-}
-
-/* rewind the audit control file */
-void
-setac(void)
-{
-	if (acf == NULL)
-		acf = fopen(AUDIT_CTRL, "r");
-	else
-		rewind(acf);
-	LASTOP = DIROP;
-	DIRINIT = 0;
-}
-
-
-/* close the audit control file */
-void
-endac(void)
-{
-	if (acf != NULL) {
-		fclose(acf);
-		acf = NULL;
-	}
-	LASTOP = DIROP;
-	DIRINIT = 0;
-}
--- a/usr/src/lib/libbc/sparc/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbc/sparc/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -59,7 +59,7 @@
 clock.o closedir.o crypt.o ctime.o ctype_.o\
 drand48.o dysize.o errlst.o execvp.o exit.o exportent.o ecvt.o\
 fabs.o fmod.o frexp.o\
-fstab.o ftok.o ftw.o getacinfo.o getauid.o getauditflags.o \
+fstab.o ftok.o ftw.o getauid.o getauditflags.o \
 getcwd.o getenv.o getgraent.o getlogin.o \
 getopt.o getsubopt.o getpwaent.o  getttyent.o\
 getttynam.o getusershell.o grpauth.o hsearch.o\
--- a/usr/src/lib/libbsm/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -45,7 +45,7 @@
 # Macros for libbsm header files. These define user-level only interfaces.
 #
 GENHDRS = audit_uevents.h
-HDRS = libbsm.h devices.h devalloc.h adt.h adt_event.h audit_private.h
+HDRS = libbsm.h devices.h devalloc.h adt.h adt_event.h audit_private.h 
 GENSRCS =	$(COMMONDIR)/adt_xlate.c $(COMMONDIR)/adt_event.h
 COMMONHDRS =	$(HDRS:%=$(COMMONDIR)/%)
 ROOTHDRDIR = 	$(ROOT)/usr/include/bsm
@@ -70,7 +70,7 @@
 ROOTETCSECURITY = 	$(ROOT)/etc/security
 $(ROOTETCSECURITY) := 	DIRMODE = 0755
 
-ESFILES =		audit_class audit_control audit_event
+ESFILES =		audit_class audit_event
 ESSRC =			$(ESFILES:%=%.txt)
 ETCSECURITYFILES =	$(ESFILES:%=$(ROOTETCSECURITY)/%)
 $(ETCSECURITYFILES) :=	FILEMODE = 0644
--- a/usr/src/lib/libbsm/Makefile.com	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/Makefile.com	Tue Jul 27 14:38:47 2010 +0200
@@ -50,12 +50,11 @@
 		audit_rexd.o \
 		audit_rexecd.o \
 		audit_rshd.o \
+		audit_scf.o \
 		audit_settid.o \
 		audit_shutdown.o \
 		bsm.o \
 		generic.o \
-		getacinfo.o \
-		getacval.o \
 		getauditflags.o \
 		getdaent.o \
 		getdevicerange.o \
@@ -84,11 +83,12 @@
 CLEANFILES +=	$(LINTOUT) $(LINTLIB)
 
 CFLAGS	+=	$(CCVERBOSE)
-LDLIBS +=	-lsocket -lnsl -lmd -lc -lsecdb -ltsol -linetutil
+LDLIBS +=	-lsocket -lnsl -lmd -lc -lsecdb -ltsol -linetutil -lscf
 
 COMDIR=		../common
+AUDITD=		$(SRC)/cmd/auditd
 
-CPPFLAGS += -I$(COMDIR)
+CPPFLAGS += -I$(COMDIR) -I$(AUDITD)
 CPPFLAGS += -D_REENTRANT
 
 #
--- a/usr/src/lib/libbsm/audit_control.txt	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License").  You may not use this file except in compliance
-# with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# ident	"%Z%%M%	%I%	%E% SMI"
-#
-dir:/var/audit
-flags:
-minfree:20
-naflags:lo
--- a/usr/src/lib/libbsm/audit_event.txt	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/audit_event.txt	Tue Jul 27 14:38:47 2010 +0200
@@ -358,6 +358,8 @@
 307:AUE_SETSID:setsid(2):pm
 308:AUE_SETPGID:setpgid(2):pm
 309:AUE_FACCESSAT:faccessat(2):no
+310:AUE_AUDITON_GETAMASK:auditon(2) - get default user preselection mask:aa
+311:AUE_AUDITON_SETAMASK:auditon(2) - set default user preselection mask:as
 #
 # user level audit events
 #	2048 -  6143	Reserved
--- a/usr/src/lib/libbsm/common/adt.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/adt.c	Tue Jul 27 14:38:47 2010 +0200
@@ -160,62 +160,59 @@
  *	See adt_audit_enabled() for state discussions.
  *	The state parameter is a hedge until all the uses become clear.
  *	Likely if adt_audit_enabled is brought internal to this file,
- *	it can take a parameter discussing the state.
+ *	it could be modified to take one or more parameters to describe the
+ *	state.
  */
 
 boolean_t
-adt_audit_state(int state)
+adt_audit_state(int states)
 {
 
 	(void) auditon(A_GETCOND, (caddr_t)&auditstate, sizeof (auditstate));
 
-	return (auditstate & state);
+	return ((auditstate & states) ? B_TRUE : B_FALSE);
 }
 
 /*
- * The man page for getpwuid_r says the buffer must be big enough
- * or ERANGE will be returned, but offers no guidance for how big
- * the buffer should be or a way to calculate it.  If you get
- * ERANGE, double pwd_buff's size.
- *
- * This may be called even when auditing is off.
+ * Get user_specific/non-attributable audit mask. This may be called even when
+ * auditing is off.
  */
 
-#define	NAFLAG_LEN 512
-
 static int
 adt_get_mask_from_user(uid_t uid, au_mask_t *mask)
 {
 	struct passwd	pwd;
-	char		pwd_buff[NSS_BUFSIZ];
-	char		naflag_buf[NAFLAG_LEN];
+	long		buff_sz;
+	char		*pwd_buff;
+
 
 	if (auditstate & AUC_DISABLED) {
 		/* c2audit excluded */
 		mask->am_success = 0;
 		mask->am_failure = 0;
 	} else if (uid <= MAXUID) {
-		if (getpwuid_r(uid, &pwd, pwd_buff, NSS_BUFSIZ) == NULL) {
-			/*
-			 * getpwuid_r returns NULL without setting
-			 * errno if the user does not exist; only
-			 * if the input is the wrong length does it
-			 * set errno.
-			 */
-			if (errno != ERANGE)
-				errno = EINVAL;
+		if ((buff_sz = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
+			adt_write_syslog("couldn't determine maximum size of "
+			    "password buffer", errno);
 			return (-1);
 		}
+		if ((pwd_buff = calloc(1, (size_t)++buff_sz)) == NULL) {
+			return (-1);
+		}
+		if (getpwuid_r(uid, &pwd, pwd_buff, (int)buff_sz) == NULL) {
+			errno = EINVAL;	/* user doesn't exist */
+			free(pwd_buff);
+			return (-1);
+		}
+		free(pwd_buff);
 		if (au_user_mask(pwd.pw_name, mask)) {
 			errno = EFAULT; /* undetermined failure */
 			return (-1);
 		}
-	} else if (getacna(naflag_buf, NAFLAG_LEN - 1) == 0) {
-		if (getauditflagsbin(naflag_buf, mask))
+	} else if (auditon(A_GETKMASK, (caddr_t)mask, sizeof (*mask)) == -1) {
 			return (-1);
-	} else {
-		return (-1);
 	}
+
 	return (0);
 }
 
--- a/usr/src/lib/libbsm/common/au_usermask.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/au_usermask.c	Tue Jul 27 14:38:47 2010 +0200
@@ -67,7 +67,6 @@
 au_user_mask(char *user, au_mask_t *mask)
 {
 	char		*last = NULL;
-	char		deflt[360];	/* matches stuff in getac*.c */
 	char		*user_flags = NULL;
 
 	if (mask == NULL) {
@@ -75,16 +74,13 @@
 	}
 
 	/*
-	 * Get the default audit flags.
+	 * Get the system wide default audit flags. If you can't get the
+	 * system wide flags, return an error code now and don't bother
+	 * trying to get the user specific flags.
 	 */
-
-	setac();
-	if (getacflg(deflt, sizeof (deflt)) != 0) {
-		endac();
+	if (auditon(A_GETAMASK, (caddr_t)mask, sizeof (*mask)) == -1) {
 		return (-1);
 	}
-	endac();
-	(void) getauditflagsbin(deflt, mask);
 
 	/*
 	 * Get per-user audit flags.
--- a/usr/src/lib/libbsm/common/audit_ftpd.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/audit_ftpd.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,12 +19,9 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/param.h>
 #include <stdio.h>
@@ -55,7 +52,7 @@
 #define	NO_ANONYMOUS	(4)
 #define	MISC_FAILURE	(5)
 
-static char		luser[16];
+static char		luser[LOGNAME_MAX + 1];
 
 static void generate_record(char *, int, char *);
 static int selected(uid_t, char *, au_event_t, int);
@@ -66,10 +63,8 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	(void) strncpy(luser, uname, 8);
-	luser[8] = '\0';
-	generate_record(luser, BAD_PASSWD, dgettext(bsm_dom,
-		"bad password"));
+	(void) strncpy(luser, uname, LOGNAME_MAX);
+	generate_record(luser, BAD_PASSWD, dgettext(bsm_dom, "bad password"));
 }
 
 
@@ -79,10 +74,8 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	(void) strncpy(luser, uname, 8);
-	luser[8] = '\0';
-	generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom,
-		"unknown user"));
+	(void) strncpy(luser, uname, LOGNAME_MAX);
+	generate_record(luser, UNKNOWN_USER, dgettext(bsm_dom, "unknown user"));
 }
 
 
@@ -92,10 +85,9 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	(void) strncpy(luser, uname, 8);
-	luser[8] = '\0';
+	(void) strncpy(luser, uname, LOGNAME_MAX);
 	generate_record(luser, EXCLUDED_USER, dgettext(bsm_dom,
-		"excluded user"));
+	    "excluded user"));
 }
 
 
@@ -105,8 +97,7 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	generate_record("", NO_ANONYMOUS, dgettext(bsm_dom,
-		"no anonymous"));
+	generate_record("", NO_ANONYMOUS, dgettext(bsm_dom, "no anonymous"));
 }
 
 void
@@ -115,8 +106,7 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	generate_record(uname, MISC_FAILURE, dgettext(bsm_dom,
-		"misc failure"));
+	generate_record(uname, MISC_FAILURE, dgettext(bsm_dom, "misc failure"));
 }
 
 void
@@ -125,8 +115,7 @@
 	if (cannot_audit(0)) {
 		return;
 	}
-	(void) strncpy(luser, uname, 8);
-	luser[8] = '\0';
+	(void) strncpy(luser, uname, LOGNAME_MAX);
 	generate_record(luser, 0, "");
 }
 
@@ -186,7 +175,7 @@
 
 	/* add subject token */
 	(void) au_write(rd, au_to_subject_ex(uid, uid, gid,
-		ruid, rgid, pid, pid, &info.ai_termid));
+	    ruid, rgid, pid, pid, &info.ai_termid));
 
 	if (is_system_labeled())
 		(void) au_write(rd, au_to_mylabel());
@@ -229,27 +218,26 @@
 	au_event_t	event,
 	int	err)
 {
-	int	rc, sorf;
-	char	naflags[512];
-	struct au_mask mask;
+	int		sorf;
+	struct au_mask	mask;
 
 	mask.am_success = mask.am_failure = 0;
 	if (uid > MAXEPHUID) {
-		rc = getacna(naflags, 256); /* get non-attrib flags */
-		if (rc == 0)
-			(void) getauditflagsbin(naflags, &mask);
+		/* get non-attrib flags */
+		(void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask));
 	} else {
-		rc = au_user_mask(locuser, &mask);
+		(void) au_user_mask(locuser, &mask);
 	}
 
-	if (err == 0)
+	if (err == 0) {
 		sorf = AU_PRS_SUCCESS;
-	else if (err >= 1)
+	} else if (err >= 1) {
 		sorf = AU_PRS_FAILURE;
-	else
+	} else {
 		sorf = AU_PRS_BOTH;
-	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
-	return (rc);
+	}
+
+	return (au_preselect(event, &mask, sorf, AU_PRS_REREAD));
 }
 
 
@@ -277,7 +265,7 @@
 
 	/* determine if we're preselected */
 	if (au_preselect(AUE_ftpd_logout, &info.ai_mask, AU_PRS_SUCCESS,
-		AU_PRS_USECACHE) == 0) {
+	    AU_PRS_USECACHE) == 0) {
 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_AUDIT,
 		    NULL);
 		return;
@@ -293,7 +281,7 @@
 
 	/* add subject token */
 	(void) au_write(rd, au_to_subject_ex(info.ai_auid, euid,
-		egid, uid, gid, pid, pid, &info.ai_termid));
+	    egid, uid, gid, pid, pid, &info.ai_termid));
 
 	if (is_system_labeled())
 		(void) au_write(rd, au_to_mylabel());
--- a/usr/src/lib/libbsm/common/audit_plugin.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/audit_plugin.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  *
  * private interfaces for auditd plugins and auditd.
  */
@@ -116,15 +115,14 @@
 		(void) waitpid(pid, &st, 0);
 		return;
 	}
-	(void) sprintf(countstr, "%d", count);
+	(void) snprintf(countstr, 5, "%d", count);
 	if (text == NULL)
 		text = empty;
 
 	if (strcmp(option, "soft") == 0 || strcmp(option, "hard") == 0)
 		(void) execl(auditwarn, auditwarn, option, text, 0);
 
-	else if (strcmp(option, "allhard") == 0 ||
-	    strcmp(option, "getacdir") == 0)
+	else if (strcmp(option, "allhard") == 0)
 		(void) execl(auditwarn, auditwarn, option, countstr, 0);
 	else if (strcmp(option, "plugin") == 0)
 		(void) execl(auditwarn, auditwarn, option, text, countstr, 0);
@@ -134,22 +132,16 @@
 	 * (execl failed)
 	 */
 	if (strcmp(option, "soft") == 0)
-		(void) sprintf(warnstring,
+		(void) snprintf(warnstring, 80,
 		    gettext("soft limit in %s.\n"), text);
 	else if (strcmp(option, "hard") == 0)
-		(void) sprintf(warnstring,
+		(void) snprintf(warnstring, 80,
 		    gettext("hard limit in %s.\n"), text);
 	else if (strcmp(option, "allhard") == 0)
 		(void) sprintf(warnstring,
 		    gettext("All audit filesystems are full.\n"));
-	else if (strcmp(option, "getacmin") == 0)
-		(void) sprintf(warnstring,
-		    gettext("audit_control minfree error.\n"));
-	else if (strcmp(option, "getacdir") == 0)
-		(void) sprintf(warnstring,
-		    gettext("audit_control directory error.\n"));
 	else
-		(void) sprintf(warnstring,
+		(void) snprintf(warnstring, 80,
 		    gettext("error %s.\n"), option);
 
 	__audit_syslog("auditd", LOG_PID | LOG_ODELAY | LOG_CONS, LOG_AUTH,
@@ -190,7 +182,7 @@
 		(void) waitpid(pid, &st, 0);
 		return;
 	}
-	(void) sprintf(countstr, "%d", count);
+	(void) snprintf(countstr, 5, "%d", count);
 	if ((text == NULL) || (*text == '\0'))
 		text = empty;
 	if ((name == NULL) || (*name == '\0'))
@@ -202,8 +194,8 @@
 	/*
 	 * (execl failed)
 	 */
-	(void) sprintf(warnstring,
-	    gettext("audit_control plugin error: %s\n"), text);
+	(void) snprintf(warnstring, 80,
+	    gettext("%s plugin error: %s\n"), name, text);
 
 	__audit_syslog("auditd", LOG_PID | LOG_ODELAY | LOG_CONS, LOG_AUTH,
 	    LOG_ALERT, (const char *)warnstring);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libbsm/common/audit_policy.h	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,86 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef	_AUDIT_POLICY_H
+#define	_AUDIT_POLICY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <bsm/audit.h>
+#include <bsm/libbsm.h>
+
+#define	ALL_POLICIES   (AUDIT_AHLT|\
+			AUDIT_ARGE|\
+			AUDIT_ARGV|\
+			AUDIT_CNT|\
+			AUDIT_GROUP|\
+			AUDIT_SEQ|\
+			AUDIT_TRAIL|\
+			AUDIT_PATH|\
+			AUDIT_PUBLIC|\
+			AUDIT_ZONENAME|\
+			AUDIT_PERZONE|\
+			AUDIT_WINDATA_DOWN|\
+			AUDIT_WINDATA_UP)
+
+#define	NO_POLICIES  (0)
+
+struct policy_entry {
+	char *policy_str;
+	uint32_t policy_mask;
+	char *policy_desc;
+};
+typedef struct policy_entry policy_entry_t;
+
+static policy_entry_t policy_table[] = {
+	{"ahlt",  AUDIT_AHLT,   "halt machine if it can not record an "
+	    "async event"},
+	{"all",   ALL_POLICIES,	"all policies"},
+	{"arge",  AUDIT_ARGE,   "include exec environment args in audit recs"},
+	{"argv",  AUDIT_ARGV,   "include exec command line args in audit recs"},
+	{"cnt",   AUDIT_CNT,    "when no more space, drop recs and keep a cnt"},
+	{"group", AUDIT_GROUP,	"include supplementary groups in audit recs"},
+	{"none",  NO_POLICIES,	"no policies"},
+	{"path",  AUDIT_PATH,	"allow multiple paths per event"},
+	{"perzone", AUDIT_PERZONE,      "use a separate queue and auditd per "
+	    "zone"},
+	{"public",  AUDIT_PUBLIC,    "audit public files"},
+	{"seq",   AUDIT_SEQ,    "include a sequence number in audit recs"},
+	{"trail", AUDIT_TRAIL,	"include trailer token in audit recs"},
+	{"windata_down", AUDIT_WINDATA_DOWN,  "include downgraded window "
+	    "information in audit recs"},
+	{"windata_up",  AUDIT_WINDATA_UP,     "include upgraded window "
+	    "information in audit recs"},
+	{"zonename", AUDIT_ZONENAME,    "include zonename token in audit recs"}
+};
+
+#define	POLICY_TBL_SZ (sizeof (policy_table) / sizeof (policy_entry_t))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _AUDIT_POLICY_H */
--- a/usr/src/lib/libbsm/common/audit_rexd.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/audit_rexd.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -85,27 +84,26 @@
 au_event_t	event;
 int	sf;
 {
-	int	rc, sorf;
-	char	naflags[512];
-	struct au_mask mask;
+	int		sorf;
+	struct au_mask	mask;
 
 	mask.am_success = mask.am_failure = 0;
 	if (uid > MAXEPHUID) {
-		rc = getacna(naflags, 256); /* get non-attrib flags */
-		if (rc == 0)
-			(void) getauditflagsbin(naflags, &mask);
+		/* get non-attrib flags */
+		(void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask));
 	} else {
-		rc = au_user_mask(user, &mask);
+		(void) au_user_mask(user, &mask);
 	}
 
-	if (sf == 0)
+	if (sf == 0) {
 		sorf = AU_PRS_SUCCESS;
-	else if (sf == -1)
+	} else if (sf == -1) {
 		sorf = AU_PRS_FAILURE;
-	else
+	} else {
 		sorf = AU_PRS_BOTH;
-	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
-	return (rc);
+	}
+
+	return (au_preselect(event, &mask, sorf, AU_PRS_REREAD));
 }
 
 void
--- a/usr/src/lib/libbsm/common/audit_rexecd.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/audit_rexecd.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -57,27 +56,26 @@
 au_event_t	event;
 int	sf;
 {
-	int	rc, sorf;
-	char	naflags[512];
-	struct au_mask mask;
+	int		sorf;
+	struct au_mask	mask;
 
 	mask.am_success = mask.am_failure = 0;
 	if (uid > MAXEPHUID) {
-		rc = getacna(naflags, 256); /* get non-attrib flags */
-		if (rc == 0)
-			(void) getauditflagsbin(naflags, &mask);
+		/* get non-attrib flags */
+		(void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask));
 	} else {
-		rc = au_user_mask(user, &mask);
+		(void) au_user_mask(user, &mask);
 	}
 
-	if (sf == 0)
+	if (sf == 0) {
 		sorf = AU_PRS_SUCCESS;
-	else if (sf == -1)
+	} else if (sf == -1) {
 		sorf = AU_PRS_FAILURE;
-	else
+	} else {
 		sorf = AU_PRS_BOTH;
-	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
-	return (rc);
+	}
+
+	return (au_preselect(event, &mask, sorf, AU_PRS_REREAD));
 }
 
 void
--- a/usr/src/lib/libbsm/common/audit_rshd.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/audit_rshd.c	Tue Jul 27 14:38:47 2010 +0200
@@ -19,10 +19,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -134,7 +132,7 @@
 	rd = au_open();
 
 	(void) au_write(rd, au_to_subject_ex(uid, uid, gid, uid, gid, pid, pid,
-		&info.ai_termid));
+	    &info.ai_termid));
 	if (is_system_labeled())
 		(void) au_write(rd, au_to_mylabel());
 
@@ -150,13 +148,13 @@
 
 	if (strcmp(remuser, locuser) != 0) {
 		(void) snprintf(buf, sizeof (buf), dgettext(bsm_dom,
-			"remote user %s"), remuser);
+		    "remote user %s"), remuser);
 		(void) au_write(rd, au_to_text(buf));
 	}
 
 	if (sf_flag == -1) {
 		(void) snprintf(buf, sizeof (buf), dgettext(bsm_dom,
-			"local user %s"), locuser);
+		    "local user %s"), locuser);
 		(void) au_write(rd, au_to_text(buf));
 		(void) au_write(rd, au_to_text(msg));
 	}
@@ -175,27 +173,26 @@
 static int
 selected(uid_t uid, char *locuser, au_event_t event, int sf)
 {
-	int	rc, sorf;
-	char	naflags[512];
-	struct au_mask mask;
+	int		sorf;
+	struct au_mask	mask;
 
 	mask.am_success = mask.am_failure = 0;
 	if (uid > MAXEPHUID) {
-		rc = getacna(naflags, 256); /* get non-attrib flags */
-		if (rc == 0)
-			(void) getauditflagsbin(naflags, &mask);
+		/* get non-attrib flags */
+		(void) auditon(A_GETKMASK, (caddr_t)&mask, sizeof (mask));
 	} else {
-		rc = au_user_mask(locuser, &mask);
+		(void) au_user_mask(locuser, &mask);
 	}
 
-	if (sf == 0)
+	if (sf == 0) {
 		sorf = AU_PRS_SUCCESS;
-	else if (sf == -1)
+	} else if (sf == -1) {
 		sorf = AU_PRS_FAILURE;
-	else
+	} else {
 		sorf = AU_PRS_BOTH;
-	rc = au_preselect(event, &mask, sorf, AU_PRS_REREAD);
-	return (rc);
+	}
+
+	return (au_preselect(event, &mask, sorf, AU_PRS_REREAD));
 }
 
 static void
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libbsm/common/audit_scf.c	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,1286 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* auditd smf(5)/libscf(3LIB) interface - set and display audit parameters */
+#include <audit_scf.h>
+#include <audit_policy.h>
+
+/* propvec array must be NULL terminated */
+scf_propvec_t	prop_vect[MAX_PROPVECS + 1];
+
+/*
+ * prt_error() - prt_error_va() wrapper; see prt_error_va() for more contextual
+ * information. Note, that the function disregards errno; if you need to print
+ * out strerror()/errno use directly prt_error_va().
+ * Inputs - program error format and message.
+ */
+/*PRINTFLIKE1*/
+static void
+prt_error(char *fmt, ...)
+{
+	va_list 	args;
+
+	errno = 0;
+
+	va_start(args, fmt);
+	prt_error_va(fmt, args);
+	va_end(args);
+}
+
+/*
+ * prt_error_va() - prints an error message along with corresponding system
+ * error number. Inputs - program error format and the va_list already prepared
+ * by the preceding functions.
+ *
+ */
+/*PRINTFLIKE1*/
+void
+prt_error_va(char *fmt, va_list args)
+{
+	(void) vfprintf(stderr, fmt, args);
+	(void) fputc('\n', stderr);
+	if (errno)
+		(void) fprintf(stderr, "error: %s(%d)\n",
+		    strerror(errno), errno);
+	(void) fflush(stderr);
+}
+
+/*
+ * prt_scf_err() - scf_error()/scf_strerror() wrapper.
+ */
+static void
+prt_scf_err(void)
+{
+	(void) fprintf(stderr, "error: %s\n", scf_strerror(scf_error()));
+}
+
+/*
+ * add_prop_vect_scf() - adds vector to the array of vectors later passed to
+ * get_/set_val_scf(). The first argument (vector) points to particular position
+ * in the vector of properties.
+ */
+static void
+add_prop_vect_scf(scf_propvec_t *vector, const char *prop_str,
+    scf_type_t prop_type, void *prop_val_ptr)
+{
+	vector->pv_prop = prop_str;
+	vector->pv_type = prop_type;
+	vector->pv_ptr = prop_val_ptr;
+}
+
+/*
+ * get_val_scf() - get a property values from the audit service
+ *
+ * Arguments:	vector = pointers to the head end of array of property vectors
+ * 		pgroup_str = property group of property in AUDITD_FMRI
+ *
+ */
+static boolean_t
+get_val_scf(scf_propvec_t *vector, char *pgroup_str)
+{
+	scf_propvec_t	*bad_prop_vec = NULL;
+
+	/*
+	 * Get the property vector from the editing snapshot (B_FALSE).
+	 * For documentation on property vectors see <libscf_priv.h>.
+	 */
+	if (scf_read_propvec(AUDITD_FMRI, pgroup_str, B_FALSE, vector,
+	    &bad_prop_vec) != SCF_SUCCESS) {
+		prt_scf_err();
+		if (bad_prop_vec != NULL) {
+			prt_error(gettext("Reading the %s property in the %s "
+			    "property group failed.\n"), bad_prop_vec->pv_prop,
+			    pgroup_str);
+		}
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * set_val_scf() - set property values of the audit service.
+ *
+ * arguments:	vector = pointers to the head end of array of property vectors
+ * 		pgroup_str = property group of property in AUDITD_FMRI
+ *
+ */
+static boolean_t
+set_val_scf(scf_propvec_t *vector, char *pgroup_str)
+{
+	scf_propvec_t	*bad_prop_vec = NULL;
+
+	/* for documentation on property vectors see <libscf_priv.h> */
+	if (scf_write_propvec(AUDITD_FMRI, pgroup_str, vector,
+	    &bad_prop_vec) != SCF_SUCCESS) {
+		prt_scf_err();
+		if (bad_prop_vec != NULL) {
+			prt_error(gettext("Setting the %s property in the %s "
+			    "property group failed.\n"), bad_prop_vec->pv_prop,
+			    pgroup_str);
+		}
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * free_prop_vect() - deallocate heap memory used for propvect values.
+ */
+static void
+free_prop_vect(void)
+{
+	scf_propvec_t	*prop_vect_ptr;
+
+	prop_vect_ptr = prop_vect;
+
+	while (prop_vect_ptr->pv_prop != NULL) {
+		if (stack_inbounds(prop_vect_ptr->pv_ptr) == 0) {
+			free(prop_vect_ptr->pv_ptr);
+		}
+		prop_vect_ptr++;
+	}
+}
+
+/*
+ * chk_prop_vect() - check for prop_vect boundaries and possibly process
+ * (typically) full prop_vect.
+ */
+static boolean_t
+chk_prop_vect(scf_propvec_t **prop_vect_ptr, char *pgrp_str)
+{
+	if (*prop_vect_ptr < prop_vect ||
+	    *prop_vect_ptr >= (prop_vect + MAX_PROPVECS)) {
+		DPRINT((dbfp, "prop_vect is full; flushing\n"));
+		if (!set_val_scf(prop_vect, pgrp_str)) {
+			return (B_FALSE);
+		}
+		free_prop_vect();
+		bzero(prop_vect, sizeof (prop_vect));
+		*prop_vect_ptr = prop_vect;
+	}
+	return (B_TRUE);
+}
+
+/*
+ * get_props_kva_all() - get all properties and fill in the plugin_kva.
+ */
+static boolean_t
+get_props_kva_all(asi_scfhandle_t *handle, asi_scfhandle_iter_t *handle_iter,
+    kva_t **plugin_kva)
+{
+	char		key_buf[PLUGIN_MAXKEY];
+	char		val_buf[PLUGIN_MAXVAL];
+	char		attr_string[PLUGIN_MAXATT];
+	char		attr_buf[PLUGIN_MAXATT];
+	int		len = 0;
+	scf_type_t	prop_type;
+
+	attr_string[0] = 0;
+	attr_buf[0] = 0;
+
+	while (scf_iter_next_property(handle_iter->prop, handle->prop) == 1) {
+		if (scf_property_get_name(handle->prop, key_buf,
+		    PLUGIN_MAXKEY) == -1) {
+			prt_scf_err();
+			return (B_FALSE);
+		}
+
+		/*
+		 * We do not fully support multi-valued properties.
+		 * scf_property_get_value() only supports single-valued
+		 * properties. It returns SCF_ERROR_CONSTRAINT_VIOLATED and one
+		 * of the property values. The audit service configuration
+		 * values are all single-valued properties. The authorizations
+		 * to configure and read the audit service properties may be
+		 * multi-valued, these may safely be ignored here as not an
+		 * error.
+		 */
+		if (scf_property_get_value(handle->prop,
+		    handle_iter->prop_val) != 0 &&
+		    scf_error() != SCF_ERROR_CONSTRAINT_VIOLATED) {
+			prt_scf_err();
+			return (B_FALSE);
+		}
+		if (scf_property_type(handle->prop, &prop_type) == -1) {
+			prt_scf_err();
+			return (B_FALSE);
+		}
+		switch (prop_type) {
+		case SCF_TYPE_BOOLEAN: {
+			uint8_t	pval_bool;
+			if (scf_value_get_boolean(handle_iter->prop_val,
+			    &pval_bool) == -1) {
+				prt_scf_err();
+				return (B_FALSE);
+			}
+			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%d;",
+			    key_buf, pval_bool);
+			if (len < 0 || len >= PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute: %s\n"),
+				    key_buf);
+				return (B_FALSE);
+			}
+			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
+			    PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute string: "
+				    "%s\n"), key_buf);
+				return (B_FALSE);
+			}
+			break;
+		}
+		case SCF_TYPE_ASTRING: {
+			if (scf_value_get_as_string(handle_iter->prop_val,
+			    val_buf, PLUGIN_MAXATT) == -1) {
+				prt_scf_err();
+				return (B_FALSE);
+			}
+			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%s;",
+			    key_buf, val_buf);
+			if (len < 0 || len >= PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute: %s\n"),
+				    key_buf);
+				return (B_FALSE);
+			}
+			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
+			    PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute string: "
+				    "%s\n"), key_buf);
+				return (B_FALSE);
+			}
+			break;
+		}
+		case SCF_TYPE_COUNT: {
+			uint64_t	pval_count;
+			if (scf_value_get_count(handle_iter->prop_val,
+			    &pval_count) == -1) {
+				prt_scf_err();
+				return (B_FALSE);
+			}
+			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%llu;",
+			    key_buf, pval_count);
+			if (len < 0 || len >= PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute: %s\n"),
+				    key_buf);
+				return (B_FALSE);
+			}
+			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
+			    PLUGIN_MAXATT) {
+				prt_error(gettext("Too long attribute string: "
+				    "%s\n"), key_buf);
+				return (B_FALSE);
+			}
+			break;
+		}
+		default:
+			(void) printf("Unsupported value type %s [%d]\n",
+			    key_buf, prop_type);
+			break;
+		}
+	}
+
+	if (*attr_string == '\0' ||
+	    (*plugin_kva = _str2kva(attr_string, "=", ";")) == NULL) {
+		prt_error(gettext("Empty or invalid attribute string."));
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * get_plugin_kva() - get and save config attributes of given plugin plugin_str
+ * (or all plugins in case plugin_str == NULL) into scf_plugin_kva_node_t.
+ */
+static boolean_t
+get_plugin_kva(asi_scfhandle_t *handle, asi_scfhandle_iter_t *handle_iter,
+    scf_plugin_kva_node_t **plugin_kva_ll, char *plugin_str)
+{
+
+	scf_plugin_kva_node_t	*node = NULL;
+	scf_plugin_kva_node_t	*node_prev = NULL;
+	scf_plugin_kva_node_t	*node_head = NULL;
+	char			plugin_str_tmp[PLUGIN_MAXBUF];
+
+	bzero(plugin_str_tmp, PLUGIN_MAXBUF);
+
+	if (scf_iter_instance_pgs_typed(handle_iter->pgrp, handle->inst,
+	    (const char *)"plugin") == -1) {
+		prt_scf_err();
+		return (B_FALSE);
+	}
+
+	while (scf_iter_next_pg(handle_iter->pgrp, handle->pgrp) == 1) {
+		if (scf_pg_get_name(handle->pgrp, plugin_str_tmp,
+		    PLUGIN_MAXBUF) == -1) {
+			prt_scf_err();
+			plugin_kva_ll_free(node);
+			return (B_FALSE);
+		}
+
+		if (plugin_str != NULL &&
+		    strcmp(plugin_str_tmp, plugin_str) != 0) {
+			continue;
+		}
+
+		if ((node =
+		    calloc(1, sizeof (scf_plugin_kva_node_t))) == NULL) {
+			prt_error(gettext("No available memory."));
+			plugin_kva_ll_free(node_prev);
+			return (B_FALSE);
+		}
+		if (node_head == NULL) {
+			node_head = node;
+		}
+		if (node_prev != NULL) {
+			node_prev->next = node;
+			node->prev = node_prev;
+		}
+		node_prev = node;
+
+		(void) strlcat((char *)&(node->plugin_name), plugin_str_tmp,
+		    PLUGIN_MAXBUF);
+
+		if (scf_iter_pg_properties(handle_iter->prop,
+		    handle->pgrp) != 0) {
+			prt_scf_err();
+			plugin_kva_ll_free(node);
+			return (B_FALSE);
+		}
+
+		if (!get_props_kva_all(handle, handle_iter,
+		    &(node->plugin_kva))) {
+			plugin_kva_ll_free(node);
+			return (B_FALSE);
+		}
+	}
+
+#if DEBUG
+	{
+		scf_plugin_kva_node_t	*node_debug = node_head;
+		char			attr_string[PLUGIN_MAXATT];
+
+		while (node_debug != NULL) {
+			if (_kva2str(node_debug->plugin_kva, attr_string,
+			    PLUGIN_MAXATT, "=", ";") == 0) {
+				DPRINT((dbfp, "Found plugin - %s: %s\n",
+				    node_debug->plugin_name, attr_string));
+			} else {
+				DPRINT((dbfp, "Could not get attribute string "
+				    "for %s\n", node_debug->plugin_name));
+			}
+			node_debug = node_debug->prev;
+		}
+	}
+#endif
+
+	*plugin_kva_ll = node_head;
+
+	return (B_TRUE);
+}
+
+/*
+ * scf_free() - free scf handles
+ */
+static void
+scf_free(asi_scfhandle_t *handle)
+{
+	if (handle == NULL) {
+		return;
+	}
+
+	if (handle->prop != NULL) {
+		scf_property_destroy(handle->prop);
+	}
+	if (handle->pgrp != NULL) {
+		scf_pg_destroy(handle->pgrp);
+	}
+	if (handle->inst != NULL) {
+		scf_instance_destroy(handle->inst);
+	}
+	if (handle->hndl != NULL) {
+		if (scf_handle_unbind(handle->hndl) == -1) {
+			prt_error(gettext("Internal error."));
+			prt_scf_err();
+		}
+		scf_handle_destroy(handle->hndl);
+	}
+}
+
+/*
+ * scf_init() - initiate scf handles
+ */
+static boolean_t
+scf_init(asi_scfhandle_t *handle)
+{
+	bzero(handle, sizeof (asi_scfhandle_t));
+
+	if ((handle->hndl = scf_handle_create(SCF_VERSION)) == NULL ||
+	    scf_handle_bind(handle->hndl) != 0) {
+		goto err_out;
+	}
+	if ((handle->inst = scf_instance_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+	if ((handle->pgrp = scf_pg_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+	if ((handle->prop = scf_property_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+
+	return (B_TRUE);
+
+err_out:
+	prt_scf_err();
+	scf_free(handle);
+	return (B_FALSE);
+}
+
+/*
+ * scf_free_iter() - free scf iter handles
+ */
+static void
+scf_free_iter(asi_scfhandle_iter_t *handle_iter)
+{
+	if (handle_iter == NULL) {
+		return;
+	}
+
+	if (handle_iter->pgrp != NULL) {
+		scf_iter_destroy(handle_iter->pgrp);
+	}
+	if (handle_iter->prop != NULL) {
+		scf_iter_destroy(handle_iter->prop);
+	}
+	if (handle_iter->prop_val != NULL) {
+		scf_value_destroy(handle_iter->prop_val);
+	}
+}
+
+/*
+ * scf_init_iter() - initiate scf iter handles
+ */
+static boolean_t
+scf_init_iter(asi_scfhandle_iter_t *handle_iter,
+    asi_scfhandle_t *handle)
+{
+	bzero(handle_iter, sizeof (asi_scfhandle_iter_t));
+
+	if ((handle_iter->pgrp = scf_iter_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+	if ((handle_iter->prop = scf_iter_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+	if ((handle_iter->prop_val = scf_value_create(handle->hndl)) == NULL) {
+		goto err_out;
+	}
+
+	return (B_TRUE);
+
+err_out:
+	prt_scf_err();
+	scf_free_iter(handle_iter);
+	return (B_FALSE);
+}
+
+/*
+ * chk_policy_context() - does some policy based checks, checks the context
+ * (zone, smf) in which the policy could make some sense.
+ */
+static boolean_t
+chk_policy_context(char *policy_str)
+{
+
+	/*
+	 * "all" and "none" policy flags, since they represent
+	 * sub/set of auditing policies, are not stored in the
+	 * AUDITD_FMRI service instance configuration.
+	 */
+	DPRINT((dbfp, "Walking policy - %s: ", policy_str));
+	if (strcmp("all", policy_str) == 0 ||
+	    strcmp("none", policy_str) == 0) {
+		DPRINT((dbfp, "skipped\n"));
+		return (B_FALSE);
+	}
+	/*
+	 * In the local zone (!= GLOBAL_ZONEID) we do not touch
+	 * "ahlt" and "perzone" policy flags, since these are
+	 * relevant only in the global zone.
+	 */
+	if ((getzoneid() != GLOBAL_ZONEID) &&
+	    (strcmp("ahlt", policy_str) == 0 ||
+	    strcmp("perzone", policy_str) == 0)) {
+		DPRINT((dbfp, "skipped\n"));
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * free_static_att_kva() - free hardcoded/static plugin attributes (key/value
+ * pairs) from the kva plugin structure.
+ */
+void
+free_static_att_kva(kva_t *plugin_kva)
+{
+	_kva_free_value(plugin_kva, PLUGIN_ACTIVE);
+	_kva_free_value(plugin_kva, PLUGIN_PATH);
+	_kva_free_value(plugin_kva, PLUGIN_QSIZE);
+	_kva_free_value(plugin_kva, "read_authorization");
+	_kva_free_value(plugin_kva, "value_authorization");
+}
+
+
+/*
+ * do_getqctrl_scf() - get the values of qctrl properties of the audit service
+ */
+boolean_t
+do_getqctrl_scf(struct au_qctrl *cval)
+{
+	scf_propvec_t   	*prop_vect_ptr;
+	scf_qctrl_t		cval_scf;
+
+	bzero(prop_vect, sizeof (prop_vect));
+
+	prop_vect_ptr = prop_vect;
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER,
+	    SCF_TYPE_COUNT, &cval_scf.scf_qhiwater);
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER,
+	    SCF_TYPE_COUNT, &cval_scf.scf_qlowater);
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ,
+	    SCF_TYPE_COUNT, &cval_scf.scf_qbufsz);
+	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY,
+	    SCF_TYPE_COUNT, &cval_scf.scf_qdelay);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
+		return (B_FALSE);
+	}
+
+	cval->aq_hiwater = (size_t)cval_scf.scf_qhiwater;
+	cval->aq_lowater = (size_t)cval_scf.scf_qlowater;
+	cval->aq_bufsz = (size_t)cval_scf.scf_qbufsz;
+	cval->aq_delay = (clock_t)cval_scf.scf_qdelay;
+
+	scf_clean_propvec(prop_vect);
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getqbufsz_scf() - get the qbufsz audit service property value
+ */
+boolean_t
+do_getqbufsz_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT, &cval_l);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
+		return (B_FALSE);
+	}
+
+	*cval = (size_t)cval_l;
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getqdelay_scf() - get the qdelay audit service property value
+ */
+boolean_t
+do_getqdelay_scf(clock_t *cval)
+{
+	uint64_t	cval_l;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT, &cval_l);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
+		return (B_FALSE);
+	}
+
+	*cval = (clock_t)cval_l;
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getqhiwater_scf() - get the qhiwater audit service property value
+ */
+boolean_t
+do_getqhiwater_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
+	    &cval_l);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
+		return (B_FALSE);
+	}
+
+	*cval = (size_t)cval_l;
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getqlowater_scf() - get the qlowater audit service property value
+ */
+boolean_t
+do_getqlowater_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
+	    &cval_l);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
+		return (B_FALSE);
+	}
+
+	*cval = (size_t)cval_l;
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getpolicy_scf() - get the audit policy flags from service
+ */
+boolean_t
+do_getpolicy_scf(uint32_t *policy_mask)
+{
+	int			i;
+	scf_propvec_t		*prop_vect_ptr;
+	char			*cur_policy_str;
+	policy_sw_t		policy_arr[POLICY_TBL_SZ + 1];
+	policy_sw_t		*policy_arr_ptr;
+
+	prop_vect_ptr = prop_vect;
+	policy_arr_ptr = policy_arr;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	bzero(policy_arr, sizeof (policy_arr));
+
+	/* prepare the smf(5) query */
+	for (i = 0; i < POLICY_TBL_SZ; i++) {
+
+		cur_policy_str = policy_table[i].policy_str;
+
+		/* Do some basic policy dependent checks */
+		if (!chk_policy_context(cur_policy_str)) {
+			continue;
+		}
+		DPRINT((dbfp, "will be queried\n"));
+
+		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
+		    SCF_TYPE_BOOLEAN, &policy_arr_ptr->flag);
+
+		policy_arr_ptr->policy = cur_policy_str;
+		policy_arr_ptr++;
+
+	}
+	if (!get_val_scf(prop_vect, ASI_PGROUP_POLICY)) {
+		return (B_FALSE);
+	}
+
+	/* set the policy mask */
+	policy_arr_ptr = policy_arr;
+	*policy_mask = 0;
+	while (policy_arr_ptr->policy != NULL) {
+		if (policy_arr_ptr->flag) {
+			*policy_mask |= get_policy(policy_arr_ptr->policy);
+		}
+		policy_arr_ptr++;
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * do_setpolicy_scf() - sets the policy flags in audit service configuration
+ */
+boolean_t
+do_setpolicy_scf(uint32_t policy)
+{
+	int		i;
+	char		*cur_policy_str;
+	scf_propvec_t	*prop_vect_ptr;
+	boolean_t	bool_arr[POLICY_TBL_SZ];
+	boolean_t	*bool_arr_ptr;
+
+	prop_vect_ptr = prop_vect;
+	bool_arr_ptr = bool_arr;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	bzero(bool_arr, sizeof (bool_arr));
+
+	for (i = 0; i < POLICY_TBL_SZ; i++) {
+
+		cur_policy_str = policy_table[i].policy_str;
+
+		/* Do some basic policy dependent checks */
+		if (!chk_policy_context(cur_policy_str)) {
+			continue;
+		}
+
+		if (policy_table[i].policy_mask & policy) {
+			*bool_arr_ptr = B_TRUE;
+		} else {
+			*bool_arr_ptr = B_FALSE;
+		}
+
+		DPRINT((dbfp, "%s%s\n", (*bool_arr_ptr == B_TRUE ? "+" : "-"),
+		    cur_policy_str));
+
+		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
+		    SCF_TYPE_BOOLEAN, bool_arr_ptr++);
+
+	}
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_POLICY));
+}
+
+/*
+ * do_setqctrl_scf() - set the values of qctrl properties of the audit service
+ */
+boolean_t
+do_setqctrl_scf(struct au_qctrl *cval)
+{
+	scf_propvec_t		*prop_vect_ptr;
+	scf_qctrl_t		cval_scf;
+
+	if (!CHK_BDRY_QHIWATER(cval->aq_lowater, cval->aq_hiwater) &&
+	    cval->aq_hiwater != 0) {
+		(void) printf(gettext("Specified audit queue hiwater mark is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+	if (!CHK_BDRY_QLOWATER(cval->aq_lowater, cval->aq_hiwater) &&
+	    cval->aq_lowater != 0) {
+		(void) printf(gettext("Specified audit queue lowater mark is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+	if (!CHK_BDRY_QBUFSZ(cval->aq_bufsz) && cval->aq_bufsz != 0) {
+		(void) printf(gettext("Specified audit queue buffer size is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+	if (!CHK_BDRY_QDELAY(cval->aq_delay) && cval->aq_delay != 0) {
+		(void) printf(gettext("Specified audit queue delay is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+
+	cval_scf.scf_qhiwater = (uint64_t)cval->aq_hiwater;
+	cval_scf.scf_qlowater = (uint64_t)cval->aq_lowater;
+	cval_scf.scf_qbufsz = (uint64_t)cval->aq_bufsz;
+	cval_scf.scf_qdelay = (uint64_t)cval->aq_delay;
+
+	bzero(prop_vect, sizeof (prop_vect));
+
+	prop_vect_ptr = prop_vect;
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
+	    &cval_scf.scf_qhiwater);
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
+	    &cval_scf.scf_qlowater);
+	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT,
+	    &cval_scf.scf_qbufsz);
+	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY, SCF_TYPE_COUNT,
+	    &cval_scf.scf_qdelay);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
+}
+
+/*
+ * do_setqbufsz_scf() - set the qbufsz property value of the audit service
+ */
+boolean_t
+do_setqbufsz_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+
+	if (!CHK_BDRY_QBUFSZ(*cval) && *cval != 0) {
+		(void) printf(gettext("Specified audit queue buffer size is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+
+	cval_l = (uint64_t)*cval;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT, &cval_l);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
+}
+
+/*
+ * do_setqdelay_scf() - set the qdelay property value of the audit service
+ */
+boolean_t
+do_setqdelay_scf(clock_t *cval)
+{
+	uint64_t	cval_l;
+
+	if (!CHK_BDRY_QDELAY(*cval) && *cval != 0) {
+		(void) printf(gettext("Specified audit queue delay is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+
+	cval_l = (uint64_t)*cval;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT, &cval_l);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
+}
+
+/*
+ * do_setqhiwater_scf() - set the qhiwater property value of the audit service
+ */
+boolean_t
+do_setqhiwater_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+	size_t		cval_lowater;
+
+	if (!do_getqlowater_scf(&cval_lowater)) {
+		(void) printf(gettext("Could not get configured value of "
+		    "queue lowater mark.\n"));
+		return (B_FALSE);
+	}
+	if (cval_lowater == 0) {
+		cval_lowater = AQ_MINLOW;
+	}
+	if (!CHK_BDRY_QHIWATER(cval_lowater, *cval) && *cval != 0) {
+		(void) printf(gettext("Specified audit queue hiwater mark is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+
+	cval_l = (uint64_t)*cval;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
+	    &cval_l);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
+}
+
+/*
+ * do_setqlowater_scf() - set the qlowater property value of the audit service
+ */
+boolean_t
+do_setqlowater_scf(size_t *cval)
+{
+	uint64_t	cval_l;
+	size_t		cval_hiwater;
+
+	if (!do_getqhiwater_scf(&cval_hiwater)) {
+		(void) printf(gettext("Could not get configured value of "
+		    "queue hiwater mark.\n"));
+		return (B_FALSE);
+	}
+	if (cval_hiwater == 0) {
+		cval_hiwater = AQ_MAXHIGH;
+	}
+	if (!CHK_BDRY_QLOWATER(*cval, cval_hiwater) && *cval != 0) {
+		(void) printf(gettext("Specified audit queue lowater mark is "
+		    "outside of allowed boundaries.\n"));
+		return (B_FALSE);
+	}
+
+	cval_l = (uint64_t)*cval;
+
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
+	    &cval_l);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
+}
+
+/*
+ * do_getflags_scf() - get the audit attributable flags from service
+ */
+boolean_t
+do_getflags_scf(char **flags)
+{
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, PRESELECTION_FLAGS, SCF_TYPE_ASTRING,
+	    flags);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_PRESELECTION)) {
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * do_getnaflags_scf() - get the audit non-attributable flags from service
+ */
+boolean_t
+do_getnaflags_scf(char **naflags)
+{
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, PRESELECTION_NAFLAGS, SCF_TYPE_ASTRING,
+	    naflags);
+
+	if (!get_val_scf(prop_vect, ASI_PGROUP_PRESELECTION)) {
+		return (B_FALSE);
+	}
+
+	return (B_TRUE);
+}
+
+/*
+ * do_setflags_scf() - set the attributable mask property value of the audit
+ * service
+ */
+boolean_t
+do_setflags_scf(char *flags)
+{
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, PRESELECTION_FLAGS, SCF_TYPE_ASTRING,
+	    flags);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_PRESELECTION));
+}
+
+/*
+ * do_setnaflags_scf() - set the attributable mask property value of the audit
+ * service
+ */
+boolean_t
+do_setnaflags_scf(char *naflags)
+{
+	bzero(prop_vect, sizeof (prop_vect));
+	add_prop_vect_scf(prop_vect, PRESELECTION_NAFLAGS, SCF_TYPE_ASTRING,
+	    naflags);
+
+	return (set_val_scf(prop_vect, ASI_PGROUP_PRESELECTION));
+}
+
+/*
+ * plugin_avail_scf() - look for the plugin in the audit service configuration
+ */
+boolean_t
+plugin_avail_scf(const char *plugin_str)
+{
+	scf_simple_handle_t	*sh;
+
+	if (plugin_str == NULL || *plugin_str == '\0') {
+		return (B_FALSE);
+	}
+
+	if ((sh = scf_general_pg_setup(AUDITD_FMRI, plugin_str)) == NULL) {
+		DPRINT((dbfp, "No such plugin found: %s (%s)\n", plugin_str,
+		    scf_strerror(scf_error())));
+		return (B_FALSE);
+	}
+
+	scf_simple_handle_destroy(sh);
+	return (B_TRUE);
+}
+
+/*
+ * do_getpluginconfig_scf() - get plugin configuration from the audit service
+ * configuration.
+ */
+boolean_t
+do_getpluginconfig_scf(char *plugin_str, scf_plugin_kva_node_t **plugin_kva_ll)
+{
+
+	char			*asi_fmri;
+	asi_scfhandle_t		handle;
+	asi_scfhandle_iter_t	handle_iter;
+	boolean_t		plugin_all = B_FALSE;
+	boolean_t		rv = B_TRUE;
+
+	if (plugin_str == NULL || *plugin_str == '\0') {
+		if (asprintf(&asi_fmri, "%s", AUDITD_FMRI) == -1) {
+			prt_error(gettext("Out of memory."));
+			return (B_FALSE);
+		}
+		plugin_all = B_TRUE;
+	} else {
+		if (asprintf(&asi_fmri, "%s%s%s", AUDITD_FMRI,
+		    SCF_FMRI_PROPERTYGRP_PREFIX, plugin_str) == -1) {
+			prt_error(gettext("Out of memory."));
+			return (B_FALSE);
+		}
+	}
+	DPRINT((dbfp, "%s will be decoded\n", asi_fmri));
+
+	if (!scf_init(&handle)) {
+		prt_error(gettext("Unable to initialize scf handles."));
+		free(asi_fmri);
+		return (B_FALSE);
+	}
+
+	if (scf_handle_decode_fmri(handle.hndl, asi_fmri, NULL, NULL,
+	    handle.inst, plugin_all ? NULL : handle.pgrp, NULL,
+	    SCF_DECODE_FMRI_EXACT) == -1) {
+		prt_scf_err();
+		scf_free(&handle);
+		free(asi_fmri);
+		return (B_FALSE);
+	}
+
+	if (!scf_init_iter(&handle_iter, &handle)) {
+		prt_error(gettext("Unable to initialize scf iter handles."));
+		scf_free(&handle);
+		free(asi_fmri);
+		return (B_FALSE);
+	}
+
+
+	if (plugin_all) {
+		rv = get_plugin_kva(&handle, &handle_iter, plugin_kva_ll, NULL);
+	} else {
+		rv = get_plugin_kva(&handle, &handle_iter, plugin_kva_ll,
+		    plugin_str);
+	}
+
+	scf_free(&handle);
+	scf_free_iter(&handle_iter);
+	free(asi_fmri);
+	return (rv);
+}
+
+/*
+ * do_setpluginconfig_scf() - set plugin configuration in the audit service
+ * configuration.
+ */
+boolean_t
+do_setpluginconfig_scf(char *plugin_str, boolean_t plugin_state,
+    char *plugin_att, int plugin_qsize)
+{
+	kva_t			*plugin_att_kva = NULL;
+	char			*plugin_att_ptr = plugin_att;
+	char			*plugin_att_clr_ptr = plugin_att;
+	scf_simple_prop_t	*plugin_prop;
+	scf_type_t		plugin_prop_type;
+	scf_propvec_t		*prop_vect_ptr;
+	int			cnt = 0;
+	kv_t			*data;
+	boolean_t		rval = B_TRUE;
+	uint64_t		plugin_qsize_l = (uint64_t)plugin_qsize;
+
+	DPRINT((dbfp, "Auditd plugin configuration to be set:\n\tplugin=%s\n\t"
+	    "state=%d (%s)\n\tattributes=%s\n\tqsize=%d%s\n", plugin_str,
+	    plugin_state, plugin_state == B_TRUE ? "active" : "inactive",
+	    plugin_att == NULL ? " (unspecified)" : plugin_att,
+	    plugin_qsize, plugin_qsize == -1 ? " (unspecified)" : ""));
+
+	bzero(prop_vect, sizeof (prop_vect));
+	prop_vect_ptr = prop_vect;
+
+	if (plugin_att != NULL) {
+
+		/* get rid of white-space chars */
+		if (*plugin_att_ptr != '\0') {
+			while (*plugin_att_ptr != '\0') {
+				if (isspace(*plugin_att_ptr) == 0) {
+					*plugin_att_clr_ptr++ = *plugin_att_ptr;
+				}
+				plugin_att_ptr++;
+			}
+			*plugin_att_clr_ptr = '\0';
+		}
+		DPRINT((dbfp, "attributes (no white-space): %s\n", plugin_att));
+
+		/* allow empty plugin_att */
+		if (*plugin_att == '\0') {
+			cnt = 0;
+			data = NULL;
+		} else {
+			plugin_att_kva = _str2kva(plugin_att, "=", ";");
+			if (plugin_att_kva == NULL) {
+				prt_error(gettext("Could not parse plugin "
+				    "attributes."));
+				return (B_FALSE);
+			}
+
+			free_static_att_kva(plugin_att_kva);
+			cnt = plugin_att_kva->length;
+			data = plugin_att_kva->data;
+		}
+	}
+
+	/* set state */
+	add_prop_vect_scf(prop_vect_ptr++, PLUGIN_ACTIVE, SCF_TYPE_BOOLEAN,
+	    &plugin_state);
+	DPRINT((dbfp, "Prepared active -> %d\n", plugin_state));
+
+	/* set attributes */
+	while (cnt) {
+		if (data->value == NULL) {
+			cnt--;
+			data++;
+			continue;
+		}
+		if (!chk_prop_vect(&prop_vect_ptr, plugin_str)) {
+			rval = B_FALSE;
+			goto err_out;
+		}
+
+		if ((plugin_prop = scf_simple_prop_get(NULL,
+		    AUDITD_FMRI, plugin_str, data->key)) == NULL) {
+			prt_error(gettext("Could not get configuration for "
+			    "attribute: %s"), data->key);
+			prt_scf_err();
+			rval = B_FALSE;
+			goto err_out;
+		}
+		if ((plugin_prop_type = scf_simple_prop_type(plugin_prop))
+		    == -1) {
+			prt_error(gettext("Could not get property type: %s"),
+			    data->key);
+			prt_scf_err();
+			rval = B_FALSE;
+			goto err_out;
+		}
+
+		switch (plugin_prop_type) {
+		case SCF_TYPE_BOOLEAN: {
+			uint8_t	*pval_bool;
+			pval_bool = (uint8_t *)malloc(sizeof (uint8_t));
+			if (pval_bool == NULL) {
+				prt_error(gettext("No free memory available."));
+				rval = B_FALSE;
+				goto err_out;
+			}
+			*pval_bool = (uint8_t)atoi(data->value);
+			add_prop_vect_scf(prop_vect_ptr++, data->key,
+			    SCF_TYPE_BOOLEAN, pval_bool);
+			break;
+		}
+		case SCF_TYPE_ASTRING: {
+			char	*pval_str;
+			if ((pval_str = strdup(data->value)) == NULL) {
+				prt_error(gettext("No free memory available."));
+				rval = B_FALSE;
+				goto err_out;
+			}
+			add_prop_vect_scf(prop_vect_ptr++, data->key,
+			    SCF_TYPE_ASTRING, pval_str);
+			break;
+		}
+		case SCF_TYPE_COUNT: {
+			uint64_t	*pval_count;
+			pval_count = (uint64_t *)malloc(sizeof (uint64_t));
+			if (pval_count == NULL) {
+				prt_error(gettext("No free memory available."));
+				rval = B_FALSE;
+				goto err_out;
+			}
+			*pval_count = (uint64_t)atoll(data->value);
+			add_prop_vect_scf(prop_vect_ptr++, data->key,
+			    SCF_TYPE_COUNT, pval_count);
+			break;
+		}
+		default:
+			prt_error(gettext("Unsupported property type: %s (%d)"),
+			    data->key, plugin_prop_type);
+			break;
+		}
+
+		DPRINT((dbfp, "Prepared %s -> %s\n", data->key, data->value));
+		scf_simple_prop_free(plugin_prop);
+		data++;
+		cnt--;
+	}
+
+	if (!chk_prop_vect(&prop_vect_ptr, plugin_str)) {
+		rval = B_FALSE;
+		goto err_out;
+	}
+
+	/* set qsize */
+	if (plugin_qsize != -1) {
+		add_prop_vect_scf(prop_vect_ptr, PLUGIN_QSIZE, SCF_TYPE_COUNT,
+		    &plugin_qsize_l);
+		DPRINT((dbfp, "Prepared qsize -> %d\n", plugin_qsize));
+	}
+
+	if (!set_val_scf(prop_vect, plugin_str)) {
+		rval = B_FALSE;
+	}
+
+err_out:
+	free_prop_vect();
+	_kva_free(plugin_att_kva);
+	return (rval);
+}
+
+/*
+ * plugin_kva_ll_free() - free the memory used by plugin kva linked list.
+ */
+void
+plugin_kva_ll_free(scf_plugin_kva_node_t *node)
+{
+	scf_plugin_kva_node_t *node_next;
+
+	if (node == NULL) {
+		return;
+	}
+
+	while (node->prev != NULL) {
+		node = node->prev;
+	}
+	while (node != NULL) {
+		_kva_free(node->plugin_kva);
+		node_next = node->next;
+		free(node);
+		node = node_next;
+	}
+}
+
+/*
+ * get_policy() - get policy mask entry
+ */
+uint32_t
+get_policy(char *policy)
+{
+	int i;
+
+	for (i = 0; i < POLICY_TBL_SZ; i++) {
+		if (strcasecmp(policy, policy_table[i].policy_str) == 0) {
+			return (policy_table[i].policy_mask);
+		}
+	}
+
+	return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libbsm/common/audit_scf.h	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _AUDIT_SCF_H
+#define	_AUDIT_SCF_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * auditd smf(5)/libscf(3LIB) interface - set and display audit parameters
+ */
+
+#include <audit_plugin.h>
+#include <bsm/libbsm.h>
+#include <ctype.h>
+#include <libintl.h>
+#include <libscf_priv.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <sys/varargs.h>
+#include <ucontext.h>
+#include <zone.h>
+
+/* gettext() obfuscation routine for lint */
+#ifdef __lint
+#define	gettext(x)	x
+#endif
+
+#ifndef DEBUG
+#define	DEBUG	0
+#endif
+
+#if DEBUG
+FILE	*dbfp;		  /* debug file pointer */
+#define	DPRINT(x)	{ if (dbfp == NULL) dbfp = __auditd_debug_file_open(); \
+			    (void) fprintf x; (void) fflush(dbfp); }
+#else	/* ! DEBUG */
+#define	DPRINT(x)
+#endif
+
+/* Audit subsystem service instances */
+#define	AUDITD_FMRI	"svc:/system/auditd:default"
+#define	AUDITSET_FMRI	"svc:/system/auditset:default"
+
+/* (ASI) Audit service instance SCF handles - libscf(3LIB) */
+struct asi_scfhandle {
+	scf_handle_t		*hndl;	/* base scf handle */
+	scf_instance_t		*inst;	/* service instance handle */
+	scf_propertygroup_t	*pgrp;	/* property group handle */
+	scf_property_t		*prop;	/* property handle */
+};
+typedef	struct asi_scfhandle asi_scfhandle_t;
+
+struct asi_scfhandle_iter {
+	scf_iter_t	*pgrp;		/* property group iter handle */
+	scf_iter_t	*prop;		/* property iter handle */
+	scf_value_t	*prop_val;	/* property value */
+};
+typedef struct asi_scfhandle_iter asi_scfhandle_iter_t;
+
+/*
+ * (ASI) Audit service instance (svc:/system/auditd:default) related
+ * configuration parameters.
+ */
+#define	ASI_PGROUP_POLICY	"policy"
+struct policy_sw {
+	char		*policy;
+	boolean_t	flag;
+};
+typedef struct policy_sw policy_sw_t;
+
+#define	ASI_PGROUP_QUEUECTRL	"queuectrl"
+#define	QUEUECTRL_QBUFSZ	"qbufsz"
+#define	QUEUECTRL_QDELAY	"qdelay"
+#define	QUEUECTRL_QHIWATER	"qhiwater"
+#define	QUEUECTRL_QLOWATER	"qlowater"
+struct scf_qctrl {
+	uint64_t	scf_qhiwater;
+	uint64_t	scf_qlowater;
+	uint64_t	scf_qbufsz;
+	uint64_t	scf_qdelay;
+};
+typedef struct scf_qctrl scf_qctrl_t;
+
+#define	ASI_PGROUP_PRESELECTION	"preselection"
+#define	PRESELECTION_FLAGS	"flags"
+#define	PRESELECTION_NAFLAGS	"naflags"
+#define	PRESELECTION_MAXBUF	256		/* max. length of na/flags */
+
+/* auditd(1M) plugin related well known properties */
+#define	PLUGIN_ACTIVE		"active"	/* plugin state */
+#define	PLUGIN_PATH		"path"		/* plugin shared object */
+#define	PLUGIN_QSIZE		"qsize"		/* plugin queue size */
+
+#define	PLUGIN_MAX		256		/* max. amount of plugins */
+#define	PLUGIN_MAXBUF		256		/* max. length of plugin name */
+#define	PLUGIN_MAXATT		256		/* max. length of plugin attr */
+#define	PLUGIN_MAXKEY		256		/* max. length of plugin key */
+#define	PLUGIN_MAXVAL		256		/* max. length of plugin val */
+struct scf_plugin_kva_node {
+	struct scf_plugin_kva_node	*next;
+	struct scf_plugin_kva_node	*prev;
+	char				plugin_name[PLUGIN_MAXBUF];
+	kva_t				*plugin_kva;
+};
+typedef struct scf_plugin_kva_node scf_plugin_kva_node_t;
+
+/* Boundary checking macros for the queuectrl parameters. */
+#define	AQ_MINLOW	1
+#define	CHK_BDRY_QBUFSZ(x)	!((x) < AQ_BUFSZ || (x) > AQ_MAXBUFSZ)
+#define	CHK_BDRY_QDELAY(x)	!((x) == 0 || (x) > AQ_MAXDELAY)
+#define	CHK_BDRY_QLOWATER(low, high)	!((low) < AQ_MINLOW || (low) >= (high))
+#define	CHK_BDRY_QHIWATER(low, high)	!((high) <= (low) || \
+					    (high) < AQ_LOWATER || \
+					    (high) > AQ_MAXHIGH)
+
+/*
+ * MAX_PROPVECS	maximum number of audit properties that will
+ * 		fit in the uint32_t audit policy mask.
+ */
+#define	MAX_PROPVECS	32
+
+boolean_t do_getflags_scf(char **);
+boolean_t do_getnaflags_scf(char **);
+boolean_t do_getpluginconfig_scf(char *, scf_plugin_kva_node_t **);
+boolean_t do_getpolicy_scf(uint32_t *);
+boolean_t do_getqbufsz_scf(size_t *);
+boolean_t do_getqctrl_scf(struct au_qctrl *);
+boolean_t do_getqdelay_scf(clock_t *);
+boolean_t do_getqhiwater_scf(size_t *);
+boolean_t do_getqlowater_scf(size_t *);
+boolean_t do_setflags_scf(char *);
+boolean_t do_setnaflags_scf(char *);
+boolean_t do_setpluginconfig_scf(char *, boolean_t, char *, int);
+boolean_t do_setpolicy_scf(uint32_t);
+boolean_t do_setqbufsz_scf(size_t *);
+boolean_t do_setqctrl_scf(struct au_qctrl *);
+boolean_t do_setqdelay_scf(clock_t *);
+boolean_t do_setqhiwater_scf(size_t *);
+boolean_t do_setqlowater_scf(size_t *);
+void free_static_att_kva(kva_t *);
+uint32_t get_policy(char *);
+boolean_t plugin_avail_scf(const char *);
+void plugin_kva_ll_free(scf_plugin_kva_node_t *);
+void prt_error_va(char *, va_list);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _AUDIT_SCF_H */
--- a/usr/src/lib/libbsm/common/getacinfo.c	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,445 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-/* getacinfo.c  -  get audit control info */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <bsm/audit.h>
-#include <bsm/libbsm.h>
-#include <synch.h>
-
-#define	DIROP 0
-#define	OTHEROP 1
-
-#define	LEN 360		/* maximum audit control entry length */
-
-#define	SUCCESS 0
-#define	EOF_WARN 1
-#define	REW_WARN 2
-#define	EOF_ERR -1
-#define	ERROR   -2
-#define	FORMAT_ERR -3
-
-static char	*AUDIT_CTRL  = AUDITCONTROLFILE;
-static char	*MINLABEL    = "minfree:";
-static char	*DIRLABEL    = "dir:";
-static char	*DEFFLGLABEL = "flags:";
-static char	*NAFLGLABEL  = "naflags:";
-static int	LASTOP;
-static int	DIRINIT;
-static FILE *acf;    /* pointer into audit control file */
-static mutex_t mutex_acf = DEFAULTMUTEX;
-
-/*
- * getacinfo.c  -  get audit control info
- *
- *	getacdir() - get audit control directories, one at a time
- *	getacflg() - get audit control default audit flags
- *	getacmin() - get audit control directory min. fill value
- *	getacna() -  get audit control non-attrib audit flags
- *	setac()    -  rewind the audit control file
- *	endac()    -  close the audit control file
- *	testac()   -  check if audit control file open
- */
-
-
-/*
- * getacdir() - get audit control directories, one at a time
- *
- * input: len  - size of dir buffer
- *
- * output: dir - directory string
- *
- * returns:	0 - entry read ok
- *		-1 - end of file
- *		-2 - error - can't open audit control file for read
- *		-3 - error - directory entry format error
- *		2 - directory search started from beginning again
- *
- * notes: It is the responsibility of the calling function to
- * 		check the status of the directory entry.
- */
-
-int
-getacdir(char *dir, int len)
-{
-	int	retstat = SUCCESS, gotone = 0, dirlen, dirst;
-	char	entry[LEN];
-	/* void	setac(); */
-
-	/* open file if it is not already opened */
-	(void) mutex_lock(&mutex_acf);
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
-		retstat = ERROR;
-	else if (LASTOP != DIROP && DIRINIT == 1) {
-		retstat = REW_WARN;
-		(void) mutex_unlock(&mutex_acf);
-		setac();
-	} else {
-		DIRINIT = 1;
-		LASTOP = DIROP;
-	}
-	if (retstat >= SUCCESS) do {
-		if (fgets(entry, LEN, acf) != NULL) {
-			switch (*entry) {
-
-			case '#':
-
-			break;
-
-			case 'd':
-
-			/* return directory entry */
-			if (strncmp(entry, DIRLABEL, strlen(DIRLABEL)) == 0) {
-				if ((strlen(entry) + 1) > (size_t)len) {
-					retstat = FORMAT_ERR;
-				} else {
-					/*
-					 * allow zero or one blank
-					 * between colon and directory
-					 */
-					if (entry[strlen(DIRLABEL)] == ' ') {
-						dirst = strlen(DIRLABEL) + 1;
-						dirlen = strlen(entry) -
-						    (strlen(DIRLABEL) + 2);
-					} else {
-						dirst = strlen(DIRLABEL);
-						dirlen = strlen(entry) -
-						    (strlen(DIRLABEL) + 1);
-					}
-					(void) strcpy(dir, entry + dirst);
-					(void) strcpy(dir + dirlen, "\0");
-					gotone = 1;
-				}
-			} else
-				retstat = FORMAT_ERR;
-
-			break;
-
-			case 'm':
-
-			break;
-
-			case 'f':
-
-			break;
-
-			default:
-
-			break;
-
-			} /* end of switch */
-		} else if ((feof(acf)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_ERR;
-		}
-	} while (gotone == 0 && retstat >= SUCCESS);
-
-	(void) mutex_unlock(&mutex_acf);
-	return (retstat);
-}
-
-
-/*
- * getacmin() - get audit control directory min. fill value
- *
- * output: min_val - percentage of directory fill allowed
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error; errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-getacmin(int *min_val)
-{
-	int	retstat = SUCCESS, gotone = 0;
-	char	entry[LEN];
-
-	/* open file if it is not already opened */
-	(void) mutex_lock(&mutex_acf);
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
-		retstat = ERROR;
-	else
-		rewind(acf);
-
-	if (retstat == SUCCESS) {
-		do {
-			if (fgets(entry, LEN, acf) != NULL) {
-				switch (*entry) {
-				case '#':
-					break;
-				case 'd':
-					break;
-				case 'm':
-					if (strncmp(entry, MINLABEL,
-					    strlen(MINLABEL)) == 0) {
-						(void) sscanf(entry +
-						    strlen(MINLABEL),
-						    "%d", min_val);
-						gotone = 1;
-					} else
-						retstat = FORMAT_ERR;
-					break;
-				case 'f':
-					break;
-				default:
-					break;
-				}
-			} else if ((feof(acf)) == 0)
-				retstat = ERROR;
-				else
-				retstat = EOF_WARN;
-
-		} while (gotone == 0 && retstat == SUCCESS);
-	}
-
-	if (LASTOP == DIROP)
-		LASTOP = OTHEROP;
-	else {
-		if (acf != NULL) {
-			(void) fclose(acf);
-			acf = NULL;
-		}
-		LASTOP = DIROP;
-		DIRINIT = 0;
-	}
-
-	(void) mutex_unlock(&mutex_acf);
-	return (retstat);
-}
-
-
-/*
- * getacflg() - get audit control flags
- *
- * output: auditstring - character representation of system audit flags
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error - errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-getacflg(char *auditstring, int len)
-{
-	int	retstat = SUCCESS, gotone = 0, minst, minlen;
-	char	entry[LEN];
-
-	/* open file if it is not already opened */
-	(void) mutex_lock(&mutex_acf);
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
-		retstat = ERROR;
-	else
-		rewind(acf);
-
-	if (retstat == SUCCESS) do {
-		if (fgets(entry, LEN, acf) != NULL) {
-			switch (*entry) {
-			case '#':
-				break;
-			case 'd':
-				break;
-			case 'm':
-				break;
-			case 'f':
-
-			if ((strncmp(entry, DEFFLGLABEL,
-			    strlen(DEFFLGLABEL))) == 0) {
-				if (entry[strlen(DEFFLGLABEL)] == ' ') {
-					minst = strlen(DEFFLGLABEL) + 1;
-					minlen = strlen(entry) -
-					    (strlen(DEFFLGLABEL) + 2);
-				} else {
-					minst = strlen(DEFFLGLABEL);
-					minlen = strlen(entry) -
-					    (strlen(DEFFLGLABEL) + 1);
-				}
-				if (minlen > len)
-					retstat = FORMAT_ERR;
-				else {
-					(void) strcpy(auditstring,
-					    entry + minst);
-					(void) strcpy(auditstring + minlen,
-					    "\0");
-					gotone = 1;
-				}
-			} else
-				retstat = FORMAT_ERR;
-
-			break; /* end of case f */
-
-			default:
-				break;
-			}
-		} else if ((feof(acf)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_WARN;
-		}
-	} while (gotone == 0 && retstat == SUCCESS);
-
-	if (LASTOP == DIROP)
-		LASTOP = OTHEROP;
-	else {
-		if (acf != NULL) {
-			(void) fclose(acf);
-			acf = NULL;
-		}
-		LASTOP = DIROP;
-		DIRINIT = 0;
-	}
-
-	(void) mutex_unlock(&mutex_acf);
-	return (retstat);
-}
-
-
-/*
- * getacna() - get audit flags for non-attributable (server) events
- *
- * output: auditstring - character representation of system audit flags
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error - errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-getacna(char *auditstring, int len)
-{
-	int	retstat = SUCCESS, gotone = 0, minst, minlen;
-	char	entry[LEN];
-
-	/* open file if it is not already opened */
-	(void) mutex_lock(&mutex_acf);
-	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) {
-		retstat = ERROR;
-	} else {
-		rewind(acf);
-	}
-
-	if (retstat == SUCCESS) do {
-		if (fgets(entry, LEN, acf) != NULL)
-			switch (*entry) {
-			case '#':
-				break;
-			case 'd':
-				break;
-			case 'm':
-				break;
-			case 'f':
-				break;
-			case 'n':
-
-			if ((strncmp(entry, NAFLGLABEL,
-			    strlen(NAFLGLABEL))) == 0) {
-				if (entry[strlen(NAFLGLABEL)] == ' ') {
-					minst = strlen(NAFLGLABEL) + 1;
-					minlen = strlen(entry) -
-					    (strlen(NAFLGLABEL) + 2);
-				} else {
-					minst = strlen(NAFLGLABEL);
-					minlen = strlen(entry) -
-					    (strlen(NAFLGLABEL) + 1);
-				}
-				if (minlen > len)
-					retstat = FORMAT_ERR;
-				else {
-					(void) strcpy(auditstring,
-					    entry + minst);
-					(void) strcpy(auditstring + minlen,
-					    "\0");
-					gotone = 1;
-				}
-			} else
-				retstat = FORMAT_ERR;
-
-			break; /* end of case n */
-
-			default:
-				break;
-
-		/* end of if-switch */
-		} else if ((feof(acf)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_WARN;
-		}
-
-	/* end of if-do */
-	} while (gotone == 0 && retstat == SUCCESS);
-
-	if (LASTOP == DIROP)
-		LASTOP = OTHEROP;
-	else {
-		if (acf != NULL) {
-			(void) fclose(acf);
-			acf = NULL;
-		}
-		LASTOP = DIROP;
-		DIRINIT = 0;
-	}
-
-	(void) mutex_unlock(&mutex_acf);
-	return (retstat);
-}
-
-
-/* rewind the audit control file */
-void
-setac()
-{
-	(void) mutex_lock(&mutex_acf);
-	if (acf == NULL)
-		acf = fopen(AUDIT_CTRL, "rF");
-	else
-		rewind(acf);
-	LASTOP = DIROP;
-	DIRINIT = 0;
-	(void) mutex_unlock(&mutex_acf);
-}
-
-
-/* close the audit control file */
-void
-endac()
-{
-	(void) mutex_lock(&mutex_acf);
-	if (acf != NULL) {
-		(void) fclose(acf);
-		acf = NULL;
-	}
-	LASTOP = DIROP;
-	DIRINIT = 0;
-	(void) mutex_unlock(&mutex_acf);
-}
--- a/usr/src/lib/libbsm/common/getacval.c	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-/*
- * get audit control info (replaces getacinfo.c)
- */
-
-#include <secdb.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <bsm/audit.h>
-#include <bsm/libbsm.h>
-#include <stdlib.h>
-#include <string.h>
-#include <synch.h>
-
-#define	REALLY_LONG_LINE 8192
-
-#define	FILE_AT_START 0	/* file pointer is at file start or file is closed */
-#define	FILE_MIDDLE 1	/* file pointer is not at file start */
-
-#define	LEN 360		/* arbitrary audit control entry length */
-
-#define	SUCCESS 0
-#define	EOF_WARN 1
-#define	REW_WARN 2
-#define	EOF_ERR -1
-#define	ERROR   -2
-#define	FORMAT_ERR -3
-#define	NO_CONTEXT -4
-
-/*
- * libbsm.h has opaque typedef:  typedef struct au_acinfo au_acinfo_t
- */
-struct au_acinfo {
-	char	*file;
-	FILE	*fp;
-	int	file_pointer;
-	int	once_read;
-};
-
-static char	*MINLABEL	= "minfree:";
-static char	*DIRLABEL	= "dir:";
-static char	*DEFFLGLABEL	= "flags:";
-static char	*NAFLGLABEL	= "naflags:";
-static char	*lib_label	= "plugin:";
-
-/*
- * get extended line, i.e., interpret trailing "\" and join to make
- * a single line.  Returns NULL on error or EOF, else returns its
- * input pointer.  A line containing only "\" and some blanks is valid.
- *
- * doesn't handle a comment line embedded in a series of continued lines.
- */
-
-static char *
-getlongline(char *line, int length, FILE *fp)
-{
-	int	keepgoing = 1;
-	int	partcount = 0;
-	char	*l, *b;
-	int	end = 0;
-
-	l = line;
-	while (keepgoing) {
-		if (fgets(l, length, fp) != NULL) {
-			partcount++;
-			end = strlen(l);
-			b = l + end - 2;	/* last char before \n */
-			*(b + 1) = '\0';	/* chop the \n */
-			keepgoing = 0;
-			while (b >= l) {
-				if (*b == '\\') {
-					keepgoing = 1;
-					l = b;
-					length -= (end - 1);
-					break;
-				} else if (*b != ' ')
-					break;
-				end--;
-				b--;
-			}
-		} else
-			keepgoing = 0;
-	}
-	if (partcount > 0)
-		return (line);
-	else
-		return (NULL);
-}
-
-/*
- * input a string of the form   attr: xxxxx{\n}
- * and return xxxxx with leading, internal, and trailing blanks removed
- */
-
-static int
-getvalue(char *out_buf, char *line, char *attr_name, int out_len)
-{
-	int	attr_length, value_length;
-	char	*bp, *cp;
-	int	retstat = SUCCESS;
-
-	attr_length = (int)strlen(attr_name);
-	value_length = (int)strlen(line);
-
-	if (strncmp(line, attr_name, attr_length) == 0) {
-		/*
-		 * allow zero or more blanks
-		 * between colon and rest of line
-		 */
-		value_length -= attr_length;
-
-		bp = line + attr_length;
-		while (*bp == ' ') {
-			value_length--;
-			attr_length++; /* offset to first non-blank */
-			bp++;
-		}
-		cp = bp;
-		while (*bp != '\0') {
-			if (*bp == ' ') {
-				bp++;
-				value_length--;
-			} else {
-				*cp++ = *bp++;
-			}
-		}
-		*cp = '\0';
-
-		if (value_length < 1) {
-			*out_buf = '\0';
-			return (retstat);
-		}
-		if ((retstat == SUCCESS) &&
-		    (strlcpy(out_buf, line + attr_length, out_len) >=
-		    out_len))
-			retstat = FORMAT_ERR;
-	} else
-		retstat = FORMAT_ERR;
-
-	return (retstat);
-}
-
-/*
- * getacval.c  -  get audit control info
- *
- *	_getacdir() - get audit control directories, one at a time
- *	_getacflg() - get audit control default audit flags
- *	_getacmin() - get audit control directory min. fill value
- *	_getacna()  - get audit control non-attrib audit flags
- *	_getacplug() - get audit control remote host and associated data
- *	_openac()  - open the audit control file
- *	_endac()    -  close the audit control file
- */
-
-/*
- * _getacdir() - get audit control directories, one at a time
- *
- * input: len  - size of dir buffer
- *
- * output: dir - directory string
- *
- * returns:	0 - entry read ok
- *		-1 - end of file
- *		-2 - error - can't open audit control file for read
- *		-3 - error - directory entry format error
- *		2 - directory search started from beginning again
- *
- * notes: It is the responsibility of the calling function to
- * 		check the status of the directory entry.
- */
-
-int
-_getacdir(au_acinfo_t *context, char *dir, int len)
-{
-	int	retstat = SUCCESS, gotone = 0;
-	char	*entry;
-
-	if (context == NULL)
-		return (NO_CONTEXT);
-
-	entry = malloc(REALLY_LONG_LINE);
-	if (entry == NULL)
-		return (ERROR);
-
-	if ((context->file_pointer != FILE_AT_START) &&
-	    (context->once_read == 1)) {
-		retstat = REW_WARN;
-		_rewindac(context);
-	} else {
-		context->once_read = 1;
-		context->file_pointer = FILE_AT_START;
-	}
-	if (retstat >= SUCCESS) do {
-		if (getlongline(entry, REALLY_LONG_LINE, context->fp) != NULL) {
-			if (*entry == 'd') {
-				retstat = getvalue(dir, entry, DIRLABEL, len);
-				if (retstat == SUCCESS) {
-					if (strlen(dir) == 0) {
-						retstat = FORMAT_ERR;
-					} else {
-						gotone = 1;
-					}
-				}
-			}
-		} else if ((feof(context->fp)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_ERR;
-		}
-	} while (gotone == 0 && retstat >= SUCCESS);
-
-	free(entry);
-	return (retstat);
-}
-
-
-/*
- * _getacmin() - get audit control directory min. fill value
- *
- * output: min_val - percentage of directory fill allowed
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error; errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-_getacmin(au_acinfo_t *context, int *min_val)
-{
-	int	retstat = SUCCESS, gotone = 0;
-
-	char	entry[LEN];
-	char	value[LEN];
-
-	if (context == NULL)
-		return (NO_CONTEXT);
-
-	_rewindac(context);
-
-	if (retstat == SUCCESS) do {
-		if (getlongline(entry, LEN, context->fp) != NULL) {
-			if (*entry == 'm') {
-				retstat = getvalue(value, entry, MINLABEL,
-				    5);	/* sb 2 digits, allow more */
-				if (retstat == SUCCESS) {
-					gotone = 1;
-					*min_val = (int)strtol(value, NULL, 10);
-					if ((*min_val == 0) && (errno != 0))
-						retstat = FORMAT_ERR;
-				}
-			}
-		} else if ((feof(context->fp)) == 0)
-			retstat = ERROR;
-		else
-			retstat = EOF_WARN;
-
-	} while (gotone == 0 && retstat == SUCCESS);
-
-	if (context->file_pointer == FILE_AT_START)
-		context->file_pointer = FILE_MIDDLE;
-	else
-		_rewindac(context);
-
-	return (retstat);
-}
-
-
-/*
- * _getacflg() - get audit control flags
- *
- * output: auditstring - character representation of system audit flags
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error - errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-_getacflg(au_acinfo_t *context, char *auditstring, int len)
-{
-	int	retstat = SUCCESS, gotone = 0;
-	char	*entry;
-
-	if (context == NULL)
-		return (NO_CONTEXT);
-
-	entry = malloc(REALLY_LONG_LINE);
-	if (entry == NULL)
-		return (ERROR);
-
-	_rewindac(context);
-
-	if (retstat == SUCCESS) do {
-		if (getlongline(entry, REALLY_LONG_LINE, context->fp) != NULL) {
-			if (*entry == 'f') {
-				retstat = getvalue(auditstring, entry,
-				    DEFFLGLABEL, len);
-				if (retstat == SUCCESS)
-					gotone = 1;
-			}
-		} else if ((feof(context->fp)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_WARN;
-		}
-	} while (gotone == 0 && retstat == SUCCESS);
-
-	if (context->file_pointer == FILE_AT_START)
-		context->file_pointer = FILE_MIDDLE;
-	else
-		_rewindac(context);
-
-	free(entry);
-	return (retstat);
-}
-
-
-/*
- * _getacna() - get audit flags for non-attributable (server) events
- *
- * output: auditstring - character representation of system audit flags
- *
- * returns:	0 - entry read ok
- *		1 - end of file
- *		-2 - error - errno contains error number
- *		-3 - error - directory entry format error
- */
-
-int
-_getacna(au_acinfo_t *context, char *auditstring, int len)
-{
-	int	retstat = SUCCESS, gotone = 0;
-	char	*entry;
-
-	entry = malloc(REALLY_LONG_LINE);
-	if (entry == NULL)
-		return (ERROR);
-
-	_rewindac(context);
-
-	if (retstat == SUCCESS) do {
-		if (getlongline(entry, REALLY_LONG_LINE, context->fp) != NULL) {
-			if (*entry == 'n') {
-				retstat = getvalue(auditstring, entry,
-				    NAFLGLABEL, len);
-				if (retstat == SUCCESS)
-					gotone = 1;
-			}
-		} else if ((feof(context->fp)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_WARN;
-		}
-	/* end of if-do */
-	} while (gotone == 0 && retstat == SUCCESS);
-
-	if (context->file_pointer == FILE_AT_START)
-		context->file_pointer = FILE_MIDDLE;
-	else
-		_rewindac(context);
-
-	free(entry);
-	return (retstat);
-}
-
-/*
- * _getacplug() - get plugin parameter line
- *
- * As with _getacdir, the caller is responsible for checking the
- * validity of what's returned.
- *
- * outputs:	keyvalue list (call _kva_free(list_ptr) when you're done with
- *		it.)
- *
- * returns:	SUCCESS - entry read ok
- *		EOF_WARN - end of file
- *		REW_WARN - started over at the start of file
- *		ERROR - error - errno contains error number
- *		FORMAT_ERROR - fat finger failure
- */
-#define	MAX_ARG	256
-
-int
-_getacplug(au_acinfo_t *context, kva_t **kv_list)
-{
-	int	retstat = SUCCESS, got_one = 0;
-	char	entry[REALLY_LONG_LINE];
-	char	value[REALLY_LONG_LINE];
-
-	if (context == NULL)
-		return (NO_CONTEXT);
-
-	if (context->file_pointer != FILE_AT_START && context->once_read == 1) {
-		retstat = REW_WARN;
-		_rewindac(context);
-	} else {
-		context->once_read = 1;
-		context->file_pointer = FILE_AT_START;
-	}
-
-	if (retstat == SUCCESS) do {
-		if (getlongline(entry, REALLY_LONG_LINE, context->fp) != NULL) {
-			if (*entry == 'p') {
-				retstat = getvalue(value, entry, lib_label,
-				    REALLY_LONG_LINE);
-				if (retstat == SUCCESS)
-					got_one = 1;
-			}
-		} else if ((feof(context->fp)) == 0) {
-			retstat = ERROR;
-		} else {
-			retstat = EOF_WARN;
-		}
-		/* end of if-do */
-	} while ((got_one == 0) && (retstat == SUCCESS));
-
-	/* value contains a list of attribute/value pairs */
-	if (got_one) {
-		*kv_list = _str2kva(value, "=", ";");
-		if (*kv_list == NULL)
-			retstat = FORMAT_ERR;
-	} else {
-		retstat = EOF_WARN;
-		*kv_list = NULL;
-	}
-lib_exit:
-
-	return (retstat);
-}
-
-/* rewind the audit control file */
-void
-_rewindac(au_acinfo_t *context)
-{
-	rewind(context->fp);
-	context->file_pointer = FILE_AT_START;
-	context->once_read = 0;
-}
-
-/*
- * _openac() open either the audit_control file or an alternate.
- * A NULL input means use the real audit_control.
- */
-
-au_acinfo_t *
-_openac(char *filepath)
-{
-	au_acinfo_t	*context;
-
-	if (filepath == NULL)
-		filepath = AUDITCONTROLFILE;
-
-	context = malloc(sizeof (au_acinfo_t));
-	if (context == NULL)
-		return (NULL);
-
-	context->file = strdup(filepath);
-	if (filepath == NULL) {
-		free(context);
-		return (NULL);
-	}
-	context->fp = fopen(filepath, "rF");
-	if (context->fp == NULL) {
-		free(context->file);
-		free(context);
-		return (NULL);
-	}
-	context->file_pointer = FILE_AT_START;
-	context->once_read = 0;
-	return (context);
-}
-
-/* close the audit control file */
-void
-_endac(au_acinfo_t *context)
-{
-	if (context == NULL)
-		return;
-
-	if (context->fp != NULL)
-		(void) fclose(context->fp);
-
-	free(context->file);
-	free(context);
-}
--- a/usr/src/lib/libbsm/common/getfaudflgs.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/getfaudflgs.c	Tue Jul 27 14:38:47 2010 +0200
@@ -18,68 +18,48 @@
  *
  * CDDL HEADER END
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
 #include <bsm/audit.h>
-
-#define	MAXSTRLEN 360
-
-/*	getfaudflgs.c */
+#include <bsm/libbsm.h>
 
 /*
  * getfauditflags() - combines system event flag mask with user event
  *	flag masks.
  *
  * input: usremasks->as_success - always audit on success
- *	usremasks->as_failure - always audit on failure
- *	usrdmasks->as_success - never audit on success
- *	usrdmasks->as_failure - never audit on failure
+ *	  usremasks->as_failure - always audit on failure
+ *	  usrdmasks->as_success - never audit on success
+ *	  usrdmasks->as_failure - never audit on failure
  *
  * output: lastmasks->as_success - audit on success
- *	lastmasks->as_failure - audit on failure
+ *	   lastmasks->as_failure - audit on failure
  *
- * returns:	0 - ok
- * 		-1 - error
+ * returns:	 0 - ok
+ * 		-1 - error (cannot get attributable mask)
  */
-
-extern int getauditflagsbin();
-extern int getacflg();
-
 int
-getfauditflags(usremasks, usrdmasks, lastmasks)
-au_mask_t *usremasks;
-au_mask_t *usrdmasks;
-au_mask_t *lastmasks;
+getfauditflags(au_mask_t *usremasks, au_mask_t *usrdmasks, au_mask_t *lastmasks)
 {
-	int	len = MAXSTRLEN, retstat = 0;
-	char	s_auditstring[MAXSTRLEN];
-	audit_state_t masks;
+	au_mask_t masks;
 
-	masks.as_success = 0;
-	masks.as_failure = 0;
 	/* get system audit mask and convert to bit mask */
-	if ((getacflg(s_auditstring, len)) >= 0)  {
-		if ((getauditflagsbin(s_auditstring, &masks)) != 0)
-			retstat = -1;
-	} else
-		retstat = -1;
+	if (auditon(A_GETAMASK, (caddr_t)&masks, sizeof (masks)) == -1) {
+		return (-1);
+	}
 
 	/* combine system and user event masks */
-	if (retstat == 0) {
-		lastmasks->as_success = masks.as_success;
-		lastmasks->as_failure = masks.as_failure;
+	lastmasks->as_success = masks.as_success;
+	lastmasks->as_failure = masks.as_failure;
+
+	lastmasks->as_success |= usremasks->as_success;
+	lastmasks->as_failure |= usremasks->as_failure;
 
-		lastmasks->as_success |= usremasks->as_success;
-		lastmasks->as_failure |= usremasks->as_failure;
+	lastmasks->as_success &= ~(usrdmasks->as_success);
+	lastmasks->as_failure &= ~(usrdmasks->as_failure);
 
-		lastmasks->as_success &= ~(usrdmasks->as_success);
-		lastmasks->as_failure &= ~(usrdmasks->as_failure);
-	}
-	return (retstat);
+	return (0);
 }
--- a/usr/src/lib/libbsm/common/libbsm.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/libbsm.h	Tue Jul 27 14:38:47 2010 +0200
@@ -85,11 +85,6 @@
 } au_user_str_t;
 
 /*
- * opaque context value for getacval.c
- */
-typedef struct au_acinfo au_acinfo_t;
-
-/*
  * adrf's version of adr_t
  */
 typedef struct adrf_s {
@@ -176,34 +171,6 @@
 extern au_class_ent_t *getauclassnam_r(au_class_ent_t *, char *);
 
 /*
- * Functions that manipulate the audit control file
- */
-
-void	endac(void);
-void	setac(void);
-
-int	getacdir(char *, int);
-int	getacmin(int *);
-int	getacna(char *, int);
-int	getacflg(char *, int);
-
-/*
- * Functions that manipulate the audit control file
- */
-
-
-au_acinfo_t	*_openac(char *);
-void		_endac(au_acinfo_t *);
-void		_rewindac(au_acinfo_t *);
-
-int		_getacdir(au_acinfo_t *, char *, int);
-int		_getaclib(au_acinfo_t *, kva_t **);
-int		_getacmin(au_acinfo_t *, int *);
-int		_getacna(au_acinfo_t *, char *, int);
-int		_getacflg(au_acinfo_t *, char *, int);
-int		_getacplug(au_acinfo_t *, kva_t **);
-
-/*
  * Functions that manipulate audit masks
  */
 
@@ -250,7 +217,6 @@
 
 /* system audit files for auditd */
 #define	AUDITCLASSFILE		"/etc/security/audit_class"
-#define	AUDITCONTROLFILE	"/etc/security/audit_control"
 #define	AUDITEVENTFILE		"/etc/security/audit_event"
 #define	AUDITUSERFILE		"/etc/security/audit_user"
 
--- a/usr/src/lib/libbsm/common/llib-lbsm	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/llib-lbsm	Tue Jul 27 14:38:47 2010 +0200
@@ -22,8 +22,7 @@
 /* PROTOLIB1 */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <bsm/devices.h>
@@ -36,3 +35,4 @@
 #include <bsm/adt_event.h>
 #include <bsm/audit_private.h>
 #include <audit_plugin.h>
+#include <audit_scf.h>
--- a/usr/src/lib/libbsm/common/mapfile-vers	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libbsm/common/mapfile-vers	Tue Jul 27 14:38:47 2010 +0200
@@ -94,13 +94,8 @@
 	au_to_text;
 	au_user_mask;
 	au_write;
-	endac;
 	endauclass;
 	endauevent;
-	getacdir;
-	getacflg;
-	getacmin;
-	getacna;
 	getauclassent;
 	getauclassnam;
 	getaudit;
@@ -112,7 +107,6 @@
 	getauevnum;
 	getauid;
 	getfauditflags;
-	setac;
 	setauclass;
 	setaudit;
 	setauevent;
@@ -296,18 +290,31 @@
 	da_rm_list_entry;
 	da_update_defattrs;
 	da_update_device;
-	_endac;
+	do_getflags_scf;
+	do_getnaflags_scf;
+	do_getpluginconfig_scf;
+	do_getpolicy_scf;
+	do_getqbufsz_scf;
+	do_getqctrl_scf;
+	do_getqdelay_scf;
+	do_getqhiwater_scf;
+	do_getqlowater_scf;
+	do_setflags_scf;
+	do_setnaflags_scf;
+	do_setpluginconfig_scf;
+	do_setpolicy_scf;
+	do_setqbufsz_scf;
+	do_setqctrl_scf;
+	do_setqdelay_scf;
+	do_setqhiwater_scf;
+	do_setqlowater_scf;
 	enddadefent;
 	enddaent;
 	enddmapent;
 	freedadefent;
 	freedaent;
 	freedmapent;
-	_getacdir;
-	_getacflg;
-	_getacmin;
-	_getacna;
-	_getacplug;
+	free_static_att_kva;
 	getdadefent;
 	getdadeftype;
 	getdadmline;
@@ -321,9 +328,11 @@
 	getdmapfield;
 	getdmapnam;
 	getdmaptype;
+	get_policy;
 	__logpost;
-	_openac;
-	_rewindac;
+	plugin_avail_scf;
+	plugin_kva_ll_free;
+	prt_error_va;
 	setdadefent;
 	setdaent;
 	setdafile;
--- a/usr/src/lib/libsecdb/auth_attr.txt	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/auth_attr.txt	Tue Jul 27 14:38:47 2010 +0200
@@ -37,9 +37,7 @@
 solaris.admin.wusb.modify:::Add or delete information of Wireless USB Device::help=WUSBmodify.html
 solaris.admin.wusb.host:::Manage Wireless USB Host::help=WUSBhost.html
 #
-solaris.audit.:::Audit Management::help=AuditHeader.html
-solaris.audit.config:::Configure Auditing::help=AuditConfig.html
-solaris.audit.read:::Read Audit Trail::help=AuditRead.html
+solaris.audit.:::Audit System-wide Management::help=AuditHeader.html
 #
 solaris.device.:::Device Allocation::help=DevAllocHeader.html
 solaris.device.allocate:::Allocate Device::help=DevAllocate.html
@@ -124,6 +122,7 @@
 solaris.smf.modify.application:::Modify Application Type Properties::help=SmfModifyAppl.html
 solaris.smf.modify.framework:::Modify Framework Type Properties::help=SmfModifyFramework.html
 solaris.smf.manage.:::Manage All SMF Service States::help=SmfManageHeader.html
+solaris.smf.manage.audit:::Manage Audit Service States::help=SmfManageAudit.html
 solaris.smf.manage.autofs:::Manage Automount Service States::help=SmfAutofsStates.html
 solaris.smf.manage.bind:::Manage DNS Service States::help=BindStates.html
 solaris.smf.manage.coreadm:::Manage Coreadm Service States::help=SmfCoreadmStates.html
@@ -162,6 +161,7 @@
 solaris.smf.manage.wpa:::Manage WPA Service States::help=SmfWpaStates.html
 solaris.smf.manage.ndmp:::Manage NDMP Service States::help=SmfNDMPStates.html
 solaris.smf.value.:::Change Values of SMF Service Properties::help=SmfValueHeader.html
+solaris.smf.value.audit:::Configure the Audit Service::help=SmfValueAudit.html
 solaris.smf.value.coreadm:::Change Values of SMF Coreadm Properties::help=SmfValueCoreadm.html
 solaris.smf.value.discovery.printers.snmp:::Manage Network Attached Device Discovery Service Properties::help=SmfValueNADD.html
 solaris.smf.value.extended-accounting.flow:::Change Values of Flow Extended Accounting Service Properties::help=SmfValueExAcctFlow.html
--- a/usr/src/lib/libsecdb/common/mapfile-vers	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/common/mapfile-vers	Tue Jul 27 14:38:47 2010 +0200
@@ -81,6 +81,7 @@
 	_kva2str;
 	_kva_dup;
 	_kva_free;
+	_kva_free_value;
 	_new_kva;
 	_str2kva;
 	_enum_profs;
--- a/usr/src/lib/libsecdb/common/secdb.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/common/secdb.c	Tue Jul 27 14:38:47 2010 +0200
@@ -49,7 +49,7 @@
 	kv_t	*data;
 
 	if (kva == NULL || key == NULL) {
-		return ((char *)NULL);
+		return (NULL);
 	}
 	data = kva->data;
 	for (i = 0; i < kva->length; i++) {
@@ -58,7 +58,7 @@
 		}
 	}
 
-	return ((char *)NULL);
+	return (NULL);
 }
 
 /*
@@ -89,6 +89,32 @@
 }
 
 /*
+ * _kva_free_value(): Free up memory (value) for all the occurrences of
+ * the given key.
+ */
+void
+_kva_free_value(kva_t *kva, char *key)
+{
+	int	ctr;
+	kv_t	*data;
+
+	if (kva == NULL) {
+		return;
+	}
+
+	ctr = kva->length;
+	data = kva->data;
+
+	while (ctr--) {
+		if (strcmp(data->key, key) == 0 && data->value != NULL) {
+			free(data->value);
+			data->value = NULL;
+		}
+		data++;
+	}
+}
+
+/*
  * new_kva(): Allocate a key-value array.
  */
 kva_t  *
@@ -97,11 +123,11 @@
 	kva_t	*new_kva;
 
 	if ((new_kva = (kva_t *)calloc(1, sizeof (kva_t))) == NULL) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	if ((new_kva->data = (kv_t *)calloc(1, (size*sizeof (kv_t)))) == NULL) {
 		free(new_kva);
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 
 	return (new_kva);
@@ -132,7 +158,7 @@
 	    *s == '\0' ||
 	    *s == '\n' ||
 	    (strlen(s) <= 1)) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	p = s;
 	while ((p = _strpbrk_escape(p, ass)) != NULL) {
@@ -147,12 +173,12 @@
 		size = m * KV_ADD_KEYS;
 	}
 	if ((nkva = _new_kva(size)) == NULL) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	data = nkva->data;
 	nkva->length = 0;
 	if ((buf = strdup(s)) == NULL) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	pair = _strtok_escape(buf, del, &last_pair);
 	do {
@@ -172,43 +198,34 @@
  * (buf). Use delimeter (del) to separate pairs.  Use assignment character
  * (ass) to separate keys and values.
  *
- * Return Values: 0  Success 1  Buffer too small 2  Out of memory
+ * Return Values: 0  Success 1  Buffer too small
  */
 int
 _kva2str(kva_t *kva, char *buf, int buflen, char *ass, char *del)
 {
 	int	i;
-	int	length = 0;
-	char	*tmp;
+	int	len;
+	int	off = 0;
 	kv_t	*data;
 
 	if (kva == NULL) {
 		return (0);
 	}
+
+	buf[0] = '\0';
 	data = kva->data;
+
 	for (i = 0; i < kva->length; i++) {
 		if (data[i].value != NULL) {
-			length += 2 + strlen(data[i].value);
+			len = snprintf(buf + off, buflen - off, "%s%s%s%s",
+			    data[i].key, ass, data[i].value, del);
+			if (len < 0 || len + off >= buflen) {
+				return (1);
+			}
+			off += len;
 		}
 	}
-	if (length > buflen) {
-		return (1);
-	}
-	(void) memset(buf, 0, buflen);
-	if ((tmp = (char *)malloc(buflen)) == NULL) {
-		return (2);
-	}
-	for (i = 0; i < kva->length; i++) {
-		if (data[i].value != NULL) {
-			if (snprintf(tmp, buflen, "%s%s%s%s",
-			    data[i].key, ass, data[i].value, del) >= buflen) {
-				free((void *)tmp);
-				return (0);
-			}
-			(void) strcat(buf, tmp);
-		}
-	}
-	free((void *)tmp);
+
 	return (0);
 }
 
@@ -240,15 +257,15 @@
 	int	size;
 	kv_t	*old_data;
 	kv_t	*new_data;
-	kva_t 	*nkva = (kva_t *)NULL;
+	kva_t 	*nkva = NULL;
 
 	if (old_kva == NULL) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	old_data = old_kva->data;
 	size = old_kva->length;
 	if ((nkva = _new_kva(size)) == NULL) {
-		return ((kva_t *)NULL);
+		return (NULL);
 	}
 	new_data = nkva->data;
 	nkva->length = old_kva->length;
@@ -309,10 +326,10 @@
 {
 	int len = 0;
 	int i = 0;
-	char *newstr = (char *)NULL;
+	char *newstr = NULL;
 
 	if (strings == NULL)
-		return ((char *)NULL);
+		return (NULL);
 	for (i = 0; strings[i] != NULL; i++) {
 		len += strlen(strings[i]) + 1;
 	}
@@ -325,7 +342,7 @@
 		newstr[len-1] = NULL;
 		return (newstr);
 	} else
-		return ((char *)NULL);
+		return (NULL);
 }
 
 
@@ -335,10 +352,10 @@
 	int len = 0;
 	int ncommas = 0;
 	int i = 0;
-	char **spc = (char **)NULL;
-	char *copy = (char *)NULL;
+	char **spc = NULL;
+	char *copy = NULL;
 	char *pc;
-	char *lasts = (char *)NULL;
+	char *lasts = NULL;
 
 	len = strlen(csl);
 	for (i = 0; i < len; i++) {
@@ -346,7 +363,7 @@
 			ncommas++;
 	}
 	if ((spc = (char **)malloc((ncommas + 2) * sizeof (char *))) == NULL) {
-		return ((char **)NULL);
+		return (NULL);
 	}
 	copy = strdup(csl);
 	for (pc = strtok_r(copy, ",", &lasts), i = 0; pc != NULL;
@@ -378,12 +395,14 @@
 	kv_t	*data;
 
 	if (kva == NULL) {
-		printf("  (empty)\n");
+		(void) printf("  (empty)\n");
 		return;
 	}
 	data = kva->data;
 	for (i = 0; i < kva->length; i++) {
-		printf("  %s = %s\n", data[i].key, data[i].value);
+		(void) printf("  %s = %s\n",
+		    data[i].key != NULL ? data[i].key : "NULL",
+		    data[i].value != NULL ? data[i].value : "NULL");
 	}
 }
 #endif  /* DEBUG */
--- a/usr/src/lib/libsecdb/exec_attr.txt	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/exec_attr.txt	Tue Jul 27 14:38:47 2010 +0200
@@ -27,15 +27,11 @@
 #
 #
 All:suser:cmd:::*:
-Audit Control:suser:cmd:::/etc/security/bsmconv:uid=0
-Audit Control:suser:cmd:::/etc/security/bsmunconv:uid=0
-Audit Control:solaris:cmd:::/usr/sbin/audit:privs=sys_audit,file_dac_read,proc_owner
-Audit Control:suser:cmd:::/usr/sbin/audit:euid=0
-Audit Control:suser:cmd:::/usr/sbin/auditconfig:euid=0
-Audit Control:suser:cmd:::/usr/sbin/auditd:uid=0
-Audit Review:suser:cmd:::/usr/sbin/auditreduce:euid=0
-Audit Review:suser:cmd:::/usr/sbin/auditstat:euid=0
-Audit Review:suser:cmd:::/usr/sbin/praudit:euid=0
+Audit Control:solaris:cmd:::/usr/sbin/audit:privs=proc_owner,sys_audit
+Audit Configuration:solaris:::/usr/sbin/auditconfig:privs=sys_audit
+Audit Review:solaris:cmd:::/usr/sbin/auditreduce:euid=0
+Audit Review:solaris:cmd:::/usr/sbin/auditstat:privs=proc_audit
+Audit Review:solaris:cmd:::/usr/sbin/praudit:privs=file_dac_read
 Contract Observer:solaris:cmd:::/usr/bin/ctwatch:\
 	privs=contract_event,contract_observer
 Cron Management:suser:cmd:::/usr/bin/crontab:euid=0
--- a/usr/src/lib/libsecdb/help/auths/AuditConfig.html	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-<HTML>
-<!--
-    Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-    Use is subject to license terms.
-
-    CDDL HEADER START
-
-    The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
-
-    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-    or http://www.opensolaris.org/os/licensing.
-    See the License for the specific language governing permissions
-    and limitations under the License.
-
-    When distributing Covered Code, include this CDDL HEADER in each
-    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-    If applicable, add the following below this CDDL HEADER, with the
-    fields enclosed by brackets "[]" replaced with your own identifying
-    information: Portions Copyright [yyyy] [name of copyright owner]
-
-    CDDL HEADER END
--->
-<!-- SCCS keyword
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
--->
-
-<HEAD>
-<!--
-META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"
--->
-<!-- 
-META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]"
--->
-</HEAD>
-<BODY>
-When Configure Auditing is in the Authorizations Included column, it grants the authorization to configure the auditing attributes
-for specific users, files, and machines.
-<p>
-If Configure Auditing is grayed, then you are not entitled to Add or Remove this authorization. 
-<BR>&nbsp;
-</BODY>
-</HTML>
--- a/usr/src/lib/libsecdb/help/auths/AuditHeader.html	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/help/auths/AuditHeader.html	Tue Jul 27 14:38:47 2010 +0200
@@ -1,14 +1,12 @@
-<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
 <!--
-    Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-    Use is subject to license terms.
-
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -22,16 +20,17 @@
     information: Portions Copyright [yyyy] [name of copyright owner]
 
     CDDL HEADER END
--->
-<!-- SCCS keyword
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+    Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 -->
-<!-- 
-   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
-   <META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
--->
-<BODY>
-Audit Management Authorization Help
-<BR>&nbsp;
-</BODY>
-</HTML>
+<head>
+<title>solaris.audit.</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
+
+<body>
+<p>
+	Audit System-wide Management Authorization Help
+</p>
+</body>
+</html>
--- a/usr/src/lib/libsecdb/help/auths/AuditRead.html	Tue Jul 27 16:58:46 2010 +0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<HTML>
-<!--
-    Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-    Use is subject to license terms.
-
-    CDDL HEADER START
-
-    The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
-
-    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-    or http://www.opensolaris.org/os/licensing.
-    See the License for the specific language governing permissions
-    and limitations under the License.
-
-    When distributing Covered Code, include this CDDL HEADER in each
-    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-    If applicable, add the following below this CDDL HEADER, with the
-    fields enclosed by brackets "[]" replaced with your own identifying
-    information: Portions Copyright [yyyy] [name of copyright owner]
-
-    CDDL HEADER END
--->
-<!-- SCCS keyword
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
--->
-<HEAD>
-<!--
-META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"
--->
-<!-- 
-META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]"
--->
-</HEAD>
-<BODY>
-When Read Audit Trail is in the Authorizations Included column, it grants the authorization to read the audit trail.
-<p>
-If Read Audit Trail is grayed, then you are not entitled to Add or Remove this authorization. 
-<BR>&nbsp;
-</BODY>
-</HTML>
--- a/usr/src/lib/libsecdb/help/auths/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/help/auths/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -28,9 +28,7 @@
 include ../../../../Makefile.master
 
 HTMLENTS = \
-	AuditConfig.html \
 	AuditHeader.html \
-	AuditRead.html \
 	DevAllocHeader.html \
 	DevAllocate.html \
 	DevConfig.html \
@@ -79,6 +77,7 @@
 	SmfInetdStates.html \
 	SmfIPsecStates.html \
 	SmfLocationStates.html \
+	SmfManageAudit.html \
 	SmfManageHeader.html \
 	SmfManageHotplug.html \
 	SmfMDNSStates.html \
@@ -97,6 +96,7 @@
 	SmfSendmailStates.html \
 	SmfSshStates.html \
 	SmfSyslogStates.html \
+	SmfValueAudit.html \
 	SmfValueCoreadm.html \
 	SmfValueExAcctFlow.html \
 	SmfValueExAcctProcess.html \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsecdb/help/auths/SmfManageAudit.html	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+
+    Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+-->
+<head>
+<title>solaris.smf.manage.audit</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
+
+<body>
+<p>
+	When Manage Audit Service is in the Authorizations Include column,
+	it grants the authorization to enable, disable, or restart the audit
+	service.
+</p>
+<p> 
+	If Manage Audit Service is grayed, then you are not entitled to
+	Add or Remove this authorization.
+</p>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsecdb/help/auths/SmfValueAudit.html	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+
+    Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+-->
+<head>
+<title>solaris.smf.value.audit</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
+
+<body>
+<p>
+	When Configure Audit is in the Authorizations Included column,
+	it grants authorization to configure the Audit service.
+</p>
+<p>  
+	If Configure Audit is grayed, then you are not entitled to Add
+	or Remove this authorization.
+</p>
+</body>
+</html>
--- a/usr/src/lib/libsecdb/help/profiles/Makefile	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/help/profiles/Makefile	Tue Jul 27 14:38:47 2010 +0200
@@ -26,6 +26,7 @@
 HTMLENTS = \
 	RtAcctadm.html \
 	RtAll.html \
+	RtAuditCfg.html \
 	RtAuditCtrl.html \
 	RtAuditReview.html \
 	RtContractObserver.html \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libsecdb/help/profiles/RtAuditCfg.html	Tue Jul 27 14:38:47 2010 +0200
@@ -0,0 +1,41 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+
+    Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+-->
+<head>
+<title>Audit Configuration</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
+
+<body>
+<p>
+	When Audit Configuration is in the Rights Included column, it grants the
+	right to configure audit service.
+</p>
+<p>
+	If Audit Configuration is grayed, then you are not entitled to Add or
+	Remove this right.
+</p>
+</body>
+</html>
--- a/usr/src/lib/libsecdb/help/profiles/RtAuditCtrl.html	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/help/profiles/RtAuditCtrl.html	Tue Jul 27 14:38:47 2010 +0200
@@ -1,11 +1,12 @@
-<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
 <!--
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -20,21 +21,23 @@
 
     CDDL HEADER END
 
--- Copyright 2000 Sun Microsystems, Inc.  All rights reserved.
--- Use is subject to license terms.
+    Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 -->
-<HEAD>
-	<TITLE> </TITLE>
-	 
-	
-</HEAD>
-<BODY>
-<!-- ident	"%Z%%M%	%I%	%E% SMI" -->
+<head>
+<title>Audit Control</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
 
-When Audit Control is in the Rights Included column, it grants the right to manage the audit subsystem (which keeps track of event information), but not the right to read the audit files (see Audit Review).
-<p>
-If Audit Control is grayed, then you are not entitled to Add or Remove this right.
+<body>
 <p>
+	When Audit Control is in the Rights Included column, it grants the right
+	to manage the audit service states (enable/disable/refresh/restart)
+	but not the right to read the audit configuration
+	(see Audit Configuration).
+</p>
 <p>
-</BODY>
-</HTML>
+	If Audit Control is grayed, then you are not entitled to Add or Remove
+	this right.
+</p>
+</body>
+</html>
--- a/usr/src/lib/libsecdb/help/profiles/RtAuditReview.html	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/help/profiles/RtAuditReview.html	Tue Jul 27 14:38:47 2010 +0200
@@ -1,11 +1,12 @@
-<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
 <!--
     CDDL HEADER START
 
     The contents of this file are subject to the terms of the
-    Common Development and Distribution License, Version 1.0 only
-    (the "License").  You may not use this file except in compliance
-    with the License.
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
 
     You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     or http://www.opensolaris.org/os/licensing.
@@ -20,20 +21,23 @@
 
     CDDL HEADER END
 
--- Copyright 2000 Sun Microsystems, Inc.  All rights reserved.
--- Use is subject to license terms.
+    Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
 -->
-<HEAD>
-	<TITLE> </TITLE>
-	 
-	
-</HEAD>
-<BODY>
-<!-- ident	"%Z%%M%	%I%	%E% SMI" -->
+<head>
+<title>Audit Review</title>
+<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
+</head>
 
-When Audit Review is in the Rights Included column, it grants the right to read the audit trail, but not the right to manage the audit subsystem (see Audit Control).
+<body>
 <p>
-If Audit Review is grayed, then you are not entitled to Add or Remove this right.
+	When Audit Review is in the Rights Included column, it grants the right
+	to read the audit trail, but not the right to manage the audit service
+	states (see Audit Control) or change the audit service configuration
+	(see Audit Configuration).
+</p>
 <p>
-</BODY>
-</HTML>
+	If Audit Review is grayed, then you are not entitled to Add or
+	Remove this right.
+</p>
+</body>
+</html>
--- a/usr/src/lib/libsecdb/prof_attr.txt	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/lib/libsecdb/prof_attr.txt	Tue Jul 27 14:38:47 2010 +0200
@@ -27,8 +27,9 @@
 # profiles attributes. see prof_attr(4)
 #
 All:::Execute any command as the user or role:help=RtAll.html
-Audit Control:::Configure Solaris Auditing:auths=solaris.audit.config,solaris.jobs.admin;help=RtAuditCtrl.html
-Audit Review:::Review Solaris Auditing logs:auths=solaris.audit.read;help=RtAuditReview.html
+Audit Configuration:::Configure Solaris Audit:auths=solaris.smf.value.audit;help=RtAuditCfg.html
+Audit Control:::Control Solaris Audit:auths=solaris.smf.manage.audit;help=RtAuditCtrl.html
+Audit Review:::Review Solaris Auditing logs:help=RtAuditReview.html
 Console User:::Manage System as the Console User:profiles=Suspend To RAM,Suspend To Disk,Brightness,CPU Power Management,Network Autoconf User;auths=solaris.system.shutdown;help=RtConsUser.html
 Contract Observer:::Reliably observe any/all contract events:help=RtContractObserver.html
 Device Management:::Control Access to Removable Media:auths=solaris.device.*;help=RtDeviceMngmnt.html
--- a/usr/src/pkg/manifests/SUNWcs.mf	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/pkg/manifests/SUNWcs.mf	Tue Jul 27 14:38:47 2010 +0200
@@ -439,7 +439,6 @@
 file path=etc/saf/_sysconfig group=sys preserve=true
 file path=etc/saf/zsmon/_pmtab group=sys preserve=true
 file path=etc/security/audit_class group=sys preserve=renamenew
-file path=etc/security/audit_control group=sys preserve=renamenew
 file path=etc/security/audit_event group=sys preserve=renamenew
 file path=etc/security/audit_warn group=sys mode=0740 preserve=renamenew
 file path=etc/security/auth_attr group=sys preserve=true \
@@ -553,6 +552,7 @@
 file path=lib/svc/manifest/network/socket-filter-kssl.xml group=sys mode=0444
 file path=lib/svc/manifest/network/ssl/kssl-proxy.xml group=sys mode=0444
 file path=lib/svc/manifest/system/auditd.xml group=sys mode=0444
+file path=lib/svc/manifest/system/auditset.xml group=sys mode=0444
 file path=lib/svc/manifest/system/boot-archive-update.xml group=sys mode=0444
 file path=lib/svc/manifest/system/boot-archive.xml group=sys mode=0444
 file path=lib/svc/manifest/system/boot-config.xml group=sys mode=0444
@@ -618,6 +618,7 @@
 file path=lib/svc/method/rmtmpfiles mode=0555
 file path=lib/svc/method/rpc-bind mode=0555
 file path=lib/svc/method/svc-auditd mode=0555
+file path=lib/svc/method/svc-auditset mode=0555
 file path=lib/svc/method/svc-boot-config mode=0555
 file path=lib/svc/method/svc-consadm mode=0555
 file path=lib/svc/method/svc-cron mode=0555
@@ -1022,9 +1023,7 @@
 file path=usr/lib/fs/ufs/volcopy mode=0555
 file path=usr/lib/getoptcvt mode=0555
 file path=usr/lib/help/auths/locale/C/AllSolAuthsHeader.html
-file path=usr/lib/help/auths/locale/C/AuditConfig.html
 file path=usr/lib/help/auths/locale/C/AuditHeader.html
-file path=usr/lib/help/auths/locale/C/AuditRead.html
 file path=usr/lib/help/auths/locale/C/AuthJobsAdmin.html
 file path=usr/lib/help/auths/locale/C/AuthJobsUser.html
 file path=usr/lib/help/auths/locale/C/AuthProfmgrAssign.html
@@ -1080,6 +1079,7 @@
 file path=usr/lib/help/auths/locale/C/SmfInetdStates.html
 file path=usr/lib/help/auths/locale/C/SmfLocationStates.html
 file path=usr/lib/help/auths/locale/C/SmfMDNSStates.html
+file path=usr/lib/help/auths/locale/C/SmfManageAudit.html
 file path=usr/lib/help/auths/locale/C/SmfManageHeader.html
 file path=usr/lib/help/auths/locale/C/SmfManageHotplug.html
 file path=usr/lib/help/auths/locale/C/SmfManageZFSSnap.html
@@ -1101,6 +1101,7 @@
 file path=usr/lib/help/auths/locale/C/SmfSshStates.html
 file path=usr/lib/help/auths/locale/C/SmfSyslogStates.html
 file path=usr/lib/help/auths/locale/C/SmfVRRPStates.html
+file path=usr/lib/help/auths/locale/C/SmfValueAudit.html
 file path=usr/lib/help/auths/locale/C/SmfValueCoreadm.html
 file path=usr/lib/help/auths/locale/C/SmfValueExAcctFlow.html
 file path=usr/lib/help/auths/locale/C/SmfValueExAcctNet.html
@@ -1142,6 +1143,7 @@
 file path=usr/lib/help/auths/locale/C/ZoneManage.html
 file path=usr/lib/help/profiles/locale/C/RtAcctadm.html
 file path=usr/lib/help/profiles/locale/C/RtAll.html
+file path=usr/lib/help/profiles/locale/C/RtAuditCfg.html
 file path=usr/lib/help/profiles/locale/C/RtAuditCtrl.html
 file path=usr/lib/help/profiles/locale/C/RtAuditReview.html
 file path=usr/lib/help/profiles/locale/C/RtCPUPowerManagement.html
--- a/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf	Tue Jul 27 14:38:47 2010 +0200
@@ -73,9 +73,7 @@
 dir path=usr/share/lib/locale/com/sun/dhcpmgr/ui
 dir path=usr/share/lib/locale/com/sun/slp
 file path=usr/lib/help/auths/locale/AllSolAuthsHeader.html
-file path=usr/lib/help/auths/locale/AuditConfig.html
 file path=usr/lib/help/auths/locale/AuditHeader.html
-file path=usr/lib/help/auths/locale/AuditRead.html
 file path=usr/lib/help/auths/locale/AuthJobsAdmin.html
 file path=usr/lib/help/auths/locale/AuthJobsUser.html
 file path=usr/lib/help/auths/locale/AuthProfmgrAssign.html
@@ -153,6 +151,7 @@
 file path=usr/lib/help/auths/locale/SmfInetdStates.html
 file path=usr/lib/help/auths/locale/SmfLocationStates.html
 file path=usr/lib/help/auths/locale/SmfMDNSStates.html
+file path=usr/lib/help/auths/locale/SmfManageAudit.html
 file path=usr/lib/help/auths/locale/SmfManageHeader.html
 file path=usr/lib/help/auths/locale/SmfManageHotplug.html
 file path=usr/lib/help/auths/locale/SmfManageZFSSnap.html
@@ -174,6 +173,7 @@
 file path=usr/lib/help/auths/locale/SmfSshStates.html
 file path=usr/lib/help/auths/locale/SmfSyslogStates.html
 file path=usr/lib/help/auths/locale/SmfVRRPStates.html
+file path=usr/lib/help/auths/locale/SmfValueAudit.html
 file path=usr/lib/help/auths/locale/SmfValueCoreadm.html
 file path=usr/lib/help/auths/locale/SmfValueExAcctFlow.html
 file path=usr/lib/help/auths/locale/SmfValueExAcctNet.html
@@ -218,6 +218,7 @@
 file path=usr/lib/help/auths/locale/ZoneManage.html
 file path=usr/lib/help/profiles/locale/RtAcctadm.html
 file path=usr/lib/help/profiles/locale/RtAll.html
+file path=usr/lib/help/profiles/locale/RtAuditCfg.html
 file path=usr/lib/help/profiles/locale/RtAuditCtrl.html
 file path=usr/lib/help/profiles/locale/RtAuditReview.html
 file path=usr/lib/help/profiles/locale/RtCPUPowerManagement.html
--- a/usr/src/uts/common/c2/audit.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/c2/audit.h	Tue Jul 27 14:38:47 2010 +0200
@@ -230,12 +230,12 @@
 #define	BSM_AUDITDOOR		37
 
 /*
- * Auditctl(2) commands
+ * auditon(2) commands
  */
 #define	A_GETPOLICY	2	/* get audit policy */
 #define	A_SETPOLICY	3	/* set audit policy */
-#define	A_GETKMASK	4	/* get kernel event preselection mask */
-#define	A_SETKMASK	5	/* set kernel event preselection mask */
+#define	A_GETKMASK	4	/* get non-attributable event audit mask */
+#define	A_SETKMASK	5	/* set non-attributable event audit mask */
 #define	A_GETQCTRL	6	/* get kernel audit queue ctrl parameters */
 #define	A_SETQCTRL	7	/* set kernel audit queue ctrl parameters */
 #define	A_GETCWD	8	/* get process current working directory */
@@ -253,6 +253,8 @@
 #define	A_GETPINFO_ADDR	28	/* get audit info for an arbitrary pid */
 #define	A_GETKAUDIT	29	/* get kernel audit characteristics */
 #define	A_SETKAUDIT	30	/* set kernel audit characteristics */
+#define	A_GETAMASK	31	/* set user default audit event mask */
+#define	A_SETAMASK	32	/* get user default audit event mask */
 
 /*
  * Audit Policy parameters (32 bits)
@@ -337,6 +339,15 @@
 
 typedef struct auditinfo auditinfo_t;
 
+struct k_auditinfo_addr {
+	au_id_t		ai_auid;
+	au_mask_t	ai_amask;	/* user default preselection mask */
+	au_mask_t	ai_namask;	/* non-attributable mask */
+	au_tid_addr_t	ai_termid;
+	au_asid_t	ai_asid;
+};
+typedef struct k_auditinfo_addr k_auditinfo_addr_t;
+
 struct auditinfo_addr {
 	au_id_t		ai_auid;
 	au_mask_t	ai_mask;
--- a/usr/src/uts/common/c2/audit_event.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/c2/audit_event.c	Tue Jul 27 14:38:47 2010 +0200
@@ -2990,6 +2990,12 @@
 		case A_SETPOLICY:
 			e = AUE_AUDITON_SPOLICY;
 			break;
+		case A_GETAMASK:
+			e = AUE_AUDITON_GETAMASK;
+			break;
+		case A_SETAMASK:
+			e = AUE_AUDITON_SETAMASK;
+			break;
 		case A_GETKMASK:
 			e = AUE_AUDITON_GETKMASK;
 			break;
@@ -3138,6 +3144,14 @@
 		au_uwrite(au_to_arg32((char)1, "asid",
 		    (uint32_t)STRUCT_FGET(ainfo_addr, ai_asid)));
 		break;
+	case AUE_AUDITON_SETAMASK:
+		if (copyin((caddr_t)a2, &mask, sizeof (au_mask_t)))
+				return;
+		au_uwrite(au_to_arg32(
+		    2, "setamask:as_success", (uint32_t)mask.as_success));
+		au_uwrite(au_to_arg32(
+		    2, "setamask:as_failure", (uint32_t)mask.as_failure));
+		break;
 	case AUE_AUDITON_SETKMASK:
 		if (copyin((caddr_t)a2, &mask, sizeof (au_mask_t)))
 				return;
@@ -3229,6 +3243,7 @@
 	case AUE_AUDIT:
 	case AUE_AUDITON_GPOLICY:
 	case AUE_AUDITON_GQCTRL:
+	case AUE_AUDITON_GETAMASK:
 	case AUE_AUDITON_GETKMASK:
 	case AUE_AUDITON_GETCWD:
 	case AUE_AUDITON_GETCAR:
--- a/usr/src/uts/common/c2/audit_io.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/c2/audit_io.c	Tue Jul 27 14:38:47 2010 +0200
@@ -808,9 +808,9 @@
 	estate = kctx->auk_ets[event];
 
 	if (sorf & AUM_SUCC)
-		success = kctx->auk_info.ai_mask.as_success & estate;
+		success = kctx->auk_info.ai_namask.as_success & estate;
 	if (sorf & AUM_FAIL)
-		failure = kctx->auk_info.ai_mask.as_failure & estate;
+		failure = kctx->auk_info.ai_namask.as_failure & estate;
 
 	if ((success | failure) == NULL)
 		return (1);
--- a/usr/src/uts/common/c2/audit_kernel.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/c2/audit_kernel.h	Tue Jul 27 14:38:47 2010 +0200
@@ -305,7 +305,7 @@
 
 	au_stat_t		auk_statistics;
 
-	struct auditinfo_addr	auk_info;
+	k_auditinfo_addr_t	auk_info;
 	kmutex_t		auk_eagain_mutex; /* door call retry */
 	kcondvar_t		auk_eagain_cv;
 
--- a/usr/src/uts/common/c2/audit_kevents.h	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/c2/audit_kevents.h	Tue Jul 27 14:38:47 2010 +0200
@@ -345,12 +345,14 @@
 #define	AUE_SETSID		307	/* =pm setsid(2) */
 #define	AUE_SETPGID		308	/* =pm setpgid(2) */
 #define	AUE_FACCESSAT		309	/* =no obsolete */
+#define	AUE_AUDITON_GETAMASK	310	/* =aa */
+#define	AUE_AUDITON_SETAMASK	311	/* =as */
 
 
 
 /* NOTE: update MAX_KEVENTS below if events are added. */
 
-#define	MAX_KEVENTS		309
+#define	MAX_KEVENTS		311
 
 
 #ifdef __cplusplus
--- a/usr/src/uts/common/syscall/auditsys.c	Tue Jul 27 16:58:46 2010 +0800
+++ b/usr/src/uts/common/syscall/auditsys.c	Tue Jul 27 14:38:47 2010 +0200
@@ -488,13 +488,44 @@
 }
 
 static int
+getamask(caddr_t data)
+{
+	au_kcontext_t	*kctx;
+
+	kctx = GET_KCTX_PZ;
+
+	if (copyout(&kctx->auk_info.ai_amask, data, sizeof (au_mask_t)))
+		return (EFAULT);
+
+	return (0);
+}
+
+static int
+setamask(caddr_t data)
+{
+	au_mask_t	mask;
+	au_kcontext_t	*kctx;
+
+	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
+		return (EINVAL);
+
+	kctx = GET_KCTX_NGZ;
+
+	if (copyin(data, &mask, sizeof (au_mask_t)))
+		return (EFAULT);
+
+	kctx->auk_info.ai_amask = mask;
+	return (0);
+}
+
+static int
 getkmask(caddr_t data)
 {
 	au_kcontext_t	*kctx;
 
 	kctx = GET_KCTX_PZ;
 
-	if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
+	if (copyout(&kctx->auk_info.ai_namask, data, sizeof (au_mask_t)))
 		return (EFAULT);
 	return (0);
 }
@@ -513,7 +544,7 @@
 	if (copyin(data, &mask, sizeof (au_mask_t)))
 		return (EFAULT);
 
-	kctx->auk_info.ai_mask = mask;
+	kctx->auk_info.ai_namask = mask;
 	return (0);
 }
 
@@ -531,7 +562,7 @@
 		return (EOVERFLOW);
 
 	STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
-	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
+	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_namask);
 #ifdef _LP64
 	if (model == DATAMODEL_ILP32) {
 		dev32_t dev;
@@ -597,7 +628,7 @@
 
 	/* Set audit mask, termid and session id as specified */
 	kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
-	kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
+	kctx->auk_info.ai_namask = STRUCT_FGET(info, ai_mask);
 #ifdef _LP64
 	/* only convert to 64 bit if coming from a 32 bit binary */
 	if (model == DATAMODEL_ILP32)
@@ -1332,6 +1363,7 @@
 	int result;
 
 	switch (cmd) {
+	case A_GETAMASK:
 	case A_GETCOND:
 	case A_GETCAR:
 	case A_GETCLASS:
@@ -1359,6 +1391,12 @@
 	case A_SETPOLICY:
 		result = setpolicy(data);
 		break;
+	case A_GETAMASK:
+		result = getamask(data);
+		break;
+	case A_SETAMASK:
+		result = setamask(data);
+		break;
 	case A_GETKMASK:
 		result = getkmask(data);
 		break;