#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <bsm/audit.h>
#include <bsm/libbsm.h>
#include <adt_xlate.h>
#define SUCCESS 0x1
#define FAILURE 0x2
#define INVERSE 0x4
static int
match_class(char *s, char *prefix, uint_t m, int v)
{
au_class_ent_t *p_class;
(void) strcat(s, prefix);
if (cacheauclass(&p_class, m) == 1) {
if (v == 0) {
(void) strncat(s, p_class->ac_name, AU_CLASS_NAME_MAX);
} else {
(void) strncat(s, p_class->ac_desc, AU_CLASS_DESC_MAX);
}
(void) strcat(s, ",");
return (0);
}
return (-1);
}
int
getauditflagschar(char *auditstring, au_mask_t *masks, int verbose)
{
char *prefix;
unsigned int m;
au_mask_t all;
int plus_all = 0;
int minus_all = 0;
int l;
*auditstring = '\0';
if ((masks->am_success == 0) && (masks->am_failure == 0)) {
if (match_class(auditstring, "", 0, verbose) != 0)
return (-1);
l = strlen(auditstring) - 1;
if (auditstring[l] == ',')
auditstring[l] = '\0';
return (0);
}
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) == ',')
*prefix = '\0';
return (0);
}
boolean_t
__chkflags(char *flags, au_mask_t *mask, boolean_t cont, char **error)
{
uint32_t prefix;
au_class_ent_t *class;
char name[AU_CLASS_NAME_MAX+1];
int i;
if (flags == NULL || mask == NULL) {
return (B_FALSE);
}
mask->am_success = 0;
mask->am_failure = 0;
while (*flags != '\0') {
prefix = (SUCCESS | FAILURE);
while (isspace(*flags)) {
flags++;
}
if (*flags == '\0') {
break;
}
if (error != NULL) {
*error = flags;
}
if (*flags == '+') {
flags++;
prefix ^= FAILURE;
} else if (*flags == '-') {
flags++;
prefix ^= SUCCESS;
} else if (*flags == '^') {
flags++;
prefix |= INVERSE;
if (*flags == '+') {
flags++;
prefix ^= FAILURE;
} else if (*flags == '-') {
flags++;
prefix ^= SUCCESS;
}
}
for (i = 0; (i < sizeof (name) - 1) &&
!(*flags == '\0' || *flags == ','); i++) {
name[i] = *flags++;
}
name[i++] = '\0';
if (*flags == ',') {
flags++;
}
if (cacheauclassnam(&class, name) != 1) {
if (!cont) {
return (B_FALSE);
} else {
char msg[512];
(void) snprintf(msg, sizeof (msg), "invalid "
"audit flag %s", name);
adt_write_syslog(msg, EINVAL);
}
} else {
if ((prefix & (INVERSE | SUCCESS)) == SUCCESS) {
mask->am_success |= class->ac_class;
} else if ((prefix & (INVERSE | SUCCESS)) ==
(INVERSE | SUCCESS)) {
mask->am_success &= ~(class->ac_class);
}
if ((prefix & (INVERSE | FAILURE)) == FAILURE) {
mask->am_failure |= class->ac_class;
} else if ((prefix & (INVERSE | FAILURE)) ==
(INVERSE | FAILURE)) {
mask->am_failure &= ~(class->ac_class);
}
}
}
return (B_TRUE);
}
int
getauditflagsbin(char *auditstring, au_mask_t *masks)
{
if (__chkflags(auditstring, masks, B_TRUE, NULL)) {
return (0);
}
return (-1);
}