summaryrefslogtreecommitdiff
path: root/usr/src/cmd/auditconfig
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/auditconfig
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/auditconfig')
-rw-r--r--usr/src/cmd/auditconfig/Makefile49
-rw-r--r--usr/src/cmd/auditconfig/auditconfig.c2852
2 files changed, 2901 insertions, 0 deletions
diff --git a/usr/src/cmd/auditconfig/Makefile b/usr/src/cmd/auditconfig/Makefile
new file mode 100644
index 0000000000..fed008f10d
--- /dev/null
+++ b/usr/src/cmd/auditconfig/Makefile
@@ -0,0 +1,49 @@
+#
+# 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"
+#
+# Copyright (c) 1992 by Sun Microsystems, Inc.
+#
+# Makefile for auditconfig
+
+PROG= auditconfig
+TEXT_DOMAIN=SUNW_OST_OSCMD
+
+include ../Makefile.cmd
+
+LDLIBS += -lnsl -lbsm
+
+OBJS = auditconfig.o
+SRCS = auditconfig.c
+
+.KEEP_STATE:
+
+install: all $(ROOTUSRSBINPROG)
+all: $(PROG)
+
+clean:
+ rm -f $(PROG) $(PROG).po
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/auditconfig/auditconfig.c b/usr/src/cmd/auditconfig/auditconfig.c
new file mode 100644
index 0000000000..322cf2687b
--- /dev/null
+++ b/usr/src/cmd/auditconfig/auditconfig.c
@@ -0,0 +1,2852 @@
+/*
+ * 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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * auditconfig - set and display audit parameters
+ */
+
+#include <locale.h>
+#include <sys/types.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <nlist.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/mkdev.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <libintl.h>
+#include <zone.h>
+
+#include <bsm/audit.h>
+#include <bsm/audit_record.h>
+#include <bsm/libbsm.h>
+
+#if !defined(TEXT_DOMAIN)
+#define TEXT_DOMAIN "SUNW_OST_OSCMD"
+#endif
+
+#define AC_ARG_AUDIT 0
+#define AC_ARG_CHKCONF 1
+#define AC_ARG_CONF 2
+#define AC_ARG_GETASID 3 /* same as GETSID */
+#define AC_ARG_GETAUDIT 4
+#define AC_ARG_GETAUID 5
+#define AC_ARG_GETCAR 6
+#define AC_ARG_GETCLASS 7 /* same as GETESTATE */
+#define AC_ARG_GETCOND 8
+#define AC_ARG_GETCWD 9
+#define AC_ARG_GETESTATE 10
+#define AC_ARG_GETKERNSTATE 11
+#define AC_ARG_GETKMASK 12 /* same as GETKERNSTATE */
+#define AC_ARG_GETPINFO 13
+#define AC_ARG_GETPOLICY 14
+#define AC_ARG_GETQBUFSZ 15
+#define AC_ARG_GETQCTRL 16
+#define AC_ARG_GETQDELAY 17
+#define AC_ARG_GETQHIWATER 18
+#define AC_ARG_GETQLOWATER 19
+#define AC_ARG_GETSID 20
+#define AC_ARG_GETSTAT 21
+#define AC_ARG_GETTERMID 22
+#define AC_ARG_GETUSERAUDIT 23 /* only CMW syscall w/out */
+#define AC_ARG_LSEVENT 24
+#define AC_ARG_LSPOLICY 25
+#define AC_ARG_SETASID 26
+#define AC_ARG_SETAUDIT 27
+#define AC_ARG_SETAUID 28
+#define AC_ARG_SETCLASS 29 /* same as SETESTATE */
+/* AC_ARG_SETCOND 30 */
+#define AC_ARG_SETESTATE 31
+#define AC_ARG_SETKERNSTATE 32
+#define AC_ARG_SETKMASK 33 /* same as SETKERNSTATE */
+#define AC_ARG_SETPMASK 34
+#define AC_ARG_SETSMASK 35
+#define AC_ARG_SETSTAT 36
+#define AC_ARG_SETPOLICY 37
+#define AC_ARG_SETQBUFSZ 38
+#define AC_ARG_SETQCTRL 39
+#define AC_ARG_SETQDELAY 40
+#define AC_ARG_SETQHIWATER 41
+#define AC_ARG_SETQLOWATER 42
+#define AC_ARG_SETTERMID 43
+#define AC_ARG_SETUMASK 44
+#define AC_ARG_SETUSERAUDIT 45
+#define AC_ARG_GETFSIZE 46
+#define AC_ARG_SETFSIZE 47
+#define AC_ARG_GETKAUDIT 48
+#define AC_ARG_SETKAUDIT 49
+#define AC_ARG_ACONF 50
+#define AC_ARG_CHKACONF 51
+
+#define AC_KERN_EVENT 0
+#define AC_USER_EVENT 1
+
+#define NONE(s) (!strlen(s) ? gettext("none") : s)
+
+#define ALL_POLICIES (AUDIT_AHLT|\
+ AUDIT_ARGE|\
+ AUDIT_ARGV|\
+ AUDIT_CNT|\
+ AUDIT_GROUP|\
+ AUDIT_PASSWD|\
+ AUDIT_WINDATA|\
+ AUDIT_SEQ|\
+ AUDIT_TRAIL|\
+ AUDIT_PATH|\
+ AUDIT_PUBLIC|\
+ AUDIT_ZONENAME|\
+ AUDIT_PERZONE)
+
+#define NO_POLICIES (0)
+
+#define ONEK 1024
+
+/* This should be defined in <string.h>, but it is not */
+extern int strncasecmp();
+
+/*
+ * remove this after the audit.h is fixed
+ */
+
+struct arg_entry {
+ char *arg_str;
+ char *arg_opts;
+ int auditconfig_cmd;
+};
+
+struct policy_entry {
+ char *policy_str;
+ uint_t policy_mask;
+ char *policy_desc;
+};
+
+static struct arg_entry arg_table[] = {
+ { "-aconf", "", AC_ARG_ACONF},
+ { "-audit", "event sorf retval string", AC_ARG_AUDIT},
+ { "-chkaconf", "", AC_ARG_CHKACONF},
+ { "-chkconf", "", AC_ARG_CHKCONF},
+ { "-conf", "", AC_ARG_CONF},
+ { "-getasid", "", AC_ARG_GETASID},
+ { "-getaudit", "", AC_ARG_GETAUDIT},
+ { "-getauid", "", AC_ARG_GETAUID},
+ { "-getcar", "", AC_ARG_GETCAR},
+ { "-getclass", "", AC_ARG_GETCLASS},
+ { "-getcond", "", AC_ARG_GETCOND},
+ { "-getcwd", "", AC_ARG_GETCWD},
+ { "-getestate", "event", AC_ARG_GETESTATE},
+ { "-getfsize", "", AC_ARG_GETFSIZE},
+ { "-getkaudit", "", AC_ARG_GETKAUDIT},
+ { "-getkernstate", "", AC_ARG_GETKERNSTATE},
+ { "-getkmask", "", AC_ARG_GETKMASK},
+ { "-getpinfo", "", AC_ARG_GETPINFO},
+ { "-getpolicy", "", AC_ARG_GETPOLICY},
+ { "-getqbufsz", "", AC_ARG_GETQBUFSZ},
+ { "-getqctrl", "", AC_ARG_GETQCTRL},
+ { "-getqdelay", "", AC_ARG_GETQDELAY},
+ { "-getqhiwater", "", AC_ARG_GETQHIWATER},
+ { "-getqlowater", "", AC_ARG_GETQLOWATER},
+ { "-getsid", "", AC_ARG_GETSID},
+ { "-getstat", "", AC_ARG_GETSTAT},
+ { "-gettermid", "", AC_ARG_GETTERMID},
+ { "-gettid", "", AC_ARG_GETTERMID},
+ { "-getuseraudit", "user", AC_ARG_GETUSERAUDIT},
+ { "-lsevent", "", AC_ARG_LSEVENT},
+ { "-lspolicy", "", AC_ARG_LSPOLICY},
+ { "-setasid", "asid [cmd]", AC_ARG_SETASID},
+ { "-setaudit", "auid audit_flags termid sid [cmd]",
+ AC_ARG_SETAUDIT},
+ { "-setauid", "auid [cmd]", AC_ARG_SETAUID},
+ { "-setclass", "event audit_flags", AC_ARG_SETCLASS},
+ { "-setestate", "event audit_flags", AC_ARG_SETESTATE},
+ { "-setfsize", "filesize", AC_ARG_SETFSIZE},
+ { "-setkaudit", "type IP_address", AC_ARG_SETKAUDIT},
+ { "-setkernstate", "audit_flags", AC_ARG_SETKERNSTATE},
+ { "-setkmask", "audit_flags", AC_ARG_SETKMASK},
+ { "-setpmask", "pid audit_flags [cmd]", AC_ARG_SETPMASK},
+ { "-setpolicy", "policy_flags", AC_ARG_SETPOLICY},
+ { "-setqbufsz", "bufsz", AC_ARG_SETQBUFSZ},
+ { "-setqctrl", "hiwater lowater bufsz delay", AC_ARG_SETQCTRL},
+ { "-setqdelay", "delay", AC_ARG_SETQDELAY},
+ { "-setqhiwater", "hiwater", AC_ARG_SETQHIWATER},
+ { "-setqlowater", "lowater", AC_ARG_SETQLOWATER},
+ { "-setsmask", "asid audit_flags", AC_ARG_SETSMASK},
+ { "-setstat", "", AC_ARG_SETSTAT},
+ { "-settid", "tid [cmd]", AC_ARG_SETTERMID},
+ { "-setumask", "user audit_flags", AC_ARG_SETUMASK},
+ { "-setuseraudit", "user audit_flags", AC_ARG_SETUSERAUDIT}
+};
+
+#define ARG_TBL_SZ (sizeof (arg_table) / sizeof (struct arg_entry))
+
+static struct arg_entry arg2_table[] = {
+ { "-chkconf", "", AC_ARG_CHKCONF},
+ { "-conf", "", AC_ARG_CONF},
+ { "-getcond", "", AC_ARG_GETCOND},
+ { "-getclass", "event", AC_ARG_GETCLASS},
+ { "-setclass", "event audit_flags", AC_ARG_SETCLASS},
+ { "-lsevent", "", AC_ARG_LSEVENT},
+ { "-lspolicy", "", AC_ARG_LSPOLICY},
+ { "-getpolicy", "", AC_ARG_GETPOLICY},
+ { "-setpolicy", "policy_flags", AC_ARG_SETPOLICY},
+ { "-getstat", "", AC_ARG_GETSTAT},
+ { "-getpinfo", "pid", AC_ARG_GETPINFO},
+ { "-setpmask", "pid audit_flags", AC_ARG_SETPMASK},
+ { "-setsmask", "asid audit_flags", AC_ARG_SETSMASK},
+ { "-setumask", "user audit_flags", AC_ARG_SETUMASK},
+ { "-getfsize", "", AC_ARG_GETFSIZE},
+ { "-setfsize", "filesize", AC_ARG_SETFSIZE}
+ };
+
+#define ARG2_TBL_SZ (sizeof (arg2_table) / sizeof (struct arg_entry))
+
+static struct policy_entry policy_table[] = {
+ {"ahlt", AUDIT_AHLT, "halt machine if it can not record an "
+ "async event"},
+ {"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"},
+ {"seq", AUDIT_SEQ, "include a sequence number in audit recs"},
+ {"trail", AUDIT_TRAIL, "include trailer token in audit recs"},
+ {"path", AUDIT_PATH, "allow multiple paths per event"},
+ {"public", AUDIT_PUBLIC, "audit public files"},
+ {"zonename", AUDIT_ZONENAME, "generate zonename token"},
+ {"perzone", AUDIT_PERZONE, "use a separate queue and auditd per "
+ "zone"},
+ {"all", ALL_POLICIES, "all policies"},
+ {"none", NO_POLICIES, "no policies"}
+ };
+
+#define POLICY_TBL_SZ (sizeof (policy_table) / sizeof (struct policy_entry))
+
+static char *progname;
+
+static au_event_ent_t *egetauevnam();
+static au_event_ent_t *egetauevnum();
+static char *strtolower();
+static int arg_ent_compare();
+static int cond2str();
+static int policy2str();
+static int str2type();
+static int str2policy();
+static int str2ipaddr();
+static int strisflags();
+static int strisipaddr();
+static int strisnum();
+static struct arg_entry *get_arg_ent();
+static struct policy_entry *get_policy_ent();
+static uid_t get_user_id();
+static void chk_event_num();
+static void chk_event_str();
+static void chk_retval();
+static void chk_sorf();
+static void chk_tid();
+static void do_aconf();
+static void do_args();
+static void do_audit();
+static void do_chkaconf();
+static void do_chkconf();
+static void do_conf();
+static void do_getasid();
+static void do_getaudit();
+static void do_getkaudit();
+static void do_setkaudit();
+static void do_getauid();
+static void do_getcar();
+static void do_getclass();
+static void do_getcond();
+static void do_getcwd();
+static void do_getkmask();
+static void do_getpinfo();
+static void do_getpolicy();
+static void do_getqbufsz();
+static void do_getqctrl();
+static void do_getqdelay();
+static void do_getqhiwater();
+static void do_getqlowater();
+static void do_getstat();
+static void do_gettermid();
+static void do_getuseraudit();
+static void do_lsevent();
+static void do_lspolicy();
+static void do_setasid();
+static void do_setaudit();
+static void do_setauid();
+static void do_setclass();
+static void do_setkmask();
+static void do_setpmask();
+static void do_setsmask();
+static void do_setumask();
+static void do_setpolicy();
+static void do_setqbufsz();
+static void do_setqctrl();
+static void do_setqdelay();
+static void do_setqhiwater();
+static void do_setqlowater();
+static void do_setstat();
+static void do_settid();
+static void do_setuseraudit();
+static void do_getfsize();
+static void do_setfsize();
+static void str2mask();
+static void str2tid();
+static void strsplit();
+
+static void eauditon();
+static void egetaudit();
+static void egetkaudit();
+static void esetkaudit();
+static void egetauditflagsbin();
+static void egetauid();
+static void esetaudit();
+static void esetauid();
+static void execit();
+static void exit_error(char *, ...);
+static void exit_usage();
+static void parse_args();
+static void print_asid();
+static void print_auid();
+static void print_mask();
+static void print_mask1();
+static void print_stats();
+static void print_tid_ex();
+
+extern char *sys_errlist[];
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ progname = "auditconfig";
+
+ (void) setlocale(LC_ALL, "");
+ (void) textdomain(TEXT_DOMAIN);
+
+ if (argc == 1) {
+ exit_usage(0);
+ exit(0);
+ }
+
+ if (argc == 2 &&
+ (argv[1][0] == '?' ||
+ strcmp(argv[1], "-h") == 0 ||
+ strcmp(argv[1], "-?") == 0))
+ exit_usage(0);
+
+ parse_args(argv);
+
+ do_args(argv);
+
+ return (0);
+}
+
+/*
+ * parse_args()
+ * Desc: Checks command line argument syntax.
+ * Inputs: Command line argv;
+ * Returns: If a syntax error is detected, a usage message is printed
+ * and exit() is called. If a syntax error is not detected,
+ * parse_args() returns without a value.
+ */
+static void
+parse_args(char **argv)
+{
+ struct arg_entry *ae;
+
+ au_mask_t pmask;
+ au_mask_t smask;
+ au_mask_t umask;
+ uint_t type;
+ uint_t addr[4];
+
+ for (++argv; *argv; argv++) {
+ if ((ae = get_arg_ent(*argv)) == (struct arg_entry *)0) {
+ exit_usage(1);
+ }
+
+ switch (ae->auditconfig_cmd) {
+
+ case AC_ARG_AUDIT:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (strisnum(*argv)) {
+ chk_event_num(AC_USER_EVENT,
+ (au_event_t)atol(*argv));
+ } else
+ chk_event_str(AC_USER_EVENT, *argv);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ chk_sorf(*argv);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ chk_retval(*argv);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ break;
+
+ case AC_ARG_CHKCONF:
+ break;
+
+ case AC_ARG_CONF:
+ break;
+
+ case AC_ARG_ACONF:
+ break;
+
+ case AC_ARG_CHKACONF:
+ break;
+
+ case AC_ARG_GETASID:
+ case AC_ARG_GETSID:
+ break;
+
+ case AC_ARG_GETAUID:
+ break;
+
+ case AC_ARG_GETAUDIT:
+ break;
+
+ case AC_ARG_GETKAUDIT:
+ break;
+
+ case AC_ARG_GETCLASS:
+ case AC_ARG_GETESTATE:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (strisnum(*argv))
+ chk_event_num(AC_KERN_EVENT,
+ (au_event_t)atol(*argv));
+ else
+ chk_event_str(AC_KERN_EVENT, *argv);
+ break;
+
+ case AC_ARG_GETCAR:
+ break;
+
+ case AC_ARG_GETCOND:
+ break;
+
+ case AC_ARG_GETCWD:
+ break;
+
+ case AC_ARG_GETKERNSTATE:
+ case AC_ARG_GETKMASK:
+ break;
+
+ case AC_ARG_GETPOLICY:
+ break;
+
+ case AC_ARG_GETQBUFSZ:
+ break;
+
+ case AC_ARG_GETQCTRL:
+ break;
+
+ case AC_ARG_GETQDELAY:
+ break;
+
+ case AC_ARG_GETQHIWATER:
+ break;
+
+ case AC_ARG_GETQLOWATER:
+ break;
+
+ case AC_ARG_GETSTAT:
+ break;
+
+ case AC_ARG_GETTERMID:
+ break;
+
+ case AC_ARG_GETUSERAUDIT:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ break;
+
+ case AC_ARG_LSEVENT:
+ break;
+
+ case AC_ARG_LSPOLICY:
+ break;
+
+ case AC_ARG_SETASID:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+
+ while (*argv)
+ ++argv;
+ --argv;
+
+ break;
+
+ case AC_ARG_SETAUID:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+
+ while (*argv)
+ ++argv;
+ --argv;
+
+ break;
+
+ case AC_ARG_SETAUDIT:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+
+ while (*argv)
+ ++argv;
+ --argv;
+
+ break;
+
+ case AC_ARG_SETKAUDIT:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (str2type (*argv, &type))
+ exit_error(gettext(
+ "Invalid IP address type specified."));
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+
+ if (str2ipaddr(*argv, addr, type))
+ exit_error(gettext(
+ "Invalid IP address specified."));
+ break;
+
+ case AC_ARG_SETCLASS:
+ case AC_ARG_SETESTATE:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (strisnum(*argv))
+ chk_event_num(AC_KERN_EVENT,
+ (au_event_t)atol(*argv));
+ else
+ chk_event_str(AC_KERN_EVENT, *argv);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ str2mask(*argv, &pmask);
+ break;
+
+ case AC_ARG_SETKERNSTATE:
+ case AC_ARG_SETKMASK:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ str2mask(*argv, &pmask);
+ break;
+
+ case AC_ARG_SETPOLICY:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ break;
+
+ case AC_ARG_SETSTAT:
+ break;
+
+ case AC_ARG_GETPINFO:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ break;
+
+ case AC_ARG_SETPMASK:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ str2mask(*argv, &pmask);
+ break;
+
+ case AC_ARG_SETQBUFSZ:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext("Invalid bufsz specified."));
+ break;
+
+ case AC_ARG_SETQCTRL:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext(
+ "Invalid hiwater specified."));
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext(
+ gettext("Invalid lowater specified.")));
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext("Invalid bufsz specified."));
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext("Invalid delay specified."));
+ break;
+
+ case AC_ARG_SETQDELAY:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext("Invalid delay specified."));
+ break;
+
+ case AC_ARG_SETQHIWATER:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext(
+ "Invalid hiwater specified."));
+ break;
+
+ case AC_ARG_SETQLOWATER:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext(
+ "Invalid lowater specified."));
+ break;
+
+ case AC_ARG_SETTERMID:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ chk_tid(*argv);
+ break;
+
+ case AC_ARG_SETUSERAUDIT:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ break;
+ case AC_ARG_SETSMASK:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ str2mask(*argv, &smask);
+ break;
+
+ case AC_ARG_SETUMASK:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ str2mask(*argv, &umask);
+ break;
+
+ case AC_ARG_GETFSIZE:
+ break;
+
+ case AC_ARG_SETFSIZE:
+ ++argv;
+ if (!*argv)
+ exit_usage(1);
+ if (!strisnum(*argv))
+ exit_error(gettext(
+ "Invalid hiwater specified."));
+ break;
+
+ default:
+ exit_error(gettext("Internal error #1."));
+ break;
+
+
+ }
+ }
+}
+
+
+/*
+ * do_args()
+ * Desc: Do command line arguments in the order in which they appear.
+ */
+static void
+do_args(argv)
+ char **argv;
+{
+ struct arg_entry *ae;
+
+ for (++argv; *argv; argv++) {
+ ae = get_arg_ent(*argv);
+
+ switch (ae->auditconfig_cmd) {
+
+ case AC_ARG_AUDIT:
+ {
+ char sorf;
+ int retval;
+ char *event_name;
+ char *audit_str;
+
+ ++argv;
+ event_name = *argv;
+ ++argv;
+ sorf = (char)atoi(*argv);
+ ++argv;
+ retval = atoi(*argv);
+ ++argv;
+ audit_str = *argv;
+ do_audit(event_name, sorf, retval, audit_str);
+ }
+ break;
+
+ case AC_ARG_CHKCONF:
+ do_chkconf();
+ break;
+
+ case AC_ARG_CONF:
+ do_conf();
+ break;
+
+ case AC_ARG_CHKACONF:
+ do_chkaconf();
+ break;
+
+ case AC_ARG_ACONF:
+ do_aconf();
+ break;
+
+ case AC_ARG_GETASID:
+ case AC_ARG_GETSID:
+ do_getasid();
+ break;
+
+ case AC_ARG_GETAUID:
+ do_getauid();
+ break;
+
+ case AC_ARG_GETAUDIT:
+ do_getaudit();
+ break;
+
+ case AC_ARG_GETKAUDIT:
+ do_getkaudit();
+ break;
+
+ case AC_ARG_GETCLASS:
+ case AC_ARG_GETESTATE:
+ ++argv;
+ do_getclass(*argv);
+ break;
+
+ case AC_ARG_GETCAR:
+ do_getcar();
+ break;
+
+ case AC_ARG_GETCOND:
+ do_getcond();
+ break;
+
+ case AC_ARG_GETCWD:
+ do_getcwd();
+ break;
+
+ case AC_ARG_GETKERNSTATE:
+ case AC_ARG_GETKMASK:
+ do_getkmask();
+ break;
+
+ case AC_ARG_GETPOLICY:
+ do_getpolicy();
+ break;
+
+ case AC_ARG_GETQBUFSZ:
+ do_getqbufsz();
+ break;
+
+ case AC_ARG_GETQCTRL:
+ do_getqctrl();
+ break;
+
+ case AC_ARG_GETQDELAY:
+ do_getqdelay();
+ break;
+
+ case AC_ARG_GETQHIWATER:
+ do_getqhiwater();
+ break;
+
+ case AC_ARG_GETQLOWATER:
+ do_getqlowater();
+ break;
+
+ case AC_ARG_GETSTAT:
+ do_getstat();
+ break;
+
+ case AC_ARG_GETTERMID:
+ do_gettermid();
+ break;
+
+ case AC_ARG_GETUSERAUDIT:
+ ++argv;
+ do_getuseraudit(*argv);
+ break;
+
+ case AC_ARG_LSEVENT:
+ do_lsevent();
+ break;
+
+ case AC_ARG_LSPOLICY:
+ do_lspolicy();
+ break;
+
+ case AC_ARG_SETASID:
+ {
+ char *sid_str;
+
+ ++argv;
+ sid_str = *argv;
+ ++argv;
+ do_setasid(sid_str, argv);
+ }
+ break;
+
+ case AC_ARG_SETAUID:
+ {
+ char *user;
+
+ ++argv;
+ user = *argv;
+ ++argv;
+ do_setauid(user, argv);
+ }
+ break;
+
+ case AC_ARG_SETAUDIT:
+ {
+ char *user_str;
+ char *mask_str;
+ char *tid_str;
+ char *sid_str;
+
+ ++argv;
+ user_str = *argv;
+ ++argv;
+ mask_str = *argv;
+ ++argv;
+ tid_str = *argv;
+ ++argv;
+ sid_str = *argv;
+ ++argv;
+ do_setaudit(user_str, mask_str,
+ tid_str, sid_str, argv);
+ }
+ break;
+
+ case AC_ARG_SETKAUDIT:
+ {
+ char *address_type, *address;
+
+ ++argv; address_type = *argv;
+ ++argv; address = *argv;
+ do_setkaudit(address_type, address);
+ }
+ break;
+
+ case AC_ARG_SETCLASS:
+ case AC_ARG_SETESTATE:
+ {
+ char *event_str, *audit_flags;
+
+ ++argv; event_str = *argv;
+ ++argv; audit_flags = *argv;
+ do_setclass(event_str, audit_flags);
+ }
+ break;
+
+ case AC_ARG_SETKERNSTATE:
+ case AC_ARG_SETKMASK:
+ ++argv;
+ do_setkmask(*argv);
+ break;
+
+ case AC_ARG_SETPOLICY:
+ ++argv;
+ do_setpolicy(*argv);
+ break;
+
+ case AC_ARG_GETPINFO:
+ {
+ char *pid_str;
+
+ ++argv;
+ pid_str = *argv;
+ do_getpinfo(pid_str);
+ }
+ break;
+
+ case AC_ARG_SETPMASK:
+ {
+ char *pid_str;
+ char *audit_flags;
+
+ ++argv;
+ pid_str = *argv;
+ ++argv;
+ audit_flags = *argv;
+ do_setpmask(pid_str, audit_flags);
+ }
+ break;
+
+ case AC_ARG_SETSTAT:
+ do_setstat();
+ break;
+
+ case AC_ARG_SETQBUFSZ:
+ ++argv;
+ do_setqbufsz(*argv);
+ break;
+
+ case AC_ARG_SETQCTRL:
+ {
+ char *hiwater, *lowater, *bufsz, *delay;
+
+ ++argv; hiwater = *argv;
+ ++argv; lowater = *argv;
+ ++argv; bufsz = *argv;
+ ++argv; delay = *argv;
+ do_setqctrl(hiwater, lowater, bufsz, delay);
+ }
+ break;
+ case AC_ARG_SETQDELAY:
+ ++argv;
+ do_setqdelay(*argv);
+ break;
+
+ case AC_ARG_SETQHIWATER:
+ ++argv;
+ do_setqhiwater(*argv);
+ break;
+
+ case AC_ARG_SETQLOWATER:
+ ++argv;
+ do_setqlowater(*argv);
+ break;
+
+ case AC_ARG_SETTERMID:
+ ++argv;
+ do_settid(*argv);
+ break;
+
+ case AC_ARG_SETUSERAUDIT:
+ {
+ char *user;
+ char *aflags;
+
+ ++argv;
+ user = *argv;
+ ++argv;
+ aflags = *argv;
+ do_setuseraudit(user, aflags);
+ }
+ break;
+ case AC_ARG_SETSMASK:
+ {
+ char *asid_str;
+ char *audit_flags;
+
+ ++argv;
+ asid_str = *argv;
+ ++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;
+ ++argv;
+ audit_flags = *argv;
+ do_setumask(auid_str, audit_flags);
+ }
+ break;
+ case AC_ARG_GETFSIZE:
+ do_getfsize();
+ break;
+ case AC_ARG_SETFSIZE:
+ ++argv;
+ do_setfsize(*argv);
+ break;
+
+ default:
+ exit_error(gettext("Internal error #2."));
+ break;
+
+ }
+ }
+
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_chkconf()
+{
+ register au_event_ent_t *evp;
+ au_mask_t pmask;
+ char conf_aflags[256];
+ char run_aflags[256];
+ au_stat_t as;
+ int class;
+ int len;
+ struct au_evclass_map cmap;
+
+ pmask.am_success = pmask.am_failure = 0;
+ eauditon(A_GETSTAT, (caddr_t)&as, 0);
+
+ setauevent();
+ if ((evp = getauevent()) == (au_event_ent_t *)NULL) {
+ (void) exit_error(gettext(
+ "NO AUDIT EVENTS: Could not read %s\n."),
+ AUDITEVENTFILE);
+ }
+
+ setauevent();
+ while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
+ cmap.ec_number = evp->ae_number;
+ len = sizeof (struct au_evclass_map);
+ if (evp->ae_number <= as.as_numevent)
+ if (auditon(A_GETCLASS, (caddr_t)&cmap, len) == -1) {
+ (void) printf("%s(%d):%s",
+ evp->ae_name, evp->ae_number, gettext(
+"UNKNOWN EVENT: Could not get class for event. Configuration may be bad.\n"));
+ } else {
+ class = cmap.ec_class;
+ if (class != evp->ae_class) {
+ conf_aflags[0] = run_aflags[0] = '\0';
+ pmask.am_success = class;
+ pmask.am_failure = class;
+ (void) getauditflagschar(run_aflags,
+ &pmask, 0);
+ pmask.am_success = evp->ae_class;
+ pmask.am_failure = evp->ae_class;
+ (void) getauditflagschar(conf_aflags,
+ &pmask, 0);
+
+ (void) printf(gettext(
+"%s(%d): CLASS MISMATCH: runtime class (%s) != configured class (%s)\n"),
+ evp->ae_name, evp->ae_number,
+ NONE(run_aflags), NONE(conf_aflags));
+ }
+ }
+ }
+ endauevent();
+
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+static void
+do_conf()
+{
+ register au_event_ent_t *evp;
+ register int i;
+ au_evclass_map_t ec;
+ au_stat_t as;
+
+ eauditon(A_GETSTAT, (caddr_t)&as, 0);
+
+ i = 0;
+ setauevent();
+ while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
+ if (evp->ae_number <= as.as_numevent) {
+ ++i;
+ ec.ec_number = evp->ae_number;
+ ec.ec_class = evp->ae_class;
+ eauditon(A_SETCLASS, (caddr_t)&ec, (int)sizeof (ec));
+ }
+ }
+ endauevent();
+ (void) printf(gettext("Configured %d kernel events.\n"), i);
+
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_chkaconf()
+{
+ char buf[1024];
+ 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 (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));
+
+ if ((pmask.am_success != kmask.am_success) ||
+ (pmask.am_failure != kmask.am_failure)) {
+ char kbuf[2048];
+ if (getauditflagschar(kbuf, &kmask, 0) < 0) {
+ (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);
+ }
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_aconf()
+{
+ 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);
+ }
+
+ 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"));
+}
+
+static void
+do_audit(event, sorf, retval, audit_str)
+ char *event;
+ char sorf;
+ int retval;
+ char *audit_str;
+{
+ int rtn;
+ int rd;
+ au_event_t event_num;
+ au_event_ent_t *evp;
+ auditinfo_addr_t ai;
+ token_t *tokp;
+
+ egetaudit(&ai, sizeof (ai));
+
+ if (strisnum(event)) {
+ event_num = (au_event_t)atoi(event);
+ evp = egetauevnum(event_num);
+ } else
+ evp = egetauevnam(event);
+
+ rtn = au_preselect(evp->ae_number, &ai.ai_mask, (int)sorf,
+ AU_PRS_USECACHE);
+
+ if (rtn == -1)
+ exit_error("%s\n%s %d\n",
+ gettext("Check audit event configuration."),
+ gettext("Could not get audit class for event number"),
+ evp->ae_number);
+
+ /* record is preselected */
+ if (rtn == 1) {
+ if ((rd = au_open()) == -1)
+ exit_error(gettext(
+ "Could not get and audit record descriptor\n"));
+ if ((tokp = au_to_me()) == (token_t *)NULL)
+ exit_error(gettext(
+ "Could not allocate subject token\n"));
+ if (au_write(rd, tokp) == -1)
+exit_error(gettext("Could not construct subject token of audit record\n"));
+ if ((tokp = au_to_text(audit_str)) == (token_t *)NULL)
+ exit_error(gettext("Could not allocate text token\n"));
+ if (au_write(rd, tokp) == -1)
+exit_error(gettext("Could not construct text token of audit record\n"));
+#ifdef _LP64
+ if ((tokp = au_to_return64(sorf, retval)) == (token_t *)NULL)
+#else
+ if ((tokp = au_to_return32(sorf, retval)) == (token_t *)NULL)
+#endif
+ exit_error(gettext(
+ "Could not allocate return token\n"));
+ if (au_write(rd, tokp) == -1)
+ exit_error(gettext(
+ "Could not construct return token of audit record\n"));
+ if (au_close(rd, 1, evp->ae_number) == -1)
+ exit_error(gettext(
+ "Could not write audit record: %s\n"),
+ strerror(errno));
+ }
+}
+
+static void
+do_getauid()
+{
+ au_id_t auid;
+
+ egetauid(&auid);
+ print_auid(auid);
+}
+
+static void
+do_getaudit()
+{
+ auditinfo_addr_t ai;
+
+ egetaudit(&ai, sizeof (ai));
+ print_auid(ai.ai_auid);
+ print_mask(gettext("process preselection mask"), &ai.ai_mask);
+ print_tid_ex(&ai.ai_termid);
+ print_asid(ai.ai_asid);
+}
+
+static void
+do_getkaudit()
+{
+ auditinfo_addr_t ai;
+
+ egetkaudit(&ai, sizeof (ai));
+ print_auid(ai.ai_auid);
+ print_mask(gettext("process preselection mask"), &ai.ai_mask);
+ print_tid_ex(&ai.ai_termid);
+ print_asid(ai.ai_asid);
+}
+
+/*
+ * per zone if AUDIT_PERZONE set, else only in global zone.
+ */
+
+static void
+do_setkaudit(t, s)
+ char *t;
+ char *s;
+{
+ uint_t type;
+ auditinfo_addr_t ai;
+
+ egetkaudit(&ai, sizeof (ai));
+ (void) str2type(t, &type);
+ (void) str2ipaddr(s, &ai.ai_termid.at_addr[0], type);
+ ai.ai_termid.at_type = type;
+ esetkaudit(&ai, sizeof (ai));
+}
+
+/*
+ * returns zone-relative root
+ */
+
+static void
+do_getcar()
+{
+ char path[MAXPATHLEN];
+
+ eauditon(A_GETCAR, (caddr_t)path, (int)sizeof (path));
+ (void) printf(gettext("current active root = %s\n"), path);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getclass(event_str)
+ char *event_str;
+{
+ au_evclass_map_t ec;
+ au_event_ent_t *evp;
+ au_event_t event_number;
+ char *event_name;
+ char desc[256];
+
+ if (strisnum(event_str)) {
+ event_number = atol(event_str);
+ if ((evp = egetauevnum(event_number)) !=
+ (au_event_ent_t *)NULL) {
+ event_number = evp->ae_number;
+ event_name = evp->ae_name;
+ } else
+ event_name = gettext("unknown");
+ } else {
+ event_name = event_str;
+ if ((evp = egetauevnam(event_str)) != (au_event_ent_t *)NULL)
+ event_number = evp->ae_number;
+ }
+
+ ec.ec_number = event_number;
+ eauditon(A_GETCLASS, (caddr_t)&ec, 0);
+
+ (void) sprintf(desc, gettext("audit class mask for event %s(%d)"),
+ event_name, event_number);
+ print_mask1(desc, ec.ec_class);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set. (AUC_DISABLED is always global, the other states are per zone
+ * if AUDIT_PERZONE is set)
+ */
+
+static void
+do_getcond()
+{
+ char cond_str[16];
+ uint_t cond;
+
+ eauditon(A_GETCOND, (caddr_t)&cond, (int)sizeof (cond));
+
+ (void) cond2str(cond, cond_str);
+ (void) printf(gettext("audit condition = %s\n"), cond_str);
+}
+
+/*
+ * returned path is relative to zone root
+ */
+
+static void
+do_getcwd()
+{
+ char path[MAXPATHLEN];
+
+ eauditon(A_GETCWD, (caddr_t)path, (int)sizeof (path));
+ (void) printf(gettext("current working directory = %s\n"), path);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getkmask()
+{
+ au_mask_t pmask;
+
+ eauditon(A_GETKMASK, (caddr_t)&pmask, (int)sizeof (pmask));
+ print_mask(gettext("audit flags for non-attributable events"), &pmask);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set. (some policies can only be set from the global zone, but all
+ * can be read from anywhere.)
+ */
+
+static void
+do_getpolicy()
+{
+ char policy_str[1024];
+ uint_t policy;
+
+ eauditon(A_GETPOLICY, (caddr_t)&policy, 0);
+ (void) policy2str(policy, policy_str, sizeof (policy_str));
+ (void) printf(gettext("audit policies = %s\n"), policy_str);
+}
+
+static void
+do_getpinfo(pid_str)
+ char *pid_str;
+{
+ struct auditpinfo_addr ap;
+
+ if (strisnum(pid_str))
+ ap.ap_pid = (pid_t)atoi(pid_str);
+ else
+ exit_usage(1);
+
+ eauditon(A_GETPINFO_ADDR, (caddr_t)&ap, sizeof (ap));
+
+ print_auid(ap.ap_auid);
+ print_mask(gettext("process preselection mask"), &(ap.ap_mask));
+ print_tid_ex(&(ap.ap_termid));
+ print_asid(ap.ap_asid);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getqbufsz()
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ (void) printf(gettext("audit queue buffer size (bytes) = %ld\n"),
+ qctrl.aq_bufsz);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getqctrl()
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ (void) printf(gettext("audit queue hiwater mark (records) = %ld\n"),
+ qctrl.aq_hiwater);
+ (void) printf(gettext("audit queue lowater mark (records) = %ld\n"),
+ qctrl.aq_lowater);
+ (void) printf(gettext("audit queue buffer size (bytes) = %ld\n"),
+ qctrl.aq_bufsz);
+ (void) printf(gettext("audit queue delay (ticks) = %ld\n"),
+ qctrl.aq_delay);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getqdelay()
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ (void) printf(gettext("audit queue delay (ticks) = %ld\n"),
+ qctrl.aq_delay);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getqhiwater()
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ (void) printf(gettext("audit queue hiwater mark (records) = %ld\n"),
+ qctrl.aq_hiwater);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getqlowater()
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ (void) printf(gettext("audit queue lowater mark (records) = %ld\n"),
+ qctrl.aq_lowater);
+}
+
+static void
+do_getasid()
+{
+ auditinfo_addr_t ai;
+
+ if (getaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("getaudit_addr(2) failed"));
+ }
+ print_asid(ai.ai_asid);
+}
+
+/*
+ * The stats are for the entire system unless AUDIT_PERZONE is set.
+ */
+
+static void
+do_getstat()
+{
+ au_stat_t as;
+
+ eauditon(A_GETSTAT, (caddr_t)&as, 0);
+ print_stats(&as);
+}
+
+static void
+do_gettermid()
+{
+ auditinfo_addr_t ai;
+
+ if (getaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("getaudit_addr(2) failed"));
+ }
+ print_tid_ex(&ai.ai_termid);
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_getfsize()
+{
+ au_fstat_t fstat;
+
+ eauditon(A_GETFSIZE, (caddr_t)&fstat, 0);
+ (void) printf(gettext("Maximum file size %d, current file size %d\n"),
+ fstat.af_filesz, fstat.af_currsz);
+}
+
+/*ARGSUSED*/
+static void
+do_getuseraudit(user)
+char *user;
+{
+ (void) printf(gettext("-getuseraudit supported on SunOS CMW only.\n"));
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_lsevent()
+{
+ register au_event_ent_t *evp;
+ au_mask_t pmask;
+ char auflags[256];
+
+ setauevent();
+ if ((evp = getauevent()) == (au_event_ent_t *)NULL) {
+ (void) exit_error(gettext(
+ "NO AUDIT EVENTS: Could not read %s\n."),
+ AUDITEVENTFILE);
+ }
+
+ setauevent();
+ while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
+ pmask.am_success = pmask.am_failure = evp->ae_class;
+ if (getauditflagschar(auflags, &pmask, 0) == -1)
+ (void) strcpy(auflags, "unknown");
+ (void) printf("%-30s %5d %s %s\n",
+ evp->ae_name, evp->ae_number, auflags, evp->ae_desc);
+ }
+ endauevent();
+}
+
+/*
+ * The returned value is for the global zone unless AUDIT_PERZONE is
+ * set.
+ */
+
+static void
+do_lspolicy()
+{
+ int i;
+
+ /*
+ * TRANSLATION_NOTE
+ * Print a properly aligned header.
+ */
+ (void) printf(gettext("policy string description:\n"));
+ for (i = 0; i < POLICY_TBL_SZ; i++)
+ (void) printf("%-17s%s\n",
+ policy_table[i].policy_str,
+ gettext(policy_table[i].policy_desc));
+}
+
+static void
+do_setasid(sid_str, argv)
+ char *sid_str;
+ char **argv;
+{
+ struct auditinfo_addr ai;
+
+ if (getaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("getaudit_addr(2) failed"));
+ }
+ ai.ai_asid = (au_asid_t)atol(sid_str);
+ if (setaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("setaudit_addr(2) failed"));
+ }
+ execit(argv);
+}
+
+static void
+do_setaudit(user_str, mask_str, tid_str, sid_str, argv)
+ char *user_str;
+ char *mask_str;
+ char *tid_str;
+ char *sid_str;
+ char **argv;
+{
+ auditinfo_addr_t ai;
+
+ ai.ai_auid = (au_id_t)get_user_id(user_str);
+ str2mask(mask_str, &ai.ai_mask),
+ str2tid(tid_str, &ai.ai_termid);
+ ai.ai_asid = (au_asid_t)atol(sid_str);
+
+ esetaudit(&ai, sizeof (ai));
+ execit(argv);
+}
+
+static void
+do_setauid(user, argv)
+ char *user;
+ char **argv;
+{
+ au_id_t auid;
+
+ auid = get_user_id(user);
+ esetauid(&auid);
+ execit(argv);
+}
+
+static void
+do_setpmask(pid_str, audit_flags)
+ char *pid_str;
+ char *audit_flags;
+{
+ struct auditpinfo ap;
+
+ if (strisnum(pid_str))
+ ap.ap_pid = (pid_t)atoi(pid_str);
+ else
+ exit_usage(1);
+
+ str2mask(audit_flags, &ap.ap_mask);
+
+ eauditon(A_SETPMASK, (caddr_t)&ap, (int)sizeof (ap));
+}
+
+static void
+do_setsmask(asid_str, audit_flags)
+ char *asid_str;
+ char *audit_flags;
+{
+ struct auditinfo ainfo;
+
+ if (strisnum(asid_str))
+ ainfo.ai_asid = (pid_t)atoi(asid_str);
+ else
+ exit_usage(1);
+
+ str2mask(audit_flags, &ainfo.ai_mask);
+
+ eauditon(A_SETSMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
+}
+
+static void
+do_setumask(auid_str, audit_flags)
+ char *auid_str;
+ char *audit_flags;
+{
+ struct auditinfo ainfo;
+
+ if (strisnum(auid_str))
+ ainfo.ai_auid = (pid_t)atoi(auid_str);
+ else
+ exit_usage(1);
+
+ str2mask(audit_flags, &ainfo.ai_mask);
+
+ eauditon(A_SETUMASK, (caddr_t)&ainfo, (int)sizeof (ainfo));
+}
+
+/*
+ * local zone use is valid if AUDIT_PERZONE is set, otherwise the
+ * syscall returns EPERM.
+ */
+
+static void
+do_setstat()
+{
+ au_stat_t as;
+
+ as.as_audit = (uint_t)-1;
+ as.as_auditctl = (uint_t)-1;
+ as.as_dropped = (uint_t)-1;
+ as.as_enqueue = (uint_t)-1;
+ as.as_generated = (uint_t)-1;
+ as.as_kernel = (uint_t)-1;
+ as.as_nonattrib = (uint_t)-1;
+ as.as_rblocked = (uint_t)-1;
+ as.as_totalsize = (uint_t)-1;
+ as.as_wblocked = (uint_t)-1;
+ as.as_written = (uint_t)-1;
+
+ eauditon(A_SETSTAT, (caddr_t)&as, (int)sizeof (as));
+ (void) puts(gettext("audit stats reset"));
+}
+
+/*ARGSUSED*/
+static void
+do_setuseraudit(user, auditflags)
+ char *user;
+ char *auditflags;
+{
+ (void) printf(gettext("-setuseraudit supported on SunOS CMW only.\n"));
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setclass(event_str, audit_flags)
+ char *event_str;
+ char *audit_flags;
+{
+ au_event_t event;
+ int mask;
+ au_mask_t pmask;
+ au_evclass_map_t ec;
+ au_event_ent_t *evp;
+
+ if (strisnum(event_str))
+ event = (uint_t)atol(event_str);
+ else {
+ if ((evp = egetauevnam(event_str)) != (au_event_ent_t *)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));
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setkmask(audit_flags)
+char *audit_flags;
+{
+ 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);
+}
+
+/*
+ * ahlt and perzone are global zone only; the other policies are valid
+ * in a local zone if AUDIT_PERZONE is set. The kernel insures that
+ * a local zone can't change ahlt and perzone (EINVAL).
+ */
+
+static void
+do_setpolicy(policy_str)
+char *policy_str;
+{
+ uint_t policy;
+
+ switch (str2policy(policy_str, &policy)) {
+ case 2:
+ exit_error(gettext(
+ "policy (%s) invalid in a local zone."),
+ policy_str);
+ break;
+ default:
+ exit_error(gettext(
+ "Invalid policy (%s) specified."),
+ policy_str);
+ break;
+ case 0:
+ eauditon(A_SETPOLICY, (caddr_t)&policy, 0);
+ break;
+ }
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setqbufsz(bufsz)
+char *bufsz;
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ qctrl.aq_bufsz = atol(bufsz);
+ eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setqctrl(hiwater, lowater, bufsz, delay)
+ char *hiwater;
+ char *lowater;
+ char *bufsz;
+ char *delay;
+{
+ struct au_qctrl qctrl;
+
+ qctrl.aq_hiwater = atol(hiwater);
+ qctrl.aq_lowater = atol(lowater);
+ qctrl.aq_bufsz = atol(bufsz);
+ qctrl.aq_delay = atol(delay);
+ eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setqdelay(delay)
+char *delay;
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ qctrl.aq_delay = atol(delay);
+ eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setqhiwater(hiwater)
+char *hiwater;
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ qctrl.aq_hiwater = atol(hiwater);
+ eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setqlowater(lowater)
+ char *lowater;
+{
+ struct au_qctrl qctrl;
+
+ eauditon(A_GETQCTRL, (caddr_t)&qctrl, 0);
+ qctrl.aq_lowater = atol(lowater);
+ eauditon(A_SETQCTRL, (caddr_t)&qctrl, 0);
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_settid(char *tid_str)
+{
+ struct auditinfo_addr ai;
+
+ if (getaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("getaudit_addr(2) failed"));
+ }
+
+ str2tid(tid_str, &ai.ai_termid);
+
+ if (setaudit_addr(&ai, sizeof (ai))) {
+ exit_error(gettext("setaudit_addr(2) failed"));
+ }
+}
+
+/*
+ * AUDIT_PERZONE set: valid in all zones
+ * AUDIT_PERZONE not set: valid in global zone only
+ */
+
+static void
+do_setfsize(size)
+ char *size;
+{
+ au_fstat_t fstat;
+
+ fstat.af_filesz = atol(size);
+ eauditon(A_SETFSIZE, (caddr_t)&fstat, 0);
+}
+
+static void
+eauditon(cmd, data, length)
+ int cmd;
+ caddr_t data;
+ int length;
+{
+ if (auditon(cmd, data, length) == -1)
+ exit_error(gettext("auditon(2) failed."));
+}
+
+static void
+egetauid(auid)
+ au_id_t *auid;
+{
+ if (getauid(auid) == -1)
+ exit_error(gettext("getauid(2) failed."));
+}
+
+static void
+egetaudit(ai, size)
+ auditinfo_addr_t *ai;
+ int size;
+{
+ if (getaudit_addr(ai, size) == -1)
+ exit_error(gettext("getaudit_addr(2) failed."));
+}
+
+static void
+egetkaudit(ai, size)
+ auditinfo_addr_t *ai;
+ int size;
+{
+ if (auditon(A_GETKAUDIT, (char *)ai, size) < 0)
+ exit_error(gettext("auditon: A_GETKAUDIT failed."));
+}
+
+static void
+esetkaudit(ai, size)
+ auditinfo_addr_t *ai;
+ int size;
+{
+ if (auditon(A_SETKAUDIT, (char *)ai, size) < 0)
+ exit_error(gettext("auditon: A_SETKAUDIT failed."));
+}
+
+static void
+egetauditflagsbin(auditflags, pmask)
+ char *auditflags;
+ au_mask_t *pmask;
+{
+ pmask->am_success = pmask->am_failure = 0;
+
+ if (strcmp(auditflags, "none") == 0)
+ return;
+
+ if (getauditflagsbin(auditflags, pmask) < 0) {
+ exit_error(gettext("Could not get audit flags (%s)"),
+ auditflags);
+ }
+}
+
+static au_event_ent_t *
+egetauevnum(event_number)
+ au_event_t event_number;
+{
+ au_event_ent_t *evp;
+
+ if ((evp = getauevnum(event_number)) == (au_event_ent_t *)NULL)
+ exit_error(gettext("Could not get audit event %d"),
+ event_number);
+
+ return (evp);
+}
+
+static au_event_ent_t *
+egetauevnam(event_name)
+ char *event_name;
+{
+ register au_event_ent_t *evp;
+
+ if ((evp = getauevnam(event_name)) == (au_event_ent_t *)NULL)
+ exit_error(gettext("Could not get audit event %s"), event_name);
+
+ return (evp);
+}
+
+static void
+esetauid(auid)
+ au_id_t *auid;
+{
+ if (setauid(auid) == -1)
+ exit_error(gettext("setauid(2) failed."));
+}
+
+static void
+esetaudit(ai, size)
+ auditinfo_addr_t *ai;
+ int size;
+{
+ if (setaudit_addr(ai, size) == -1)
+ exit_error(gettext("setaudit_addr(2) failed."));
+}
+
+static uid_t
+get_user_id(user)
+ char *user;
+{
+ struct passwd *pwd;
+ uid_t uid;
+
+ setpwent();
+ if (isdigit(*user)) {
+ uid = atoi(user);
+ if ((pwd = getpwuid(uid)) == (struct passwd *)NULL) {
+ exit_error(gettext("Invalid user: %s"), user);
+ }
+ } else {
+ if ((pwd = getpwnam(user)) == (struct passwd *)NULL) {
+ exit_error(gettext("Invalid user: %s"), user);
+ }
+ }
+ endpwent();
+
+ return (pwd->pw_uid);
+}
+
+/*
+ * get_arg_ent()
+ * Inputs: command line argument string
+ * Returns ptr to policy_entry if found; null, if not found
+ */
+static struct arg_entry *
+get_arg_ent(arg_str)
+ char *arg_str;
+{
+ struct arg_entry key;
+
+ key.arg_str = arg_str;
+
+ return ((struct arg_entry *)bsearch((char *)&key,
+ (char *)arg_table, ARG_TBL_SZ, sizeof (struct arg_entry),
+ arg_ent_compare));
+}
+
+/*
+ * arg_ent_compare()
+ * Compares two command line arguments to determine which is
+ * lexicographically greater.
+ * Inputs: two argument map table entry pointers
+ * Returns: > 1: aep1->arg_str > aep2->arg_str
+ * < 1: aep1->arg_str < aep2->arg_str
+ * 0: aep1->arg_str = aep->arg_str2
+ */
+static int
+arg_ent_compare(aep1, aep2)
+struct arg_entry *aep1, *aep2;
+{
+ return (strcmp(aep1->arg_str, aep2->arg_str));
+}
+
+/*
+ * Convert mask of the following forms:
+ *
+ * audit_flags (ie. +lo,-ad,pc)
+ * 0xffffffff,0xffffffff
+ * ffffffff,ffffffff
+ * 20,20
+ */
+static void
+str2mask(mask_str, mp)
+ 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
+ */
+ if (strisflags(mask_str)) {
+ egetauditflagsbin(mask_str, mp);
+ /*
+ * a mask of the form 0xffffffff,0xffffffff or 1,1
+ */
+ } 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
+str2tid(char *tid_str, au_tid_addr_t *tp)
+{
+ char *major_str = (char *)NULL;
+ char *minor_str = (char *)NULL;
+ char *host_str = (char *)NULL;
+ major_t major = 0;
+ major_t minor = 0;
+ dev_t dev = 0;
+ struct hostent *phe;
+ int err;
+ uint32_t ibuf;
+ uint32_t ibuf6[4];
+
+ tp->at_port = 0;
+ tp->at_type = 0;
+ bzero(tp->at_addr, 16);
+
+ major_str = tid_str;
+ if ((minor_str = strchr(tid_str, ',')) != NULL) {
+ *minor_str = '\0';
+ minor_str++;
+ }
+
+ if (minor_str)
+ if ((host_str = strchr(minor_str, ',')) != NULL) {
+ *host_str = '\0';
+ host_str++;
+ }
+
+ if (major_str)
+ major = (major_t)atoi(major_str);
+
+ if (minor_str)
+ minor = (minor_t)atoi(minor_str);
+
+ if ((dev = makedev(major, minor)) != NODEV)
+ tp->at_port = dev;
+
+ if (host_str) {
+ if (strisipaddr(host_str)) {
+ if (inet_pton(AF_INET, host_str, &ibuf)) {
+ tp->at_addr[0] = ibuf;
+ tp->at_type = AU_IPv4;
+ } else if (inet_pton(AF_INET6, host_str, ibuf6)) {
+ tp->at_addr[0] = ibuf6[0];
+ tp->at_addr[1] = ibuf6[1];
+ tp->at_addr[2] = ibuf6[2];
+ tp->at_addr[3] = ibuf6[3];
+ tp->at_type = AU_IPv6;
+ }
+ } else {
+ phe = getipnodebyname((const void *)host_str,
+ AF_INET, 0, &err);
+ if (phe == 0) {
+ phe = getipnodebyname((const void *)host_str,
+ AF_INET6, 0, &err);
+ }
+
+ if (phe != NULL) {
+ if (phe->h_addrtype == AF_INET6) {
+ /* address is IPv6 (128 bits) */
+ (void) memcpy(&tp->at_addr[0],
+ phe->h_addr_list[0], 16);
+ tp->at_type = AU_IPv6;
+ } else {
+ /* address is IPv4 (32 bits) */
+ (void) memcpy(&tp->at_addr[0],
+ phe->h_addr_list[0], 4);
+ tp->at_type = AU_IPv4;
+ }
+ freehostent(phe);
+ }
+ }
+ }
+}
+
+static int
+cond2str(cond, cond_str)
+ uint_t cond;
+ char *cond_str;
+{
+ *cond_str = '\0';
+
+ if (cond == AUC_AUDITING) {
+ (void) strcpy(cond_str, "auditing");
+ return (0);
+ }
+
+ if ((cond == AUC_NOAUDIT) || (cond == AUC_INIT_AUDIT)) {
+ (void) strcpy(cond_str, "noaudit");
+ return (0);
+ }
+
+ if (cond == AUC_UNSET) {
+ (void) strcpy(cond_str, "unset");
+ return (0);
+ }
+
+ if (cond == AUC_NOSPACE) {
+ (void) strcpy(cond_str, "nospace");
+ return (0);
+ }
+
+ return (1);
+}
+
+static struct policy_entry *
+get_policy_ent(policy)
+ char *policy;
+{
+ int i;
+
+ for (i = 0; i < POLICY_TBL_SZ; i++)
+ if (strcmp(strtolower(policy),
+ policy_table[i].policy_str) == 0)
+ return (&policy_table[i]);
+
+ return ((struct policy_entry *)NULL);
+}
+
+static int
+str2policy(char *policy_str, uint_t *policy_mask)
+{
+ char *buf;
+ char *tok;
+ char pfix;
+ boolean_t is_all = 0;
+ uint_t pm = 0;
+ uint_t curp = 0;
+ struct policy_entry *pep;
+
+ pfix = *policy_str;
+
+ if (pfix == '-' || pfix == '+' || pfix == '=')
+ ++policy_str;
+
+ if ((buf = strdup(policy_str)) == NULL)
+ return (1);
+
+ for (tok = strtok(buf, ","); tok != NULL;
+ tok = strtok(NULL, ",")) {
+ if ((pep = get_policy_ent(tok)) == NULL) {
+ return (1);
+ } else {
+ pm |= pep->policy_mask;
+ if (pep->policy_mask == ALL_POLICIES)
+ is_all = 1;
+ }
+ }
+
+ free(buf);
+
+ if (pfix == '-') {
+ if (!is_all && (getzoneid() != GLOBAL_ZONEID) &&
+ (pm & ~AUDIT_LOCAL))
+ return (2);
+
+ eauditon(A_GETPOLICY, (caddr_t)&curp, 0);
+ if (getzoneid() != GLOBAL_ZONEID)
+ curp &= AUDIT_LOCAL;
+ *policy_mask = curp & ~pm;
+ } else if (pfix == '+') {
+ /*
+ * if the user is in a local zone and tries ahlt or
+ * perzone, that's an error. But if the user uses "all"
+ * then make it work
+ */
+ if (!is_all && (getzoneid() != GLOBAL_ZONEID) &&
+ (pm & ~AUDIT_LOCAL))
+ return (2);
+ eauditon(A_GETPOLICY, (caddr_t)&curp, 0);
+ if (getzoneid() != GLOBAL_ZONEID) {
+ curp &= AUDIT_LOCAL;
+ if (is_all)
+ pm &= AUDIT_LOCAL;
+ }
+ *policy_mask = curp | pm;
+ } else {
+ if (is_all && (getzoneid() != GLOBAL_ZONEID))
+ pm &= AUDIT_LOCAL;
+
+ *policy_mask = pm;
+ }
+ return (0);
+}
+
+static int
+policy2str(policy, policy_str, len)
+ uint_t policy;
+ char *policy_str;
+ size_t len;
+{
+ int i, j;
+
+ if (policy == ALL_POLICIES) {
+ (void) strcpy(policy_str, "all");
+ return (1);
+ }
+
+ if (policy == NO_POLICIES) {
+ (void) strcpy(policy_str, "none");
+ return (1);
+ }
+
+ *policy_str = '\0';
+
+ for (i = 0, j = 0; i < POLICY_TBL_SZ; i++)
+ if (policy & policy_table[i].policy_mask &&
+ policy_table[i].policy_mask != ALL_POLICIES) {
+ if (j++)
+ (void) strcat(policy_str, ",");
+ (void) strlcat(policy_str,
+ policy_table[i].policy_str, len);
+ }
+
+ if (*policy_str)
+ return (0);
+
+ return (1);
+}
+
+
+static int
+strisnum(s)
+ char *s;
+{
+ if (s == (char *)NULL || !*s)
+ return (0);
+
+ for (; *s == '-' || *s == '+'; s++)
+
+ if (!*s)
+ return (0);
+
+ for (; *s; s++)
+ if (!isdigit(*s))
+ return (0);
+
+ return (1);
+}
+
+static int
+strisflags(s)
+ char *s;
+{
+ if (s == (char *)NULL || !*s)
+ return (0);
+
+ for (; *s; s++) {
+ if (!isalpha(*s) &&
+ (*s != '+' && *s != '-' && *s != '^' && *s != ','))
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+strisipaddr(s)
+ char *s;
+{
+ int dot = 0;
+ int colon = 0;
+
+ /* no string */
+ if ((s == (char *)NULL) || (!*s))
+ return (0);
+
+ for (; *s; s++) {
+ if (!(isxdigit(*s) || *s != '.' || *s != ':'))
+ return (0);
+ if (*s == '.') dot++;
+ if (*s == ':') colon++;
+ }
+
+ if (dot && colon)
+ return (0);
+
+ if (!dot && !colon)
+ return (0);
+
+ return (1);
+}
+
+static void
+strsplit(s, p1, p2, c)
+ char *s;
+ char *p1;
+ char *p2;
+ char c;
+{
+ *p1 = *p2 = '\0';
+
+ while (*s != '\0' && *s != c)
+ *p1++ = *s++;
+ *p1 = '\0';
+ s++;
+
+ while (*s != '\0')
+ *p2++ = *s++;
+ *p2 = '\0';
+}
+
+static char *
+strtolower(s)
+ char *s;
+{
+ char *save;
+
+ for (save = s; *s; s++)
+ (void) tolower(*s);
+
+ return (save);
+}
+
+static void
+chk_event_num(etype, event)
+ int etype;
+ au_event_t event;
+{
+ au_stat_t as;
+
+ eauditon(A_GETSTAT, (caddr_t)&as, 0);
+
+ if (etype == AC_KERN_EVENT) {
+ if (event > as.as_numevent) {
+ exit_error(gettext("Invalid kernel audit event number "
+ "specified.\n\t%d is outside allowable range 0-%d."),
+ event, as.as_numevent);
+ }
+ } else { /* user event */
+ if (event <= as.as_numevent) {
+ exit_error(gettext(
+ "Invalid user level audit event number specified %d."),
+ event);
+ }
+ }
+}
+
+static void
+chk_event_str(etype, event_str)
+ int etype;
+ char *event_str;
+{
+ au_event_ent_t *evp;
+ au_stat_t as;
+
+ eauditon(A_GETSTAT, (caddr_t)&as, 0);
+
+ evp = egetauevnam(event_str);
+ if (etype == AC_KERN_EVENT && (evp->ae_number > as.as_numevent)) {
+ exit_error(
+ gettext("Invalid kernel audit event string specified.\n"
+ "\t\"%s\" appears to be a user level event. "
+ "Check configuration."),
+ event_str);
+ } else if (etype == AC_USER_EVENT &&
+ (evp->ae_number < as.as_numevent)) {
+ exit_error(
+ gettext("Invalid user audit event string specified.\n"
+ "\t\"%s\" appears to be a kernel event. "
+ "Check configuration."),
+ event_str);
+ }
+}
+
+static void
+chk_sorf(sorf_str)
+ char *sorf_str;
+{
+ if (!strisnum(sorf_str))
+ exit_error(gettext("Invalid sorf specified: %s"), sorf_str);
+}
+
+static void
+chk_retval(retval_str)
+ char *retval_str;
+{
+ if (!strisnum(retval_str))
+ exit_error(gettext("Invalid retval specified: %s"), retval_str);
+}
+
+static void
+chk_tid(tid_str)
+ char *tid_str;
+{
+ int c;
+ char *p;
+
+ /* need two commas (maj,min,hostname) */
+
+
+ for (p = tid_str, c = 0; *p; p++)
+ if (*p == ',')
+ ++c;
+ if (c != 2)
+ exit_error(gettext("Invalid tid specified: %s"), tid_str);
+}
+
+static void
+execit(argv)
+ char **argv;
+{
+ char *shell;
+
+ if (*argv)
+ (void) execvp(*argv, argv);
+ else {
+ if (((shell = getenv("SHELL")) == (char *)NULL) ||
+ *shell != '/')
+ shell = "/bin/csh";
+
+ (void) execlp(shell, shell, (char *)NULL);
+ }
+
+ exit_error(gettext("exec(2) failed"));
+}
+
+/*
+ * exit_error()
+ * Desc: Prints an error message along with corresponding system
+ * error number and error message, then exits.
+ * Inputs: Program name, program error message.
+ */
+/*PRINTFLIKE1*/
+static void
+exit_error(char *fmt, ...)
+{
+ va_list args;
+
+ (void) fprintf(stderr, "%s: ", progname);
+
+ va_start(args, fmt);
+ (void) vfprintf(stderr, fmt, args);
+ va_end(args);
+
+ (void) fputc('\n', stderr);
+ if (errno)
+ (void) fprintf(stderr, gettext("%s: error = %s(%d)\n"),
+ progname, strerror(errno), errno);
+ (void) fflush(stderr);
+
+ exit(1);
+}
+
+static void
+exit_usage(status)
+ int status;
+{
+ FILE *fp;
+ int i;
+
+ fp = (status ? stderr : stdout);
+ (void) fprintf(fp, gettext("usage: %s option ...\n"), progname);
+
+ for (i = 0; i < ARG2_TBL_SZ; i++)
+ (void) fprintf(fp, " %s %s\n",
+ arg2_table[i].arg_str, arg2_table[i].arg_opts);
+
+ exit(status);
+}
+
+static void
+print_asid(asid)
+ au_asid_t asid;
+{
+ (void) printf(gettext("audit session id = %u\n"), asid);
+}
+
+static void
+print_auid(auid)
+ au_id_t auid;
+{
+ struct passwd *pwd;
+ char *username;
+
+ setpwent();
+ if ((pwd = getpwuid((uid_t)auid)) != (struct passwd *)NULL)
+ username = pwd->pw_name;
+ else
+ username = gettext("unknown");
+ endpwent();
+
+ (void) printf(gettext("audit id = %s(%d)\n"), username, auid);
+}
+
+static void
+print_mask(desc, pmp)
+ char *desc;
+ au_mask_t *pmp;
+{
+ char auflags[512];
+
+ if (getauditflagschar(auflags, pmp, NULL) < 0)
+ (void) strlcpy(auflags, gettext("unknown"), sizeof (auflags));
+
+ (void) printf("%s = %s(0x%x,0x%x)\n",
+ desc, auflags, pmp->am_success, pmp->am_failure);
+}
+
+static void
+print_mask1(desc, mask1)
+ char *desc;
+ au_class_t mask1;
+{
+ (void) printf("%s = 0x%x\n", desc, (int)mask1);
+}
+
+static void
+print_stats(s)
+ au_stat_t *s;
+{
+ int offset[12]; /* used to line the header up correctly */
+ char buf[512];
+
+ (void) sprintf(buf, "%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu %n%4lu "
+ "%n%4lu %n%4lu %n%4lu %n%4lu %n%4lu%n",
+ (ulong_t)s->as_generated, &(offset[0]),
+ (ulong_t)s->as_nonattrib, &(offset[1]),
+ (ulong_t)s->as_kernel, &(offset[2]),
+ (ulong_t)s->as_audit, &(offset[3]),
+ (ulong_t)s->as_auditctl, &(offset[4]),
+ (ulong_t)s->as_enqueue, &(offset[5]),
+ (ulong_t)s->as_written, &(offset[6]),
+ (ulong_t)s->as_wblocked, &(offset[7]),
+ (ulong_t)s->as_rblocked, &(offset[8]),
+ (ulong_t)s->as_dropped, &(offset[9]),
+ (ulong_t)s->as_totalsize / ONEK, &(offset[10]),
+ (ulong_t)s->as_memused / ONEK, &(offset[11]));
+
+ /*
+ * TRANSLATION_NOTE
+ * Print a properly aligned header.
+ */
+ (void) printf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s\n",
+ offset[0] - 1, gettext("gen"),
+ offset[1] - offset[0] -1, gettext("nona"),
+ offset[2] - offset[1] -1, gettext("kern"),
+ offset[3] - offset[2] -1, gettext("aud"),
+ offset[4] - offset[3] -1, gettext("ctl"),
+ offset[5] - offset[4] -1, gettext("enq"),
+ offset[6] - offset[5] -1, gettext("wrtn"),
+ offset[7] - offset[6] -1, gettext("wblk"),
+ offset[8] - offset[7] -1, gettext("rblk"),
+ offset[9] - offset[8] -1, gettext("drop"),
+ offset[10] - offset[9] -1, gettext("tot"),
+ offset[11] - offset[10], gettext("mem"));
+
+ (void) puts(buf);
+}
+
+static void
+print_tid_ex(tidp)
+ au_tid_addr_t *tidp;
+{
+ struct hostent *phe;
+ char *hostname;
+ struct in_addr ia;
+ uint32_t *addr;
+ int err;
+ char buf[256];
+ char *bufp;
+
+
+ /* IPV6 or IPV4 address */
+ if (tidp->at_type == AU_IPv4) {
+ if ((phe = gethostbyaddr((char *)&tidp->at_addr[0],
+ sizeof (tidp->at_addr[0]),
+ AF_INET)) != (struct hostent *)NULL)
+ hostname = phe->h_name;
+ else
+ hostname = gettext("unknown");
+
+ ia.s_addr = tidp->at_addr[0];
+
+ (void) printf(gettext(
+ "terminal id (maj,min,host) = %u,%u,%s(%s)\n"),
+ major(tidp->at_port), minor(tidp->at_port),
+ hostname, inet_ntoa(ia));
+ } else {
+ addr = &tidp->at_addr[0];
+ phe = getipnodebyaddr((const void *)addr, 16, AF_INET6, &err);
+
+ bzero(buf, sizeof (buf));
+
+ (void) inet_ntop(AF_INET6, (void *)addr, buf,
+ sizeof (buf));
+ if (phe == (struct hostent *)0) {
+ bufp = gettext("unknown");
+ } else
+ bufp = phe->h_name;
+
+ (void) printf(gettext(
+ "terminal id (maj,min,host) = %u,%u,%s(%s)\n"),
+ major(tidp->at_port), minor(tidp->at_port),
+ bufp, buf);
+ if (phe)
+ freehostent(phe);
+ }
+}
+
+static int
+str2ipaddr(s, addr, type)
+ char *s;
+ uint32_t *addr;
+ uint32_t type;
+{
+ int j, sl;
+ char *ss;
+ unsigned int v;
+
+ bzero(addr, 16);
+ if (strisipaddr(s)) {
+ if (type == AU_IPv4) {
+ if (inet_pton(AF_INET, s, addr))
+ return (0);
+ return (1);
+ }
+ if (type == AU_IPv6) {
+ if (inet_pton(AF_INET6, s, addr))
+ return (0);
+ return (1);
+ }
+ return (1);
+ } else {
+ if (type == AU_IPv4) {
+ (void) sscanf(s, "%x", &addr[0]);
+ return (0);
+ }
+ if (type == AU_IPv6) {
+ sl = strlen(s);
+ ss = s;
+ for (j = 3; j >= 0; j--) {
+ if ((sl - 8) <= 0) {
+ (void) sscanf(s, "%x", &v);
+ addr[j] = v;
+ return (0);
+ }
+ ss = &s[sl-8];
+ (void) sscanf(ss, "%x", &v);
+ addr[j] = v;
+ sl -= 8;
+ *ss = '\0';
+ }
+ }
+ return (0);
+ }
+}
+
+static int
+str2type(s, type)
+ char *s;
+ uint_t *type;
+{
+ if (strcmp(s, "ipv6") == 0) {
+ *type = AU_IPv6;
+ return (0);
+ }
+ if (strcmp(s, "ipv4") == 0) {
+ *type = AU_IPv4;
+ return (0);
+ }
+
+ return (1);
+}