10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51914Scasper * Common Development and Distribution License (the "License").
61914Scasper * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate
220Sstevel@tonic-gate /*
23*11706SJan.Friedel@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
276812Sraf
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate * Interfaces to audit_event(5) (/etc/security/audit_event)
300Sstevel@tonic-gate */
310Sstevel@tonic-gate
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate * This routine is obsolete. I have removed its inclusion by removing
340Sstevel@tonic-gate * the .o from the makefile. Please use cacheauevent() or any of the
350Sstevel@tonic-gate * getauev* routines.
360Sstevel@tonic-gate */
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <limits.h>
400Sstevel@tonic-gate #include <stdio.h>
410Sstevel@tonic-gate #include <stdlib.h>
420Sstevel@tonic-gate #include <string.h>
430Sstevel@tonic-gate #include <bsm/audit.h>
440Sstevel@tonic-gate #include <bsm/libbsm.h>
450Sstevel@tonic-gate #include <synch.h>
460Sstevel@tonic-gate
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate * Macros to produce a quoted string containing the value of a
490Sstevel@tonic-gate * preprocessor macro. For example, if SIZE is defined to be 256,
500Sstevel@tonic-gate * VAL2STR(SIZE) is "256". This is used to construct format
510Sstevel@tonic-gate * strings for scanf-family functions below.
520Sstevel@tonic-gate */
530Sstevel@tonic-gate #define QUOTE(x) #x
540Sstevel@tonic-gate #define VAL2STR(x) QUOTE(x)
550Sstevel@tonic-gate
560Sstevel@tonic-gate static au_class_t flagstohex(char *);
570Sstevel@tonic-gate
580Sstevel@tonic-gate static char au_event_fname[PATH_MAX] = AUDITEVENTFILE;
590Sstevel@tonic-gate static FILE *au_event_file = (FILE *)0;
600Sstevel@tonic-gate static mutex_t mutex_eventfile = DEFAULTMUTEX;
610Sstevel@tonic-gate static mutex_t mutex_eventcache = DEFAULTMUTEX;
622540Spaulson /*
632540Spaulson * If an error occurs during the call to cacheauclassnam() inside
642540Spaulson * flagstohex() any return value could be seen as a valid class mask so
652540Spaulson * the following global variable, cacheauclass_failure, is set to indicate
662540Spaulson * that an error has occurred.
672540Spaulson */
682540Spaulson static int cacheauclass_failure = 0;
690Sstevel@tonic-gate
70*11706SJan.Friedel@Sun.COM #ifdef DEBUG2
71*11706SJan.Friedel@Sun.COM void
printevent(au_event_ent_t * p_event)72*11706SJan.Friedel@Sun.COM printevent(au_event_ent_t *p_event)
73*11706SJan.Friedel@Sun.COM {
74*11706SJan.Friedel@Sun.COM (void) printf("%d:%s:%s:%d\n", p_event->ae_number, p_event->ae_name,
75*11706SJan.Friedel@Sun.COM p_event->ae_desc, p_event->ae_class);
76*11706SJan.Friedel@Sun.COM (void) fflush(stdout);
77*11706SJan.Friedel@Sun.COM }
78*11706SJan.Friedel@Sun.COM #endif
790Sstevel@tonic-gate
800Sstevel@tonic-gate void
setauevent()810Sstevel@tonic-gate setauevent()
820Sstevel@tonic-gate {
836812Sraf (void) mutex_lock(&mutex_eventfile);
840Sstevel@tonic-gate if (au_event_file) {
850Sstevel@tonic-gate (void) fseek(au_event_file, 0L, 0);
860Sstevel@tonic-gate }
876812Sraf (void) mutex_unlock(&mutex_eventfile);
880Sstevel@tonic-gate }
890Sstevel@tonic-gate
900Sstevel@tonic-gate void
endauevent()910Sstevel@tonic-gate endauevent()
920Sstevel@tonic-gate {
936812Sraf (void) mutex_lock(&mutex_eventfile);
940Sstevel@tonic-gate if (au_event_file) {
950Sstevel@tonic-gate (void) fclose(au_event_file);
960Sstevel@tonic-gate au_event_file = (FILE *)0;
970Sstevel@tonic-gate }
986812Sraf (void) mutex_unlock(&mutex_eventfile);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate au_event_ent_t *
getauevent()1020Sstevel@tonic-gate getauevent()
1030Sstevel@tonic-gate {
1040Sstevel@tonic-gate static au_event_ent_t au_event_entry;
1050Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
1060Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate /* initialize au_event_entry structure */
1090Sstevel@tonic-gate au_event_entry.ae_name = ename;
1100Sstevel@tonic-gate au_event_entry.ae_desc = edesc;
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate return (getauevent_r(&au_event_entry));
1130Sstevel@tonic-gate }
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate au_event_ent_t *
getauevent_r(au_event_ent_t * au_event_entry)116*11706SJan.Friedel@Sun.COM getauevent_r(au_event_ent_t *au_event_entry)
1170Sstevel@tonic-gate {
1180Sstevel@tonic-gate int i, error = 0, found = 0;
1190Sstevel@tonic-gate char *s, input[AU_EVENT_LINE_MAX];
1200Sstevel@tonic-gate char trim_buf[AU_EVENT_NAME_MAX+1];
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate /* open audit event file if it isn't already */
1236812Sraf (void) mutex_lock(&mutex_eventfile);
1240Sstevel@tonic-gate if (!au_event_file)
1251914Scasper if (!(au_event_file = fopen(au_event_fname, "rF"))) {
1266812Sraf (void) mutex_unlock(&mutex_eventfile);
1277753STon.Nguyen@Sun.COM return (NULL);
1280Sstevel@tonic-gate }
1290Sstevel@tonic-gate
1300Sstevel@tonic-gate while (fgets(input, AU_EVENT_LINE_MAX, au_event_file)) {
1310Sstevel@tonic-gate if (input[0] != '#') {
1320Sstevel@tonic-gate s = input + strspn(input, " \t\r\n");
1330Sstevel@tonic-gate if ((*s == '\0') || (*s == '#')) {
1340Sstevel@tonic-gate continue;
1350Sstevel@tonic-gate }
1360Sstevel@tonic-gate found = 1;
1370Sstevel@tonic-gate s = input;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate /* parse number */
1400Sstevel@tonic-gate i = strcspn(s, ":");
1410Sstevel@tonic-gate s[i] = '\0';
1427753STon.Nguyen@Sun.COM (void) sscanf(s, "%hu", &au_event_entry->ae_number);
1430Sstevel@tonic-gate s = &s[i+1];
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate /* parse event name */
1460Sstevel@tonic-gate i = strcspn(s, ":");
1470Sstevel@tonic-gate s[i] = '\0';
1480Sstevel@tonic-gate (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
1490Sstevel@tonic-gate trim_buf);
1500Sstevel@tonic-gate (void) strncpy(au_event_entry->ae_name, trim_buf,
151*11706SJan.Friedel@Sun.COM AU_EVENT_NAME_MAX);
1520Sstevel@tonic-gate s = &s[i+1];
1530Sstevel@tonic-gate
1540Sstevel@tonic-gate /* parse event description */
1550Sstevel@tonic-gate i = strcspn(s, ":");
1560Sstevel@tonic-gate s[i] = '\0';
1570Sstevel@tonic-gate (void) strncpy(au_event_entry->ae_desc, s,
158*11706SJan.Friedel@Sun.COM AU_EVENT_DESC_MAX);
1590Sstevel@tonic-gate s = &s[i+1];
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate /* parse class */
1620Sstevel@tonic-gate i = strcspn(s, "\n\0");
1630Sstevel@tonic-gate s[i] = '\0';
1640Sstevel@tonic-gate (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
1650Sstevel@tonic-gate trim_buf);
1660Sstevel@tonic-gate au_event_entry->ae_class = flagstohex(trim_buf);
1672540Spaulson if (cacheauclass_failure == 1) {
1682540Spaulson error = 1;
1692540Spaulson cacheauclass_failure = 0;
1702540Spaulson }
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate break;
1730Sstevel@tonic-gate }
1740Sstevel@tonic-gate }
1756812Sraf (void) mutex_unlock(&mutex_eventfile);
1760Sstevel@tonic-gate
1770Sstevel@tonic-gate if (!error && found) {
1780Sstevel@tonic-gate return (au_event_entry);
1790Sstevel@tonic-gate } else {
1807753STon.Nguyen@Sun.COM return (NULL);
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate au_event_ent_t *
getauevnam(char * name)1850Sstevel@tonic-gate getauevnam(char *name)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate static au_event_ent_t au_event_entry;
1880Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
1890Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate /* initialize au_event_entry structure */
1920Sstevel@tonic-gate au_event_entry.ae_name = ename;
1930Sstevel@tonic-gate au_event_entry.ae_desc = edesc;
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate return (getauevnam_r(&au_event_entry, name));
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate au_event_ent_t *
getauevnam_r(au_event_ent_t * e,char * name)1990Sstevel@tonic-gate getauevnam_r(au_event_ent_t *e, char *name)
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate setauevent();
2020Sstevel@tonic-gate while (getauevent_r(e) != NULL) {
2030Sstevel@tonic-gate if (strcmp(e->ae_name, name) == 0) {
2040Sstevel@tonic-gate endauevent();
2050Sstevel@tonic-gate return (e);
2060Sstevel@tonic-gate }
2070Sstevel@tonic-gate }
2080Sstevel@tonic-gate endauevent();
2097753STon.Nguyen@Sun.COM return (NULL);
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate
2120Sstevel@tonic-gate au_event_ent_t *
getauevnum_r(au_event_ent_t * e,au_event_t event_number)2130Sstevel@tonic-gate getauevnum_r(au_event_ent_t *e, au_event_t event_number)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate setauevent();
2160Sstevel@tonic-gate while (getauevent_r(e) != NULL) {
2170Sstevel@tonic-gate if (e->ae_number == event_number) {
2180Sstevel@tonic-gate endauevent();
2190Sstevel@tonic-gate return (e);
2200Sstevel@tonic-gate }
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate endauevent();
2237753STon.Nguyen@Sun.COM return (NULL);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate au_event_ent_t *
getauevnum(au_event_t event_number)2270Sstevel@tonic-gate getauevnum(au_event_t event_number)
2280Sstevel@tonic-gate {
2290Sstevel@tonic-gate static au_event_ent_t e;
2300Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
2310Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate /* initialize au_event_entry structure */
2340Sstevel@tonic-gate e.ae_name = ename;
2350Sstevel@tonic-gate e.ae_desc = edesc;
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate return (getauevnum_r(&e, event_number));
2380Sstevel@tonic-gate }
2390Sstevel@tonic-gate
2400Sstevel@tonic-gate au_event_t
getauevnonam(char * event_name)2410Sstevel@tonic-gate getauevnonam(char *event_name)
2420Sstevel@tonic-gate {
2430Sstevel@tonic-gate au_event_ent_t e;
2440Sstevel@tonic-gate char ename[AU_EVENT_NAME_MAX];
2450Sstevel@tonic-gate char edesc[AU_EVENT_DESC_MAX];
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate /* initialize au_event_entry structure */
2480Sstevel@tonic-gate e.ae_name = ename;
2490Sstevel@tonic-gate e.ae_desc = edesc;
2500Sstevel@tonic-gate
2517753STon.Nguyen@Sun.COM if (getauevnam_r(&e, event_name) == NULL) {
2527753STon.Nguyen@Sun.COM return (0);
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate return (e.ae_number);
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate /*
2580Sstevel@tonic-gate * cacheauevent:
2590Sstevel@tonic-gate * Read the entire audit_event file into memory.
2600Sstevel@tonic-gate * Set a pointer to the requested entry in the cache
2610Sstevel@tonic-gate * or a pointer to an invalid entry if the event number
2620Sstevel@tonic-gate * is not known.
2630Sstevel@tonic-gate *
2640Sstevel@tonic-gate * Return < 0, if error.
2650Sstevel@tonic-gate * Return 0, if event number not in cache.
2660Sstevel@tonic-gate * Return 1, if event number is in cache.
2670Sstevel@tonic-gate */
2680Sstevel@tonic-gate int
cacheauevent(au_event_ent_t ** result,au_event_t event_number)2690Sstevel@tonic-gate cacheauevent(au_event_ent_t **result, au_event_t event_number)
2700Sstevel@tonic-gate {
2717753STon.Nguyen@Sun.COM static au_event_t max; /* the highest event number in the file */
2727753STon.Nguyen@Sun.COM static au_event_t min; /* the lowest event number in the file */
2730Sstevel@tonic-gate static int invalid; /* 1+index of the highest event number */
2740Sstevel@tonic-gate static au_event_ent_t **index_tbl;
2750Sstevel@tonic-gate static au_event_ent_t **p_tbl;
2760Sstevel@tonic-gate static int called_once = 0;
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate char line[AU_EVENT_LINE_MAX];
2790Sstevel@tonic-gate int lines = 0;
2800Sstevel@tonic-gate FILE *fp;
2810Sstevel@tonic-gate au_event_ent_t *p_event;
2820Sstevel@tonic-gate int i, size;
2830Sstevel@tonic-gate int hit = 0;
2840Sstevel@tonic-gate char *s;
2850Sstevel@tonic-gate
2866812Sraf (void) mutex_lock(&mutex_eventcache);
2870Sstevel@tonic-gate if (called_once == 0) {
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate /* Count number of lines in the events file */
2901914Scasper if ((fp = fopen(au_event_fname, "rF")) == NULL) {
2916812Sraf (void) mutex_unlock(&mutex_eventcache);
2920Sstevel@tonic-gate return (-1);
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate while (fgets(line, AU_EVENT_LINE_MAX, fp) != NULL) {
2950Sstevel@tonic-gate s = line + strspn(line, " \t\r\n");
2960Sstevel@tonic-gate if ((*s == '\0') || (*s == '#')) {
2970Sstevel@tonic-gate continue;
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate lines++;
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate (void) fclose(fp);
3020Sstevel@tonic-gate size = lines;
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate /*
3050Sstevel@tonic-gate * Make an array in which each element in an entry in the
3060Sstevel@tonic-gate * events file. Make the next to last element an invalid
3070Sstevel@tonic-gate * event. Make the last element a NULL pointer.
3080Sstevel@tonic-gate */
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate p_tbl = calloc(lines + 1, sizeof (au_event_ent_t));
3110Sstevel@tonic-gate if (p_tbl == NULL) {
3126812Sraf (void) mutex_unlock(&mutex_eventcache);
3130Sstevel@tonic-gate return (-2);
3140Sstevel@tonic-gate }
3150Sstevel@tonic-gate lines = 0;
3160Sstevel@tonic-gate max = 0;
3170Sstevel@tonic-gate min = 65535;
3180Sstevel@tonic-gate setauevent();
3190Sstevel@tonic-gate while ((p_event = getauevent()) != NULL) {
3200Sstevel@tonic-gate p_tbl[lines] = (au_event_ent_t *)
321*11706SJan.Friedel@Sun.COM malloc(sizeof (au_event_ent_t));
3220Sstevel@tonic-gate if (p_tbl[lines] == NULL) {
3236812Sraf (void) mutex_unlock(&mutex_eventcache);
3240Sstevel@tonic-gate return (-3);
3250Sstevel@tonic-gate }
3260Sstevel@tonic-gate p_tbl[lines]->ae_number = p_event->ae_number;
3270Sstevel@tonic-gate p_tbl[lines]->ae_name = strdup(p_event->ae_name);
3280Sstevel@tonic-gate p_tbl[lines]->ae_desc = strdup(p_event->ae_desc);
3290Sstevel@tonic-gate p_tbl[lines]->ae_class = p_event->ae_class;
3300Sstevel@tonic-gate #ifdef DEBUG2
3310Sstevel@tonic-gate printevent(p_tbl[lines]);
3320Sstevel@tonic-gate #endif
3337753STon.Nguyen@Sun.COM if (p_event->ae_number > max) {
3340Sstevel@tonic-gate max = p_event->ae_number;
3350Sstevel@tonic-gate }
3367753STon.Nguyen@Sun.COM if (p_event->ae_number < min) {
3370Sstevel@tonic-gate min = p_event->ae_number;
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate lines++;
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate endauevent();
3420Sstevel@tonic-gate invalid = lines;
3430Sstevel@tonic-gate p_tbl[invalid] = (au_event_ent_t *)
344*11706SJan.Friedel@Sun.COM malloc(sizeof (au_event_ent_t));
3450Sstevel@tonic-gate if (p_tbl[invalid] == NULL) {
3466812Sraf (void) mutex_unlock(&mutex_eventcache);
3470Sstevel@tonic-gate return (-4);
3480Sstevel@tonic-gate }
3497753STon.Nguyen@Sun.COM p_tbl[invalid]->ae_number = (au_event_t)-1;
3500Sstevel@tonic-gate p_tbl[invalid]->ae_name = "invalid event number";
3510Sstevel@tonic-gate p_tbl[invalid]->ae_desc = p_tbl[invalid]->ae_name;
3520Sstevel@tonic-gate p_tbl[invalid]->ae_class = (au_class_t)-1;
3530Sstevel@tonic-gate
3540Sstevel@tonic-gate #ifdef DEBUG2
3550Sstevel@tonic-gate for (i = 0; i < size; i++) {
356*11706SJan.Friedel@Sun.COM (void) printf("%d:%s:%s:%d\n", p_tbl[i]->ae_number,
357*11706SJan.Friedel@Sun.COM p_tbl[i]->ae_name, p_tbl[i]->ae_desc,
358*11706SJan.Friedel@Sun.COM p_tbl[i]->ae_class);
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate #endif
3610Sstevel@tonic-gate
3620Sstevel@tonic-gate /* get space for the index_tbl */
3630Sstevel@tonic-gate index_tbl = calloc(max+1, sizeof (au_event_ent_t *));
3640Sstevel@tonic-gate if (index_tbl == NULL) {
3656812Sraf (void) mutex_unlock(&mutex_eventcache);
3660Sstevel@tonic-gate return (-5);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate /* intialize the index_tbl to the invalid event number */
3707753STon.Nguyen@Sun.COM for (i = 0; (au_event_t)i < max; i++) {
3710Sstevel@tonic-gate index_tbl[i] = p_tbl[invalid];
3720Sstevel@tonic-gate }
3730Sstevel@tonic-gate
3740Sstevel@tonic-gate /* point each index_tbl element at the corresponding event */
3750Sstevel@tonic-gate for (i = 0; i < size; i++) {
3767753STon.Nguyen@Sun.COM index_tbl[p_tbl[i]->ae_number] = p_tbl[i];
3770Sstevel@tonic-gate }
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate called_once = 1;
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate
3837753STon.Nguyen@Sun.COM if (event_number > max || event_number < min) {
3840Sstevel@tonic-gate *result = index_tbl[invalid];
3850Sstevel@tonic-gate } else {
3867753STon.Nguyen@Sun.COM *result = index_tbl[event_number];
3870Sstevel@tonic-gate hit = 1;
3880Sstevel@tonic-gate }
3896812Sraf (void) mutex_unlock(&mutex_eventcache);
3900Sstevel@tonic-gate return (hit);
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate static au_class_t
flagstohex(char * flags)3940Sstevel@tonic-gate flagstohex(char *flags)
3950Sstevel@tonic-gate {
3960Sstevel@tonic-gate au_class_ent_t *p_class;
3972540Spaulson au_class_t hex = 0;
3980Sstevel@tonic-gate char *comma = ",";
3990Sstevel@tonic-gate char *s;
4000Sstevel@tonic-gate char *last;
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate s = strtok_r(flags, comma, &last);
4030Sstevel@tonic-gate while (s != NULL) {
4042540Spaulson if ((cacheauclassnam(&p_class, s)) < 0) {
4052540Spaulson cacheauclass_failure = 1;
4062540Spaulson return ((au_class_t)-1);
4072540Spaulson }
4080Sstevel@tonic-gate hex |= p_class->ac_class;
4090Sstevel@tonic-gate s = strtok_r(NULL, comma, &last);
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate return (hex);
4120Sstevel@tonic-gate }
413