summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbsm
diff options
context:
space:
mode:
authorJan Friedel <Jan.Friedel@Sun.COM>2010-07-27 14:38:47 +0200
committerJan Friedel <Jan.Friedel@Sun.COM>2010-07-27 14:38:47 +0200
commitf89940742f5d14dde79b69b98a414dd7b7f585c7 (patch)
tree4ee3607a7fa5f68806f2e15326b561943bfdc420 /usr/src/lib/libbsm
parent7a0c1e298cab158fe4113f2e75e46140eb4825e9 (diff)
downloadillumos-joyent-f89940742f5d14dde79b69b98a414dd7b7f585c7.tar.gz
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 --HG-- rename : usr/src/cmd/auditconfig/auditconfig_impl.h => usr/src/lib/libbsm/common/audit_policy.h rename : usr/src/cmd/auditconfig/audit_scf.c => usr/src/lib/libbsm/common/audit_scf.c rename : usr/src/cmd/auditconfig/audit_scf.h => usr/src/lib/libbsm/common/audit_scf.h
Diffstat (limited to 'usr/src/lib/libbsm')
-rw-r--r--usr/src/lib/libbsm/Makefile4
-rw-r--r--usr/src/lib/libbsm/Makefile.com8
-rw-r--r--usr/src/lib/libbsm/audit_control.txt30
-rw-r--r--usr/src/lib/libbsm/audit_event.txt2
-rw-r--r--usr/src/lib/libbsm/common/adt.c49
-rw-r--r--usr/src/lib/libbsm/common/au_usermask.c12
-rw-r--r--usr/src/lib/libbsm/common/audit_ftpd.c62
-rw-r--r--usr/src/lib/libbsm/common/audit_plugin.c26
-rw-r--r--usr/src/lib/libbsm/common/audit_policy.h86
-rw-r--r--usr/src/lib/libbsm/common/audit_rexd.c26
-rw-r--r--usr/src/lib/libbsm/common/audit_rexecd.c26
-rw-r--r--usr/src/lib/libbsm/common/audit_rshd.c33
-rw-r--r--usr/src/lib/libbsm/common/audit_scf.c1286
-rw-r--r--usr/src/lib/libbsm/common/audit_scf.h174
-rw-r--r--usr/src/lib/libbsm/common/getacinfo.c445
-rw-r--r--usr/src/lib/libbsm/common/getacval.c511
-rw-r--r--usr/src/lib/libbsm/common/getfaudflgs.c62
-rw-r--r--usr/src/lib/libbsm/common/libbsm.h34
-rw-r--r--usr/src/lib/libbsm/common/llib-lbsm4
-rw-r--r--usr/src/lib/libbsm/common/mapfile-vers37
20 files changed, 1700 insertions, 1217 deletions
diff --git a/usr/src/lib/libbsm/Makefile b/usr/src/lib/libbsm/Makefile
index 9b522bff9e..514358a52f 100644
--- a/usr/src/lib/libbsm/Makefile
+++ b/usr/src/lib/libbsm/Makefile
@@ -45,7 +45,7 @@ COMMONDIR = common
# 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 @@ clean clobber delete: $(SUBDIRS)
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
diff --git a/usr/src/lib/libbsm/Makefile.com b/usr/src/lib/libbsm/Makefile.com
index 857b565826..5d1e207ff5 100644
--- a/usr/src/lib/libbsm/Makefile.com
+++ b/usr/src/lib/libbsm/Makefile.com
@@ -50,12 +50,11 @@ OBJECTS= adr.o \
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 @@ ROOTLINT= $(LINTSRC:%=$(ROOTLINTDIR)/%)
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
#
diff --git a/usr/src/lib/libbsm/audit_control.txt b/usr/src/lib/libbsm/audit_control.txt
deleted file mode 100644
index f10a043ea5..0000000000
--- a/usr/src/lib/libbsm/audit_control.txt
+++ /dev/null
@@ -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
diff --git a/usr/src/lib/libbsm/audit_event.txt b/usr/src/lib/libbsm/audit_event.txt
index 4317d3cb78..123af31251 100644
--- a/usr/src/lib/libbsm/audit_event.txt
+++ b/usr/src/lib/libbsm/audit_event.txt
@@ -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
diff --git a/usr/src/lib/libbsm/common/adt.c b/usr/src/lib/libbsm/common/adt.c
index 76b3d23357..653628aac9 100644
--- a/usr/src/lib/libbsm/common/adt.c
+++ b/usr/src/lib/libbsm/common/adt.c
@@ -160,62 +160,59 @@ adt_audit_enabled(void)
* 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);
}
diff --git a/usr/src/lib/libbsm/common/au_usermask.c b/usr/src/lib/libbsm/common/au_usermask.c
index a693c1f4cb..1c2fc909aa 100644
--- a/usr/src/lib/libbsm/common/au_usermask.c
+++ b/usr/src/lib/libbsm/common/au_usermask.c
@@ -67,7 +67,6 @@ int
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 @@ au_user_mask(char *user, au_mask_t *mask)
}
/*
- * 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.
diff --git a/usr/src/lib/libbsm/common/audit_ftpd.c b/usr/src/lib/libbsm/common/audit_ftpd.c
index 0b53043d1e..6c46336ff1 100644
--- a/usr/src/lib/libbsm/common/audit_ftpd.c
+++ b/usr/src/lib/libbsm/common/audit_ftpd.c
@@ -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 @@ audit_ftpd_bad_pw(char *uname)
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 @@ audit_ftpd_unknown(char *uname)
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 @@ audit_ftpd_excluded(char *uname)
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 @@ audit_ftpd_no_anon(void)
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 @@ audit_ftpd_failure(char *uname)
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 @@ audit_ftpd_success(char *uname)
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 @@ generate_record(
/* 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 @@ selected(
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 @@ audit_ftpd_logout(void)
/* 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 @@ audit_ftpd_logout(void)
/* 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());
diff --git a/usr/src/lib/libbsm/common/audit_plugin.c b/usr/src/lib/libbsm/common/audit_plugin.c
index 76c69f01e1..a3bec300c3 100644
--- a/usr/src/lib/libbsm/common/audit_plugin.c
+++ b/usr/src/lib/libbsm/common/audit_plugin.c
@@ -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 @@ __audit_dowarn(char *option, char *text, int count)
(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 @@ __audit_dowarn(char *option, char *text, int count)
* (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 @@ __audit_dowarn2(char *option, char *name, char *error, char *text, int count)
(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 @@ __audit_dowarn2(char *option, char *name, char *error, char *text, int count)
/*
* (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);
diff --git a/usr/src/lib/libbsm/common/audit_policy.h b/usr/src/lib/libbsm/common/audit_policy.h
new file mode 100644
index 0000000000..f302f1e2ac
--- /dev/null
+++ b/usr/src/lib/libbsm/common/audit_policy.h
@@ -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 */
diff --git a/usr/src/lib/libbsm/common/audit_rexd.c b/usr/src/lib/libbsm/common/audit_rexd.c
index 38aead7526..17b6ba7c6e 100644
--- a/usr/src/lib/libbsm/common/audit_rexd.c
+++ b/usr/src/lib/libbsm/common/audit_rexd.c
@@ -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 @@ char *user;
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
diff --git a/usr/src/lib/libbsm/common/audit_rexecd.c b/usr/src/lib/libbsm/common/audit_rexecd.c
index fa588318d4..38246e232c 100644
--- a/usr/src/lib/libbsm/common/audit_rexecd.c
+++ b/usr/src/lib/libbsm/common/audit_rexecd.c
@@ -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 @@ char *user;
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
diff --git a/usr/src/lib/libbsm/common/audit_rshd.c b/usr/src/lib/libbsm/common/audit_rshd.c
index 24de2fd281..7ef782d05d 100644
--- a/usr/src/lib/libbsm/common/audit_rshd.c
+++ b/usr/src/lib/libbsm/common/audit_rshd.c
@@ -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 @@ generate_record(char *remuser, /* username at machine requesting service */
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 @@ generate_record(char *remuser, /* username at machine requesting service */
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 @@ generate_record(char *remuser, /* username at machine requesting service */
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
diff --git a/usr/src/lib/libbsm/common/audit_scf.c b/usr/src/lib/libbsm/common/audit_scf.c
new file mode 100644
index 0000000000..fa990fc669
--- /dev/null
+++ b/usr/src/lib/libbsm/common/audit_scf.c
@@ -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);
+}
diff --git a/usr/src/lib/libbsm/common/audit_scf.h b/usr/src/lib/libbsm/common/audit_scf.h
new file mode 100644
index 0000000000..09b826e97b
--- /dev/null
+++ b/usr/src/lib/libbsm/common/audit_scf.h
@@ -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 */
diff --git a/usr/src/lib/libbsm/common/getacinfo.c b/usr/src/lib/libbsm/common/getacinfo.c
deleted file mode 100644
index 4766b873cb..0000000000
--- a/usr/src/lib/libbsm/common/getacinfo.c
+++ /dev/null
@@ -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);
-}
diff --git a/usr/src/lib/libbsm/common/getacval.c b/usr/src/lib/libbsm/common/getacval.c
deleted file mode 100644
index 993b08257f..0000000000
--- a/usr/src/lib/libbsm/common/getacval.c
+++ /dev/null
@@ -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);
-}
diff --git a/usr/src/lib/libbsm/common/getfaudflgs.c b/usr/src/lib/libbsm/common/getfaudflgs.c
index 93668aae66..e0b3f490fa 100644
--- a/usr/src/lib/libbsm/common/getfaudflgs.c
+++ b/usr/src/lib/libbsm/common/getfaudflgs.c
@@ -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);
- }
- return (retstat);
+ lastmasks->as_success &= ~(usrdmasks->as_success);
+ lastmasks->as_failure &= ~(usrdmasks->as_failure);
+
+ return (0);
}
diff --git a/usr/src/lib/libbsm/common/libbsm.h b/usr/src/lib/libbsm/common/libbsm.h
index b3f63e28b4..23cef801f7 100644
--- a/usr/src/lib/libbsm/common/libbsm.h
+++ b/usr/src/lib/libbsm/common/libbsm.h
@@ -85,11 +85,6 @@ typedef struct au_user_str_s {
} 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(char *);
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 @@ extern int setauid(au_id_t *);
/* 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"
diff --git a/usr/src/lib/libbsm/common/llib-lbsm b/usr/src/lib/libbsm/common/llib-lbsm
index 52a923f4ec..ece270a6ed 100644
--- a/usr/src/lib/libbsm/common/llib-lbsm
+++ b/usr/src/lib/libbsm/common/llib-lbsm
@@ -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>
diff --git a/usr/src/lib/libbsm/common/mapfile-vers b/usr/src/lib/libbsm/common/mapfile-vers
index 671dd66d10..33d11ad71c 100644
--- a/usr/src/lib/libbsm/common/mapfile-vers
+++ b/usr/src/lib/libbsm/common/mapfile-vers
@@ -94,13 +94,8 @@ SYMBOL_VERSION SUNW_0.7 {
au_to_text;
au_user_mask;
au_write;
- endac;
endauclass;
endauevent;
- getacdir;
- getacflg;
- getacmin;
- getacna;
getauclassent;
getauclassnam;
getaudit;
@@ -112,7 +107,6 @@ SYMBOL_VERSION SUNW_0.7 {
getauevnum;
getauid;
getfauditflags;
- setac;
setauclass;
setaudit;
setauevent;
@@ -296,18 +290,31 @@ SYMBOL_VERSION SUNWprivate_1.1 {
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 @@ SYMBOL_VERSION SUNWprivate_1.1 {
getdmapfield;
getdmapnam;
getdmaptype;
+ get_policy;
__logpost;
- _openac;
- _rewindac;
+ plugin_avail_scf;
+ plugin_kva_ll_free;
+ prt_error_va;
setdadefent;
setdaent;
setdafile;