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