8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbsm / common / audit_event.c
blobba93597ced801016effe09ace3538111c29cbae0
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 * Interfaces to audit_event(5) (/etc/security/audit_event)
33 * This routine is obsolete. I have removed its inclusion by removing
34 * the .o from the makefile. Please use cacheauevent() or any of the
35 * getauev* routines.
38 #include <sys/types.h>
39 #include <limits.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <bsm/audit.h>
44 #include <bsm/libbsm.h>
45 #include <synch.h>
48 * Macros to produce a quoted string containing the value of a
49 * preprocessor macro. For example, if SIZE is defined to be 256,
50 * VAL2STR(SIZE) is "256". This is used to construct format
51 * strings for scanf-family functions below.
53 #define QUOTE(x) #x
54 #define VAL2STR(x) QUOTE(x)
56 static au_class_t flagstohex(char *);
58 static char au_event_fname[PATH_MAX] = AUDITEVENTFILE;
59 static FILE *au_event_file = (FILE *)0;
60 static mutex_t mutex_eventfile = DEFAULTMUTEX;
61 static mutex_t mutex_eventcache = DEFAULTMUTEX;
63 * If an error occurs during the call to cacheauclassnam() inside
64 * flagstohex() any return value could be seen as a valid class mask so
65 * the following global variable, cacheauclass_failure, is set to indicate
66 * that an error has occurred.
68 static int cacheauclass_failure = 0;
70 #ifdef DEBUG2
71 void
72 printevent(au_event_ent_t *p_event)
74 (void) printf("%d:%s:%s:%d\n", p_event->ae_number, p_event->ae_name,
75 p_event->ae_desc, p_event->ae_class);
76 (void) fflush(stdout);
78 #endif
80 void
81 setauevent()
83 (void) mutex_lock(&mutex_eventfile);
84 if (au_event_file) {
85 (void) fseek(au_event_file, 0L, 0);
87 (void) mutex_unlock(&mutex_eventfile);
90 void
91 endauevent()
93 (void) mutex_lock(&mutex_eventfile);
94 if (au_event_file) {
95 (void) fclose(au_event_file);
96 au_event_file = (FILE *)0;
98 (void) mutex_unlock(&mutex_eventfile);
101 au_event_ent_t *
102 getauevent()
104 static au_event_ent_t au_event_entry;
105 static char ename[AU_EVENT_NAME_MAX];
106 static char edesc[AU_EVENT_DESC_MAX];
108 /* initialize au_event_entry structure */
109 au_event_entry.ae_name = ename;
110 au_event_entry.ae_desc = edesc;
112 return (getauevent_r(&au_event_entry));
115 au_event_ent_t *
116 getauevent_r(au_event_ent_t *au_event_entry)
118 int i, error = 0, found = 0;
119 char *s, input[AU_EVENT_LINE_MAX];
120 char trim_buf[AU_EVENT_NAME_MAX+1];
122 /* open audit event file if it isn't already */
123 (void) mutex_lock(&mutex_eventfile);
124 if (!au_event_file)
125 if (!(au_event_file = fopen(au_event_fname, "rF"))) {
126 (void) mutex_unlock(&mutex_eventfile);
127 return (NULL);
130 while (fgets(input, AU_EVENT_LINE_MAX, au_event_file)) {
131 if (input[0] != '#') {
132 s = input + strspn(input, " \t\r\n");
133 if ((*s == '\0') || (*s == '#')) {
134 continue;
136 found = 1;
137 s = input;
139 /* parse number */
140 i = strcspn(s, ":");
141 s[i] = '\0';
142 (void) sscanf(s, "%hu", &au_event_entry->ae_number);
143 s = &s[i+1];
145 /* parse event name */
146 i = strcspn(s, ":");
147 s[i] = '\0';
148 (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
149 trim_buf);
150 (void) strncpy(au_event_entry->ae_name, trim_buf,
151 AU_EVENT_NAME_MAX);
152 s = &s[i+1];
154 /* parse event description */
155 i = strcspn(s, ":");
156 s[i] = '\0';
157 (void) strncpy(au_event_entry->ae_desc, s,
158 AU_EVENT_DESC_MAX);
159 s = &s[i+1];
161 /* parse class */
162 i = strcspn(s, "\n\0");
163 s[i] = '\0';
164 (void) sscanf(s, "%" VAL2STR(AU_EVENT_NAME_MAX) "s",
165 trim_buf);
166 au_event_entry->ae_class = flagstohex(trim_buf);
167 if (cacheauclass_failure == 1) {
168 error = 1;
169 cacheauclass_failure = 0;
172 break;
175 (void) mutex_unlock(&mutex_eventfile);
177 if (!error && found) {
178 return (au_event_entry);
179 } else {
180 return (NULL);
184 au_event_ent_t *
185 getauevnam(char *name)
187 static au_event_ent_t au_event_entry;
188 static char ename[AU_EVENT_NAME_MAX];
189 static char edesc[AU_EVENT_DESC_MAX];
191 /* initialize au_event_entry structure */
192 au_event_entry.ae_name = ename;
193 au_event_entry.ae_desc = edesc;
195 return (getauevnam_r(&au_event_entry, name));
198 au_event_ent_t *
199 getauevnam_r(au_event_ent_t *e, char *name)
201 setauevent();
202 while (getauevent_r(e) != NULL) {
203 if (strcmp(e->ae_name, name) == 0) {
204 endauevent();
205 return (e);
208 endauevent();
209 return (NULL);
212 au_event_ent_t *
213 getauevnum_r(au_event_ent_t *e, au_event_t event_number)
215 setauevent();
216 while (getauevent_r(e) != NULL) {
217 if (e->ae_number == event_number) {
218 endauevent();
219 return (e);
222 endauevent();
223 return (NULL);
226 au_event_ent_t *
227 getauevnum(au_event_t event_number)
229 static au_event_ent_t e;
230 static char ename[AU_EVENT_NAME_MAX];
231 static char edesc[AU_EVENT_DESC_MAX];
233 /* initialize au_event_entry structure */
234 e.ae_name = ename;
235 e.ae_desc = edesc;
237 return (getauevnum_r(&e, event_number));
240 au_event_t
241 getauevnonam(char *event_name)
243 au_event_ent_t e;
244 char ename[AU_EVENT_NAME_MAX];
245 char edesc[AU_EVENT_DESC_MAX];
247 /* initialize au_event_entry structure */
248 e.ae_name = ename;
249 e.ae_desc = edesc;
251 if (getauevnam_r(&e, event_name) == NULL) {
252 return (0);
254 return (e.ae_number);
258 * cacheauevent:
259 * Read the entire audit_event file into memory.
260 * Set a pointer to the requested entry in the cache
261 * or a pointer to an invalid entry if the event number
262 * is not known.
264 * Return < 0, if error.
265 * Return 0, if event number not in cache.
266 * Return 1, if event number is in cache.
269 cacheauevent(au_event_ent_t **result, au_event_t event_number)
271 static au_event_t max; /* the highest event number in the file */
272 static au_event_t min; /* the lowest event number in the file */
273 static int invalid; /* 1+index of the highest event number */
274 static au_event_ent_t **index_tbl;
275 static au_event_ent_t **p_tbl;
276 static int called_once = 0;
278 char line[AU_EVENT_LINE_MAX];
279 int lines = 0;
280 FILE *fp;
281 au_event_ent_t *p_event;
282 int i, size;
283 int hit = 0;
284 char *s;
286 (void) mutex_lock(&mutex_eventcache);
287 if (called_once == 0) {
289 /* Count number of lines in the events file */
290 if ((fp = fopen(au_event_fname, "rF")) == NULL) {
291 (void) mutex_unlock(&mutex_eventcache);
292 return (-1);
294 while (fgets(line, AU_EVENT_LINE_MAX, fp) != NULL) {
295 s = line + strspn(line, " \t\r\n");
296 if ((*s == '\0') || (*s == '#')) {
297 continue;
299 lines++;
301 (void) fclose(fp);
302 size = lines;
305 * Make an array in which each element in an entry in the
306 * events file. Make the next to last element an invalid
307 * event. Make the last element a NULL pointer.
310 p_tbl = calloc(lines + 1, sizeof (au_event_ent_t));
311 if (p_tbl == NULL) {
312 (void) mutex_unlock(&mutex_eventcache);
313 return (-2);
315 lines = 0;
316 max = 0;
317 min = 65535;
318 setauevent();
319 while ((p_event = getauevent()) != NULL) {
320 p_tbl[lines] = (au_event_ent_t *)
321 malloc(sizeof (au_event_ent_t));
322 if (p_tbl[lines] == NULL) {
323 (void) mutex_unlock(&mutex_eventcache);
324 return (-3);
326 p_tbl[lines]->ae_number = p_event->ae_number;
327 p_tbl[lines]->ae_name = strdup(p_event->ae_name);
328 p_tbl[lines]->ae_desc = strdup(p_event->ae_desc);
329 p_tbl[lines]->ae_class = p_event->ae_class;
330 #ifdef DEBUG2
331 printevent(p_tbl[lines]);
332 #endif
333 if (p_event->ae_number > max) {
334 max = p_event->ae_number;
336 if (p_event->ae_number < min) {
337 min = p_event->ae_number;
339 lines++;
341 endauevent();
342 invalid = lines;
343 p_tbl[invalid] = (au_event_ent_t *)
344 malloc(sizeof (au_event_ent_t));
345 if (p_tbl[invalid] == NULL) {
346 (void) mutex_unlock(&mutex_eventcache);
347 return (-4);
349 p_tbl[invalid]->ae_number = (au_event_t)-1;
350 p_tbl[invalid]->ae_name = "invalid event number";
351 p_tbl[invalid]->ae_desc = p_tbl[invalid]->ae_name;
352 p_tbl[invalid]->ae_class = (au_class_t)-1;
354 #ifdef DEBUG2
355 for (i = 0; i < size; i++) {
356 (void) printf("%d:%s:%s:%d\n", p_tbl[i]->ae_number,
357 p_tbl[i]->ae_name, p_tbl[i]->ae_desc,
358 p_tbl[i]->ae_class);
360 #endif
362 /* get space for the index_tbl */
363 index_tbl = calloc(max+1, sizeof (au_event_ent_t *));
364 if (index_tbl == NULL) {
365 (void) mutex_unlock(&mutex_eventcache);
366 return (-5);
369 /* intialize the index_tbl to the invalid event number */
370 for (i = 0; (au_event_t)i < max; i++) {
371 index_tbl[i] = p_tbl[invalid];
374 /* point each index_tbl element at the corresponding event */
375 for (i = 0; i < size; i++) {
376 index_tbl[p_tbl[i]->ae_number] = p_tbl[i];
379 called_once = 1;
383 if (event_number > max || event_number < min) {
384 *result = index_tbl[invalid];
385 } else {
386 *result = index_tbl[event_number];
387 hit = 1;
389 (void) mutex_unlock(&mutex_eventcache);
390 return (hit);
393 static au_class_t
394 flagstohex(char *flags)
396 au_class_ent_t *p_class;
397 au_class_t hex = 0;
398 char *comma = ",";
399 char *s;
400 char *last;
402 s = strtok_r(flags, comma, &last);
403 while (s != NULL) {
404 if ((cacheauclassnam(&p_class, s)) < 0) {
405 cacheauclass_failure = 1;
406 return ((au_class_t)-1);
408 hex |= p_class->ac_class;
409 s = strtok_r(NULL, comma, &last);
411 return (hex);