summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbc/libc/gen/common/getauditflags.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libbc/libc/gen/common/getauditflags.c')
-rw-r--r--usr/src/lib/libbc/libc/gen/common/getauditflags.c497
1 files changed, 497 insertions, 0 deletions
diff --git a/usr/src/lib/libbc/libc/gen/common/getauditflags.c b/usr/src/lib/libbc/libc/gen/common/getauditflags.c
new file mode 100644
index 0000000000..c58be9f408
--- /dev/null
+++ b/usr/src/lib/libbc/libc/gen/common/getauditflags.c
@@ -0,0 +1,497 @@
+/*
+ * 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 1992 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI" /* c2 secure */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/label.h>
+#include <sys/audit.h>
+#include <auevents.h>
+
+#define ON 1
+#define OK 0
+#define OFF -1
+#define COMMA ','
+#define COMMASTR ","
+
+#define COMMON 0
+#define SUCCESS 1
+#define FAILURE 2
+
+#define MAXFLDLEN 25
+#define MAXSTRLEN 360
+#define MAXEVENT 11
+
+/* GLOBALS */
+
+static int length;
+static int pos = 0;
+
+struct list {
+ short count;
+ short on[MAXEVENT+1];
+ short off;
+};
+typedef struct list list_t;
+
+struct exception {
+ short type;
+ short exception;
+};
+typedef struct exception except_t;
+
+/*
+ * getauditflagschar() - convert bit flag to character string
+ *
+ * input: masks->as_success - audit on success
+ * masks->as_failure - audit on failure
+ * verbose - string format. 0 if short name; 1 if long name;
+ *
+ * output: auditstring - resultant audit string
+ *
+ * returns: 0 - entry read ok
+ * -1 - error
+ */
+
+getauditflagschar(auditstring, masks, verbose)
+ char *auditstring;
+ audit_state_t *masks;
+ int verbose;
+{
+ int i, j, k, mask_num;
+ int list = -1, retstat = 0;
+ int except_list[3];
+ char *prefix = " ";
+ except_t except[2];
+ list_t lists[3];
+
+ /*
+ * initialize input buffer
+ */
+ strcpy(auditstring, "");
+ /*
+ * initialize lists struct
+ */
+ for (mask_num = COMMON; mask_num <= FAILURE; mask_num++) {
+ lists[mask_num].count = 0;
+ lists[mask_num].off = -1;
+ for (i=0;i<MAXEVENT+1;i++)
+ lists[mask_num].on[i] = -1;
+ }
+ /*
+ * initialize exception lists
+ */
+ for (i = 0; i < 2; i++) {
+ except[i].type = -1;
+ except[i].exception = -1;
+ }
+
+ for (i = 0; i < 3; i++)
+ except_list[i] = 0;
+
+ /*
+ * set length global
+ */
+ length = verbose;
+ pos = 0;
+
+ /*
+ * find turned-on events - if on, store index of event
+ * in one of the three event lists, common, success, failure.
+ */
+ for ( i = 0; i < MAXEVENT; i++) {
+ if (((event_class[i].event_mask & masks->as_success) > 0) ||
+ ((event_class[i].event_mask & masks->as_failure) > 0)) {
+
+ /*
+ * check for events in common
+ */
+ if (((event_class[i].event_mask & masks->as_success) >
+ 0) &&
+ ((event_class[i].event_mask & masks->as_failure) > 0))
+ lists[COMMON].on[lists[COMMON].count++] = i;
+
+ /*
+ * check for success events
+ */
+ if ((event_class[i].event_mask & masks->as_success) > 0)
+ lists[SUCCESS].on[lists[SUCCESS].count++] = i;
+ else {
+ except_list[SUCCESS]++;
+ if (lists[SUCCESS].off == -1)
+ lists[SUCCESS].off = i;
+ }
+ /*
+ * check for failure events
+ */
+ if ((event_class[i].event_mask & masks->as_failure) > 0)
+ lists[FAILURE].on[lists[FAILURE].count++] = i;
+ else {
+ except_list[FAILURE]++;
+ if (lists[FAILURE].off == -1)
+ lists[FAILURE].off = i;
+ }
+ } else {
+ except_list[COMMON]++;
+ if (lists[COMMON].off == -1)
+ lists[COMMON].off = i;
+ }
+ }
+ /*
+ * check for all set or all-1 set - output all and common exceptions.
+ * the all or common state is exclusive; only one of the
+ * three, (+-)all, allowed
+ */
+ /*
+ * no exceptions
+ */
+ if (lists[COMMON].count >= MAXEVENT-2) {
+ if (lists[COMMON].count == MAXEVENT)
+ list = COMMON;
+
+ /*
+ * one exception
+ */
+ else if (lists[COMMON].count == MAXEVENT-1) {
+ for (i=COMMON;i<=FAILURE && (list == -1);i++) {
+ if (except_list[i] == 1) {
+ list = COMMON;
+ except[0].type = i;
+ except[0].exception = lists[i].off;
+ }
+ }
+ }
+ /*
+ * two exceptions
+ */
+ else if (lists[COMMON].count == MAXEVENT-2) {
+ if (except_list[COMMON] == 1) {
+ list = COMMON;
+ except[0].type = COMMON;
+ except[0].exception = lists[COMMON].off;
+ for (i=SUCCESS;i<=FAILURE;i++) {
+ if (except_list[i] == 1) {
+ except[1].type = i;
+ except[1].exception = lists[i].off;
+ }
+ }
+
+ } else if (except_list[COMMON] == 0) {
+ for (i=SUCCESS,j=0;i<=FAILURE;i++) {
+ if (except_list[i] == 1) {
+ list = COMMON;
+ except[j].type = i;
+ except[j++].exception = lists[i].off;
+ }
+ }
+ }
+ }
+ } else {
+ /*
+ * check for +all or -all
+ */
+ for (i=SUCCESS,j=0;i<=FAILURE;i++) {
+ if (lists[i].count >= MAXEVENT-1) {
+ list = i;
+ except[j].type = i;
+ if (lists[i].count != MAXEVENT) {
+ if (lists[i].off != -1)
+ except[j++].exception =
+ lists[i].off;
+ else
+ except[j++].exception =
+ lists[COMMON].off;
+ }
+ }
+ }
+ }
+ /*
+ * output all and exceptions
+ */
+ if (list != -1) {
+ if(list==SUCCESS) {
+ if ((stringcopy(auditstring, "+", 0)) == -1)
+ retstat = -1;
+ }
+ if(list==FAILURE) {
+ if ((stringcopy(auditstring, "-", 0)) == -1)
+ retstat = -1;
+ }
+
+ if (retstat == 0) {
+ if (length) {
+ if
+ ((stringcopy(auditstring,event_class[11].event_lname,1)) == -1)
+ retstat = -1;
+ } else
+ if ((stringcopy(auditstring, event_class[11].event_sname,1)) == -1)
+ retstat = -1;
+ }
+
+ if (retstat == 0) {
+ /*
+ * output exceptions
+ */
+ for (i=0;i<2 && except[i].exception != -1; i++) {
+ if ((stringcopy(auditstring, "^", 0)) == -1)
+ retstat = -1;
+ if(except[i].type==SUCCESS) {
+ if ((stringcopy(auditstring, "+", 0)) == -1)
+ retstat = -1;
+ }
+ if (except[i].type==FAILURE) {
+ if ((stringcopy(auditstring, "-", 0)) == -1)
+ retstat = -1;
+ }
+ if (length == 1 && retstat == 0) {
+ if ((stringcopy(auditstring,
+ event_class[except[i].exception].event_lname, 1))==-1)
+ retstat = -1;
+ } else if (retstat == 0) {
+ if ((stringcopy(auditstring,
+ event_class[except[i].exception].event_sname, 1))==-1)
+ retstat = -1;
+ }
+ }
+ }
+ } /* end of " all " processing */
+
+ /*
+ * process common events if no "all" was output
+ */
+ if (list == -1 && (lists[COMMON].count > 0) && retstat == 0) {
+ /*
+ * output common events first
+ */
+ for (j=0;j<lists[COMMON].count;j++) {
+ if (length == 1) {
+ if ((stringcopy(auditstring,
+ event_class[lists[COMMON].on[j]].event_lname, 1)) == -1)
+ retstat = -1;
+ } else if ((stringcopy(auditstring,
+ event_class[lists[COMMON].on[j]].event_sname, 1)) == -1)
+ retstat = -1;
+ }
+ /*
+ * remove common events from individual lists
+ */
+ if (retstat == 0) {
+ for (i=SUCCESS;i<=FAILURE;i++) {
+ for(j=0;j<lists[COMMON].count;j++) {
+ for(k=0;k < lists[i].count;k++) {
+ if (lists[COMMON].on[j] ==
+ lists[i].on[k])
+ lists[i].on[k] = -1;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * start processing individual event flags in success
+ * and failure lists
+ */
+ if (list != COMMON && retstat == 0) {
+ for (i=SUCCESS;i<=FAILURE;i++) {
+ if(list != i) {
+ if (i==SUCCESS) strcpy(prefix, "+");
+ if (i==FAILURE) strcpy(prefix, "-");
+ for (j=0;j<MAXEVENT && j<lists[i].count;j++) {
+ if (lists[i].on[j] != -1) {
+ if ((stringcopy(auditstring, prefix, 0)) == -1)
+ retstat = -1;
+ if (length == 1 &&
+ retstat == 0) {
+ if ((stringcopy(auditstring,
+ event_class[lists[i].on[j]].event_lname, 1))==-1)
+ retstat = -1;
+ } else if (retstat == 0) {
+ if ((stringcopy(auditstring,
+ event_class[lists[i].on[j]].event_sname, 1))==-1)
+ retstat = -1;
+ }
+ }
+ }
+ }
+ }
+ }
+ if ((stringcopy(auditstring, "\0", 2)) == -1)
+ retstat = -1;
+
+ return (retstat);
+}
+
+static stringcopy(auditstring, event, flag)
+ char *auditstring;
+ char *event;
+ int flag; /* if set, output comma after event */
+{
+ int retstat = 0;
+
+ /*
+ * check size
+ */
+ if (pos >= MAXSTRLEN) {
+ fprintf(stderr,"getauditflagschar: Inputted buffer too small.\n");
+ retstat = -1;
+ } else if (flag != 2) {
+ strcpy(auditstring+pos, event);
+ pos += strlen(event);
+ if(flag) {
+ strcpy(auditstring+pos, COMMASTR);
+ pos += strlen(COMMASTR);
+ }
+ } else {
+ /*
+ * add null terminator only
+ */
+ if (pos)
+ strcpy(auditstring+(pos-1), event);
+
+ }
+ return (retstat);
+}
+
+/*
+ * getauditflagsbin() - converts character string to success and
+ * failure bit masks
+ *
+ * input: auditstring - audit string
+ * cnt - number of elements in the masks array
+ *
+ * output: masks->as_success - audit on success
+ * masks->as_failure - audit on failure
+ *
+ * returns: 0 - ok
+ * -1 - error - string contains characters which do
+ * not match event flag names
+ */
+
+getauditflagsbin(auditstring, masks)
+ char *auditstring;
+ audit_state_t *masks;
+{
+ int i, gotone, done = 0, invert = 0, tryagain;
+ int retstat = 0, succ_event, fail_event;
+ char *ptr, tmp_buff[MAXFLDLEN];
+
+ /*
+ * process character string
+ */
+ do {
+ gotone = 0;
+ /*
+ * read through string storing chars. until a comma
+ */
+ for (ptr=tmp_buff; !gotone;) {
+ if(*auditstring!=COMMA && *auditstring!='\0' &&
+ *auditstring!='\n' && *auditstring!=' ')
+ *ptr++ = *auditstring++;
+ else if (*auditstring == ' ')
+ *auditstring++;
+ else {
+ if (*auditstring == '\0' ||
+ *auditstring == '\n') {
+ done = 1;
+ if (ptr == tmp_buff)
+ done = 2;
+ }
+ gotone = 1;
+ }
+ }
+ /*
+ * process audit state
+ */
+ if(gotone && done != 2) {
+ if(!done) auditstring++;
+ *ptr++ = '\0';
+ ptr = tmp_buff;
+ gotone = 0;
+ succ_event = ON;
+ fail_event = ON;
+ tryagain = 1;
+ invert = 0;
+
+ /*
+ * get flags
+ */
+ do {
+ switch (*ptr++) {
+ case '^':
+ invert = 1;
+ succ_event = OFF;
+ fail_event = OFF;
+ break;
+ case '+':
+ if (invert)
+ fail_event = OK;
+ else {
+ succ_event = ON;
+ fail_event = OK;
+ }
+ break;
+ case '-':
+ if (invert)
+ succ_event = OK;
+ else {
+ fail_event = ON;
+ succ_event = OK;
+ }
+ break;
+ default:
+ tryagain = 0;
+ ptr--;
+ break;
+ }
+ } while(tryagain);
+
+ /* add audit state to mask */
+ for (i=0;i<MAXEVENT+1 && !gotone;i++) {
+ if ((!(strcmp(ptr, event_class[i].event_sname))) ||
+ (!(strcmp(ptr, event_class[i].event_lname)))) {
+ if (succ_event == ON)
+ masks->as_success |= event_class[i].event_mask;
+ else if (succ_event == OFF)
+ masks->as_success &= ~(event_class[i].event_mask);
+ if (fail_event == ON)
+ masks->as_failure |= event_class[i].event_mask;
+ else if (fail_event == OFF)
+ masks->as_failure &= ~(event_class[i].event_mask);
+ gotone = 1;
+ }
+ }
+ if(!gotone) {
+ retstat = -1;
+ done = 1;
+ }
+ }
+ } while (!done);
+
+ return (retstat);
+}