17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5004388ebScasper * Common Development and Distribution License (the "License").
6004388ebScasper * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate
227c478bd9Sstevel@tonic-gate /*
23*dfc7be02SJan Friedel * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277257d1b4Sraf
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate * Interfaces to audit_event(5) (/etc/security/audit_event)
307c478bd9Sstevel@tonic-gate */
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate * This routine is obsolete. I have removed its inclusion by removing
347c478bd9Sstevel@tonic-gate * the .o from the makefile. Please use cacheauevent() or any of the
357c478bd9Sstevel@tonic-gate * getauev* routines.
367c478bd9Sstevel@tonic-gate */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <sys/types.h>
397c478bd9Sstevel@tonic-gate #include <limits.h>
407c478bd9Sstevel@tonic-gate #include <stdio.h>
417c478bd9Sstevel@tonic-gate #include <stdlib.h>
427c478bd9Sstevel@tonic-gate #include <string.h>
437c478bd9Sstevel@tonic-gate #include <bsm/audit.h>
447c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h>
457c478bd9Sstevel@tonic-gate #include <synch.h>
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate /*
487c478bd9Sstevel@tonic-gate * Macros to produce a quoted string containing the value of a
497c478bd9Sstevel@tonic-gate * preprocessor macro. For example, if SIZE is defined to be 256,
507c478bd9Sstevel@tonic-gate * VAL2STR(SIZE) is "256". This is used to construct format
517c478bd9Sstevel@tonic-gate * strings for scanf-family functions below.
527c478bd9Sstevel@tonic-gate */
537c478bd9Sstevel@tonic-gate #define QUOTE(x) #x
547c478bd9Sstevel@tonic-gate #define VAL2STR(x) QUOTE(x)
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate static au_class_t flagstohex(char *);
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate static char au_event_fname[PATH_MAX] = AUDITEVENTFILE;
597c478bd9Sstevel@tonic-gate static FILE *au_event_file = (FILE *)0;
607c478bd9Sstevel@tonic-gate static mutex_t mutex_eventfile = DEFAULTMUTEX;
617c478bd9Sstevel@tonic-gate static mutex_t mutex_eventcache = DEFAULTMUTEX;
62e4163c9bSpaulson /*
63e4163c9bSpaulson * If an error occurs during the call to cacheauclassnam() inside
64e4163c9bSpaulson * flagstohex() any return value could be seen as a valid class mask so
65e4163c9bSpaulson * the following global variable, cacheauclass_failure, is set to indicate
66e4163c9bSpaulson * that an error has occurred.
67e4163c9bSpaulson */
68e4163c9bSpaulson static int cacheauclass_failure = 0;
697c478bd9Sstevel@tonic-gate
70*dfc7be02SJan Friedel #ifdef DEBUG2
71*dfc7be02SJan Friedel void
printevent(au_event_ent_t * p_event)72*dfc7be02SJan Friedel printevent(au_event_ent_t *p_event)
73*dfc7be02SJan Friedel {
74*dfc7be02SJan Friedel (void) printf("%d:%s:%s:%d\n", p_event->ae_number, p_event->ae_name,
75*dfc7be02SJan Friedel p_event->ae_desc, p_event->ae_class);
76*dfc7be02SJan Friedel (void) fflush(stdout);
77*dfc7be02SJan Friedel }
78*dfc7be02SJan Friedel #endif
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate void
setauevent()817c478bd9Sstevel@tonic-gate setauevent()
827c478bd9Sstevel@tonic-gate {
837257d1b4Sraf (void) mutex_lock(&mutex_eventfile);
847c478bd9Sstevel@tonic-gate if (au_event_file) {
857c478bd9Sstevel@tonic-gate (void) fseek(au_event_file, 0L, 0);
867c478bd9Sstevel@tonic-gate }
877257d1b4Sraf (void) mutex_unlock(&mutex_eventfile);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate
907c478bd9Sstevel@tonic-gate void
endauevent()917c478bd9Sstevel@tonic-gate endauevent()
927c478bd9Sstevel@tonic-gate {
937257d1b4Sraf (void) mutex_lock(&mutex_eventfile);
947c478bd9Sstevel@tonic-gate if (au_event_file) {
957c478bd9Sstevel@tonic-gate (void) fclose(au_event_file);
967c478bd9Sstevel@tonic-gate au_event_file = (FILE *)0;
977c478bd9Sstevel@tonic-gate }
987257d1b4Sraf (void) mutex_unlock(&mutex_eventfile);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevent()1027c478bd9Sstevel@tonic-gate getauevent()
1037c478bd9Sstevel@tonic-gate {
1047c478bd9Sstevel@tonic-gate static au_event_ent_t au_event_entry;
1057c478bd9Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
1067c478bd9Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate /* initialize au_event_entry structure */
1097c478bd9Sstevel@tonic-gate au_event_entry.ae_name = ename;
1107c478bd9Sstevel@tonic-gate au_event_entry.ae_desc = edesc;
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate return (getauevent_r(&au_event_entry));
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevent_r(au_event_ent_t * au_event_entry)116*dfc7be02SJan Friedel getauevent_r(au_event_ent_t *au_event_entry)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate int i, error = 0, found = 0;
1197c478bd9Sstevel@tonic-gate char *s, input[AU_EVENT_LINE_MAX];
1207c478bd9Sstevel@tonic-gate char trim_buf[AU_EVENT_NAME_MAX+1];
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate /* open audit event file if it isn't already */
1237257d1b4Sraf (void) mutex_lock(&mutex_eventfile);
1247c478bd9Sstevel@tonic-gate if (!au_event_file)
125004388ebScasper if (!(au_event_file = fopen(au_event_fname, "rF"))) {
1267257d1b4Sraf (void) mutex_unlock(&mutex_eventfile);
127d0fa49b7STony Nguyen return (NULL);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate while (fgets(input, AU_EVENT_LINE_MAX, au_event_file)) {
1317c478bd9Sstevel@tonic-gate if (input[0] != '#') {
1327c478bd9Sstevel@tonic-gate s = input + strspn(input, " \t\r\n");
1337c478bd9Sstevel@tonic-gate if ((*s == '\0') || (*s == '#')) {
1347c478bd9Sstevel@tonic-gate continue;
1357c478bd9Sstevel@tonic-gate }
1367c478bd9Sstevel@tonic-gate found = 1;
1377c478bd9Sstevel@tonic-gate s = input;
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate /* parse number */
1407c478bd9Sstevel@tonic-gate i = strcspn(s, ":");
1417c478bd9Sstevel@tonic-gate s[i] = '\0';
142d0fa49b7STony Nguyen (void) sscanf(s, "%hu", &au_event_entry->ae_number);
1437c478bd9Sstevel@tonic-gate s = &s[i+1];
1447c478bd9Sstevel@tonic-gate
1457c478bd9Sstevel@tonic-gate /* parse event name */
1467c478bd9Sstevel@tonic-gate i = strcspn(s, ":");
1477c478bd9Sstevel@tonic-gate s[i] = '\0';
1487c478bd9Sstevel@tonic-gate (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
1497c478bd9Sstevel@tonic-gate trim_buf);
1507c478bd9Sstevel@tonic-gate (void) strncpy(au_event_entry->ae_name, trim_buf,
1517c478bd9Sstevel@tonic-gate AU_EVENT_NAME_MAX);
1527c478bd9Sstevel@tonic-gate s = &s[i+1];
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /* parse event description */
1557c478bd9Sstevel@tonic-gate i = strcspn(s, ":");
1567c478bd9Sstevel@tonic-gate s[i] = '\0';
1577c478bd9Sstevel@tonic-gate (void) strncpy(au_event_entry->ae_desc, s,
1587c478bd9Sstevel@tonic-gate AU_EVENT_DESC_MAX);
1597c478bd9Sstevel@tonic-gate s = &s[i+1];
1607c478bd9Sstevel@tonic-gate
1617c478bd9Sstevel@tonic-gate /* parse class */
1627c478bd9Sstevel@tonic-gate i = strcspn(s, "\n\0");
1637c478bd9Sstevel@tonic-gate s[i] = '\0';
1647c478bd9Sstevel@tonic-gate (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
1657c478bd9Sstevel@tonic-gate trim_buf);
1667c478bd9Sstevel@tonic-gate au_event_entry->ae_class = flagstohex(trim_buf);
167e4163c9bSpaulson if (cacheauclass_failure == 1) {
168e4163c9bSpaulson error = 1;
169e4163c9bSpaulson cacheauclass_failure = 0;
170e4163c9bSpaulson }
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate break;
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate }
1757257d1b4Sraf (void) mutex_unlock(&mutex_eventfile);
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate if (!error && found) {
1787c478bd9Sstevel@tonic-gate return (au_event_entry);
1797c478bd9Sstevel@tonic-gate } else {
180d0fa49b7STony Nguyen return (NULL);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevnam(char * name)1857c478bd9Sstevel@tonic-gate getauevnam(char *name)
1867c478bd9Sstevel@tonic-gate {
1877c478bd9Sstevel@tonic-gate static au_event_ent_t au_event_entry;
1887c478bd9Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
1897c478bd9Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate /* initialize au_event_entry structure */
1927c478bd9Sstevel@tonic-gate au_event_entry.ae_name = ename;
1937c478bd9Sstevel@tonic-gate au_event_entry.ae_desc = edesc;
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate return (getauevnam_r(&au_event_entry, name));
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevnam_r(au_event_ent_t * e,char * name)1997c478bd9Sstevel@tonic-gate getauevnam_r(au_event_ent_t *e, char *name)
2007c478bd9Sstevel@tonic-gate {
2017c478bd9Sstevel@tonic-gate setauevent();
2027c478bd9Sstevel@tonic-gate while (getauevent_r(e) != NULL) {
2037c478bd9Sstevel@tonic-gate if (strcmp(e->ae_name, name) == 0) {
2047c478bd9Sstevel@tonic-gate endauevent();
2057c478bd9Sstevel@tonic-gate return (e);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate endauevent();
209d0fa49b7STony Nguyen return (NULL);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevnum_r(au_event_ent_t * e,au_event_t event_number)2137c478bd9Sstevel@tonic-gate getauevnum_r(au_event_ent_t *e, au_event_t event_number)
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate setauevent();
2167c478bd9Sstevel@tonic-gate while (getauevent_r(e) != NULL) {
2177c478bd9Sstevel@tonic-gate if (e->ae_number == event_number) {
2187c478bd9Sstevel@tonic-gate endauevent();
2197c478bd9Sstevel@tonic-gate return (e);
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate }
2227c478bd9Sstevel@tonic-gate endauevent();
223d0fa49b7STony Nguyen return (NULL);
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate au_event_ent_t *
getauevnum(au_event_t event_number)2277c478bd9Sstevel@tonic-gate getauevnum(au_event_t event_number)
2287c478bd9Sstevel@tonic-gate {
2297c478bd9Sstevel@tonic-gate static au_event_ent_t e;
2307c478bd9Sstevel@tonic-gate static char ename[AU_EVENT_NAME_MAX];
2317c478bd9Sstevel@tonic-gate static char edesc[AU_EVENT_DESC_MAX];
2327c478bd9Sstevel@tonic-gate
2337c478bd9Sstevel@tonic-gate /* initialize au_event_entry structure */
2347c478bd9Sstevel@tonic-gate e.ae_name = ename;
2357c478bd9Sstevel@tonic-gate e.ae_desc = edesc;
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate return (getauevnum_r(&e, event_number));
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate au_event_t
getauevnonam(char * event_name)2417c478bd9Sstevel@tonic-gate getauevnonam(char *event_name)
2427c478bd9Sstevel@tonic-gate {
2437c478bd9Sstevel@tonic-gate au_event_ent_t e;
2447c478bd9Sstevel@tonic-gate char ename[AU_EVENT_NAME_MAX];
2457c478bd9Sstevel@tonic-gate char edesc[AU_EVENT_DESC_MAX];
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate /* initialize au_event_entry structure */
2487c478bd9Sstevel@tonic-gate e.ae_name = ename;
2497c478bd9Sstevel@tonic-gate e.ae_desc = edesc;
2507c478bd9Sstevel@tonic-gate
251d0fa49b7STony Nguyen if (getauevnam_r(&e, event_name) == NULL) {
252d0fa49b7STony Nguyen return (0);
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate return (e.ae_number);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate /*
2587c478bd9Sstevel@tonic-gate * cacheauevent:
2597c478bd9Sstevel@tonic-gate * Read the entire audit_event file into memory.
2607c478bd9Sstevel@tonic-gate * Set a pointer to the requested entry in the cache
2617c478bd9Sstevel@tonic-gate * or a pointer to an invalid entry if the event number
2627c478bd9Sstevel@tonic-gate * is not known.
2637c478bd9Sstevel@tonic-gate *
2647c478bd9Sstevel@tonic-gate * Return < 0, if error.
2657c478bd9Sstevel@tonic-gate * Return 0, if event number not in cache.
2667c478bd9Sstevel@tonic-gate * Return 1, if event number is in cache.
2677c478bd9Sstevel@tonic-gate */
2687c478bd9Sstevel@tonic-gate int
cacheauevent(au_event_ent_t ** result,au_event_t event_number)2697c478bd9Sstevel@tonic-gate cacheauevent(au_event_ent_t **result, au_event_t event_number)
2707c478bd9Sstevel@tonic-gate {
271d0fa49b7STony Nguyen static au_event_t max; /* the highest event number in the file */
272d0fa49b7STony Nguyen static au_event_t min; /* the lowest event number in the file */
2737c478bd9Sstevel@tonic-gate static int invalid; /* 1+index of the highest event number */
2747c478bd9Sstevel@tonic-gate static au_event_ent_t **index_tbl;
2757c478bd9Sstevel@tonic-gate static au_event_ent_t **p_tbl;
2767c478bd9Sstevel@tonic-gate static int called_once = 0;
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate char line[AU_EVENT_LINE_MAX];
2797c478bd9Sstevel@tonic-gate int lines = 0;
2807c478bd9Sstevel@tonic-gate FILE *fp;
2817c478bd9Sstevel@tonic-gate au_event_ent_t *p_event;
2827c478bd9Sstevel@tonic-gate int i, size;
2837c478bd9Sstevel@tonic-gate int hit = 0;
2847c478bd9Sstevel@tonic-gate char *s;
2857c478bd9Sstevel@tonic-gate
2867257d1b4Sraf (void) mutex_lock(&mutex_eventcache);
2877c478bd9Sstevel@tonic-gate if (called_once == 0) {
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gate /* Count number of lines in the events file */
290004388ebScasper if ((fp = fopen(au_event_fname, "rF")) == NULL) {
2917257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
2927c478bd9Sstevel@tonic-gate return (-1);
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate while (fgets(line, AU_EVENT_LINE_MAX, fp) != NULL) {
2957c478bd9Sstevel@tonic-gate s = line + strspn(line, " \t\r\n");
2967c478bd9Sstevel@tonic-gate if ((*s == '\0') || (*s == '#')) {
2977c478bd9Sstevel@tonic-gate continue;
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate lines++;
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate (void) fclose(fp);
3027c478bd9Sstevel@tonic-gate size = lines;
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate /*
3057c478bd9Sstevel@tonic-gate * Make an array in which each element in an entry in the
3067c478bd9Sstevel@tonic-gate * events file. Make the next to last element an invalid
3077c478bd9Sstevel@tonic-gate * event. Make the last element a NULL pointer.
3087c478bd9Sstevel@tonic-gate */
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate p_tbl = calloc(lines + 1, sizeof (au_event_ent_t));
3117c478bd9Sstevel@tonic-gate if (p_tbl == NULL) {
3127257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
3137c478bd9Sstevel@tonic-gate return (-2);
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate lines = 0;
3167c478bd9Sstevel@tonic-gate max = 0;
3177c478bd9Sstevel@tonic-gate min = 65535;
3187c478bd9Sstevel@tonic-gate setauevent();
3197c478bd9Sstevel@tonic-gate while ((p_event = getauevent()) != NULL) {
3207c478bd9Sstevel@tonic-gate p_tbl[lines] = (au_event_ent_t *)
3217c478bd9Sstevel@tonic-gate malloc(sizeof (au_event_ent_t));
3227c478bd9Sstevel@tonic-gate if (p_tbl[lines] == NULL) {
3237257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
3247c478bd9Sstevel@tonic-gate return (-3);
3257c478bd9Sstevel@tonic-gate }
3267c478bd9Sstevel@tonic-gate p_tbl[lines]->ae_number = p_event->ae_number;
3277c478bd9Sstevel@tonic-gate p_tbl[lines]->ae_name = strdup(p_event->ae_name);
3287c478bd9Sstevel@tonic-gate p_tbl[lines]->ae_desc = strdup(p_event->ae_desc);
3297c478bd9Sstevel@tonic-gate p_tbl[lines]->ae_class = p_event->ae_class;
3307c478bd9Sstevel@tonic-gate #ifdef DEBUG2
3317c478bd9Sstevel@tonic-gate printevent(p_tbl[lines]);
3327c478bd9Sstevel@tonic-gate #endif
333d0fa49b7STony Nguyen if (p_event->ae_number > max) {
3347c478bd9Sstevel@tonic-gate max = p_event->ae_number;
3357c478bd9Sstevel@tonic-gate }
336d0fa49b7STony Nguyen if (p_event->ae_number < min) {
3377c478bd9Sstevel@tonic-gate min = p_event->ae_number;
3387c478bd9Sstevel@tonic-gate }
3397c478bd9Sstevel@tonic-gate lines++;
3407c478bd9Sstevel@tonic-gate }
3417c478bd9Sstevel@tonic-gate endauevent();
3427c478bd9Sstevel@tonic-gate invalid = lines;
3437c478bd9Sstevel@tonic-gate p_tbl[invalid] = (au_event_ent_t *)
3447c478bd9Sstevel@tonic-gate malloc(sizeof (au_event_ent_t));
3457c478bd9Sstevel@tonic-gate if (p_tbl[invalid] == NULL) {
3467257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
3477c478bd9Sstevel@tonic-gate return (-4);
3487c478bd9Sstevel@tonic-gate }
349d0fa49b7STony Nguyen p_tbl[invalid]->ae_number = (au_event_t)-1;
3507c478bd9Sstevel@tonic-gate p_tbl[invalid]->ae_name = "invalid event number";
3517c478bd9Sstevel@tonic-gate p_tbl[invalid]->ae_desc = p_tbl[invalid]->ae_name;
3527c478bd9Sstevel@tonic-gate p_tbl[invalid]->ae_class = (au_class_t)-1;
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate #ifdef DEBUG2
3557c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) {
356*dfc7be02SJan Friedel (void) printf("%d:%s:%s:%d\n", p_tbl[i]->ae_number,
3577c478bd9Sstevel@tonic-gate p_tbl[i]->ae_name, p_tbl[i]->ae_desc,
3587c478bd9Sstevel@tonic-gate p_tbl[i]->ae_class);
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate #endif
3617c478bd9Sstevel@tonic-gate
3627c478bd9Sstevel@tonic-gate /* get space for the index_tbl */
3637c478bd9Sstevel@tonic-gate index_tbl = calloc(max+1, sizeof (au_event_ent_t *));
3647c478bd9Sstevel@tonic-gate if (index_tbl == NULL) {
3657257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
3667c478bd9Sstevel@tonic-gate return (-5);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate /* intialize the index_tbl to the invalid event number */
370d0fa49b7STony Nguyen for (i = 0; (au_event_t)i < max; i++) {
3717c478bd9Sstevel@tonic-gate index_tbl[i] = p_tbl[invalid];
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate
3747c478bd9Sstevel@tonic-gate /* point each index_tbl element at the corresponding event */
3757c478bd9Sstevel@tonic-gate for (i = 0; i < size; i++) {
376d0fa49b7STony Nguyen index_tbl[p_tbl[i]->ae_number] = p_tbl[i];
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate called_once = 1;
3807c478bd9Sstevel@tonic-gate
3817c478bd9Sstevel@tonic-gate }
3827c478bd9Sstevel@tonic-gate
383d0fa49b7STony Nguyen if (event_number > max || event_number < min) {
3847c478bd9Sstevel@tonic-gate *result = index_tbl[invalid];
3857c478bd9Sstevel@tonic-gate } else {
386d0fa49b7STony Nguyen *result = index_tbl[event_number];
3877c478bd9Sstevel@tonic-gate hit = 1;
3887c478bd9Sstevel@tonic-gate }
3897257d1b4Sraf (void) mutex_unlock(&mutex_eventcache);
3907c478bd9Sstevel@tonic-gate return (hit);
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate static au_class_t
flagstohex(char * flags)3947c478bd9Sstevel@tonic-gate flagstohex(char *flags)
3957c478bd9Sstevel@tonic-gate {
3967c478bd9Sstevel@tonic-gate au_class_ent_t *p_class;
397e4163c9bSpaulson au_class_t hex = 0;
3987c478bd9Sstevel@tonic-gate char *comma = ",";
3997c478bd9Sstevel@tonic-gate char *s;
4007c478bd9Sstevel@tonic-gate char *last;
4017c478bd9Sstevel@tonic-gate
4027c478bd9Sstevel@tonic-gate s = strtok_r(flags, comma, &last);
4037c478bd9Sstevel@tonic-gate while (s != NULL) {
404e4163c9bSpaulson if ((cacheauclassnam(&p_class, s)) < 0) {
405e4163c9bSpaulson cacheauclass_failure = 1;
406e4163c9bSpaulson return ((au_class_t)-1);
407e4163c9bSpaulson }
4087c478bd9Sstevel@tonic-gate hex |= p_class->ac_class;
4097c478bd9Sstevel@tonic-gate s = strtok_r(NULL, comma, &last);
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate return (hex);
4127c478bd9Sstevel@tonic-gate }
413