getauditflags.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* get audit preselection mask values
*/
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <sys/types.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#define ON 1
#define OK 0
#define OFF -1
#define COMMA ','
#define MAXFLDLEN 25
int getauditflagsbin();
static int
match_class(s, prefix, m, v)
char *s;
char *prefix;
unsigned int m;
int v;
{
au_class_ent_t *p_class;
(void) strcat(s, prefix);
if (cacheauclass(&p_class, m) == 1) {
(void) strcat(s, v ? p_class->ac_desc : p_class->ac_name);
(void) strcat(s, ",");
return (0);
}
return (-1);
}
/*
* getauditflagschar() - convert bit flag to character string
*
* input: masks->am_success - audit on success
* masks->am_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
*/
int
getauditflagschar(auditstring, masks, verbose)
char *auditstring;
au_mask_t *masks;
int verbose;
{
char *prefix; /* +, -, or null */
unsigned int m; /* for masking with masks */
au_mask_t all; /* value for the string "all" */
int plus_all = 0; /* true if +all */
int minus_all = 0; /* true if -all */
int l;
/* initialize input buffer */
*auditstring = '\0';
/* no masks, no flags; we're outta here */
if ((masks->am_success == 0) && (masks->am_failure == 0)) {
if (match_class(auditstring, "", 0, verbose) != 0)
return (-1);
/* kludge to get rid of trailing comma */
l = strlen(auditstring) - 1;
if (auditstring[l] == COMMA)
auditstring[l] = '\0';
return (0);
}
/* Get the mask value for the string "all" */
all.am_success = 0;
all.am_failure = 0;
if (getauditflagsbin("all", &all) != 0)
return (-1);
if (all.am_success == masks->am_success) {
if (all.am_failure == masks->am_failure) {
(void) strcat(auditstring, "all");
return (0);
}
(void) strcat(auditstring, "+all,");
plus_all = 1;
} else if (all.am_failure == masks->am_failure) {
(void) strcat(auditstring, "-all,");
minus_all = 1;
}
for (m = (unsigned)0x80000000; m != 0; m >>= 1) {
if (m & masks->am_success & masks->am_failure)
prefix = plus_all ? "-" : (minus_all ? "+" : "");
else if (m & masks->am_success)
prefix = "+";
else if (m & masks->am_failure)
prefix = "-";
else
continue;
if (match_class(auditstring, prefix, m, verbose) != 0)
return (-1);
}
if (*(prefix = auditstring + strlen(auditstring) - 1) == COMMA)
*prefix = '\0';
return (0);
}
/*
* getauditflagsbin() - converts character string to success and
* failure bit masks
*
* input: auditstring - audit string
* cnt - number of elements in the masks array
*
* output: masks->am_success - audit on success
* masks->am_failure - audit on failure
*
* returns: 0 - ok
* -1 - error - string contains characters which do
* not match event flag names or invalid pointers
* passed in.
*/
int
getauditflagsbin(auditstring, masks)
char *auditstring;
au_mask_t *masks;
{
int gotone, done = 0, invert = 0, tryagain;
int retstat = 0, succ_event, fail_event;
char *ptr, tmp_buff[MAXFLDLEN];
au_class_ent_t *p_class;
if ((masks == NULL) || (auditstring == NULL))
return (-1);
masks->am_success = masks->am_failure = 0;
/* 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 != ' ' &&
*auditstring != '\t')
*ptr++ = *auditstring++;
else if (*auditstring == ' ' || *auditstring == '\t')
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 */
if (cacheauclassnam(&p_class, ptr) == 1) {
if (succ_event == ON)
masks->am_success |= p_class->ac_class;
else if (succ_event == OFF)
masks->am_success &=
~(p_class->ac_class);
if (fail_event == ON)
masks->am_failure |= p_class->ac_class;
else if (fail_event == OFF)
masks->am_failure &=
~(p_class->ac_class);
gotone = 1;
} else { /* Bug 4330887 */
syslog(LOG_CRIT,
"auditflags have invalid flag %s",
ptr);
continue;
}
if (!gotone) {
retstat = -1;
done = 1;
}
}
} while (!done);
return (retstat);
}