xref: /illumos-gate/usr/src/lib/libbsm/common/au_preselect.c (revision 711890bc9379ceea66272dc8d4981812224ea86e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 #pragma ident	"%Z%%M%	%I%	%E% SMI"
23 
24 #ifndef lint
25 static char sccsid[] = "%Z%%M% %I% %E% SMI";
26 #endif
27 
28 /*
29  * Copyright (c) 1988 by Sun Microsystems, Inc.
30  */
31 
32 /*
33  * au_preselect.c
34  */
35 
36 #include <sys/types.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <bsm/audit.h>
40 #include <bsm/libbsm.h>
41 #include <synch.h>
42 
43 #define	ALLOC_INIT (600)	/* initially allocate ALLOC_INIT map entries */
44 #define	ALLOC_INCR (100)	/* if more map entries are needed, realloc */
45 				/* in ALLOC_INCR increments */
46 
47 static int alloc_map();
48 static int load_map();
49 static int realloc_map();
50 
51 typedef struct event_map {
52 	au_event_t event;	/* audit event number */
53 	au_class_t class;	/* audit event class mask */
54 } event_map_t;
55 
56 static event_map_t *event_map;	/* the map */
57 static u_int alloc_count;	/* number of entries currently allocated */
58 static u_int event_count;	/* number of entries in map */
59 static mutex_t mutex_au_preselect = DEFAULTMUTEX;
60 
61 extern int _mutex_lock(mutex_t *);
62 extern int _mutex_unlock(mutex_t *);
63 
64 /*
65  * au_preselect:
66  *
67  * Keep a dynamic array of event<-->class mappings.
68  * Refresh the map when the value of flag is non-zero.
69  * Return:
70  *	1: The event is preselected.
71  *	0: The event is not preselected.
72  *	-1: There was an error:
73  *		Couldn't allocate memory.
74  *		Couldn't find event.
75  */
76 int
77 #ifdef __STDC__
78 au_preselect(au_event_t au_event, au_mask_t *au_mask_p, int sorf, int flag)
79 #else
80 au_preselect(au_event, au_mask_p, sorf, flag)
81 	au_event_t au_event;	/* event */
82 	au_mask_t *au_mask_p;	/* preselection mask */
83 	int sorf;		/* success or failure */
84 	int flag;		/* re-read flag */
85 #endif /* __STDC__ */
86 {
87 	static char been_here_before;  /* we cache the map */
88 	register int i;
89 	register au_class_t comp_class;
90 
91 	_mutex_lock(&mutex_au_preselect);
92 	if (!been_here_before) {
93 		if (alloc_map() == -1) {
94 			_mutex_unlock(&mutex_au_preselect);
95 			return (-1);
96 		}
97 
98 		if (load_map() == -1) {
99 			_mutex_unlock(&mutex_au_preselect);
100 			return (-1);
101 		}
102 
103 		been_here_before = 1;
104 	}
105 
106 	/*
107 	 * Don't use the cache. Re-read the audit_event(5) db every time
108 	 */
109 	if (flag == AU_PRS_REREAD) {
110 		if (load_map() == -1) {
111 			_mutex_unlock(&mutex_au_preselect);
112 			return (-1);
113 		}
114 	}
115 
116 	/* Determine what portion of the preselection mask to check. */
117 	if (sorf == AU_PRS_SUCCESS)
118 		comp_class = au_mask_p->am_success;
119 	else if (sorf == AU_PRS_FAILURE)
120 		comp_class = au_mask_p->am_failure;
121 	else
122 		comp_class = au_mask_p->am_success | au_mask_p->am_failure;
123 
124 	for (i = 0; i < event_count; i++) {
125 		if (event_map[i].event == au_event) {
126 			if (event_map[i].class & comp_class) {
127 				_mutex_unlock(&mutex_au_preselect);
128 				return (1);
129 			} else {
130 				_mutex_unlock(&mutex_au_preselect);
131 				return (0);
132 			}
133 		}
134 	}
135 
136 	_mutex_unlock(&mutex_au_preselect);
137 	return (-1);	/* could not find event in the table */
138 }
139 
140 /*
141  * Initially allocate about as many map entries as are there
142  * are audit events shipped with the system. For sites
143  * that don't add audit events, this should be enough.
144  */
145 static int
146 alloc_map()
147 {
148 	if ((event_map = (event_map_t *)
149 		calloc(ALLOC_INIT, (size_t)sizeof (event_map_t))) ==
150 		(event_map_t *)NULL)
151 		return (-1);
152 	else
153 		alloc_count = ALLOC_INIT;
154 
155 	return (0);
156 }
157 
158 /*
159  * load the event<->class map into memory
160  */
161 static int
162 load_map()
163 {
164 	register au_event_ent_t *evp;
165 
166 	event_count = 0;
167 	setauevent();
168 	while ((evp = getauevent()) != (au_event_ent_t *)NULL) {
169 		if (event_count > alloc_count)
170 			if (realloc_map() == -1) {
171 				endauevent();
172 				return (-1);
173 			}
174 		event_map[event_count].event = evp->ae_number;
175 		event_map[event_count].class = evp->ae_class;
176 		++event_count;
177 	}
178 	endauevent();
179 
180 	return (0);
181 }
182 
183 /*
184  * realloc the event map in ALLOC_INCR increments
185  */
186 static int
187 realloc_map()
188 {
189 	register size_t rsize;
190 	rsize = sizeof (event_map_t) * (alloc_count + ALLOC_INCR);
191 
192 	if ((event_map = (event_map_t *)
193 		realloc(event_map, rsize)) == (event_map_t *)NULL)
194 		return (-1);
195 
196 	return (0);
197 }
198