473 lines
10 KiB
C
473 lines
10 KiB
C
#if !defined(lint) && defined(SCCSIDS)
|
|
static char sccsid[] = "@(#)getauditflags.c 1.1 92/07/30 Copyr 1987 Sun Micro"; /* c2 secure */
|
|
#endif
|
|
|
|
#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);
|
|
}
|