]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/openbsm/libbsm/bsm_event.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / openbsm / libbsm / bsm_event.c
1 /*-
2  * Copyright (c) 2004 Apple Inc.
3  * Copyright (c) 2006 Robert N. M. Watson
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
22  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#17 $
31  */
32
33 #include <config/config.h>
34
35 #include <bsm/libbsm.h>
36
37 #include <string.h>
38 #ifdef HAVE_PTHREAD_MUTEX_LOCK
39 #include <pthread.h>
40 #endif
41 #include <stdio.h>
42 #include <stdlib.h>
43
44 #ifndef HAVE_STRLCPY
45 #include <compat/strlcpy.h>
46 #endif
47
48
49 /*
50  * Parse the contents of the audit_event file to return
51  * au_event_ent entries
52  */
53 static FILE             *fp = NULL;
54 static char              linestr[AU_LINE_MAX];
55 static const char       *eventdelim = ":";
56
57 #ifdef HAVE_PTHREAD_MUTEX_LOCK
58 static pthread_mutex_t  mutex = PTHREAD_MUTEX_INITIALIZER;
59 #endif
60
61 /*
62  * Parse one line from the audit_event file into the au_event_ent structure.
63  */
64 static struct au_event_ent *
65 eventfromstr(char *str, struct au_event_ent *e)
66 {
67         char *evno, *evname, *evdesc, *evclass;
68         struct au_mask evmask;
69         char *last;
70
71         evno = strtok_r(str, eventdelim, &last);
72         evname = strtok_r(NULL, eventdelim, &last);
73         evdesc = strtok_r(NULL, eventdelim, &last);
74         evclass = strtok_r(NULL, eventdelim, &last);
75
76         if ((evno == NULL) || (evname == NULL))
77                 return (NULL);
78
79         if (strlen(evname) >= AU_EVENT_NAME_MAX)
80                 return (NULL);
81
82         strlcpy(e->ae_name, evname, AU_EVENT_NAME_MAX);
83         if (evdesc != NULL) {
84                 if (strlen(evdesc) >= AU_EVENT_DESC_MAX)
85                         return (NULL);
86                 strlcpy(e->ae_desc, evdesc, AU_EVENT_DESC_MAX);
87         } else
88                 strlcpy(e->ae_desc, "", AU_EVENT_DESC_MAX);
89
90         e->ae_number = atoi(evno);
91
92         /*
93          * Find out the mask that corresponds to the given list of classes.
94          */
95         if (evclass != NULL) {
96                 if (getauditflagsbin(evclass, &evmask) != 0)
97                         e->ae_class = 0;
98                 else
99                         e->ae_class = evmask.am_success;
100         } else
101                 e->ae_class = 0;
102
103         return (e);
104 }
105
106 /*
107  * Rewind the audit_event file.
108  */
109 static void
110 setauevent_locked(void)
111 {
112
113         if (fp != NULL)
114                 fseek(fp, 0, SEEK_SET);
115 }
116
117 void
118 setauevent(void)
119 {
120
121 #ifdef HAVE_PTHREAD_MUTEX_LOCK
122         pthread_mutex_lock(&mutex);
123 #endif
124         setauevent_locked();
125 #ifdef HAVE_PTHREAD_MUTEX_LOCK
126         pthread_mutex_unlock(&mutex);
127 #endif
128 }
129
130 /*
131  * Close the open file pointers.
132  */
133 void
134 endauevent(void)
135 {
136
137 #ifdef HAVE_PTHREAD_MUTEX_LOCK
138         pthread_mutex_lock(&mutex);
139 #endif
140         if (fp != NULL) {
141                 fclose(fp);
142                 fp = NULL;
143         }
144 #ifdef HAVE_PTHREAD_MUTEX_LOCK
145         pthread_mutex_unlock(&mutex);
146 #endif
147 }
148
149 /*
150  * Enumerate the au_event_ent entries.
151  */
152 static struct au_event_ent *
153 getauevent_r_locked(struct au_event_ent *e)
154 {
155         char *nl;
156
157         if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
158                 return (NULL);
159
160         while (1) {
161                 if (fgets(linestr, AU_LINE_MAX, fp) == NULL)
162                         return (NULL);
163
164                 /* Remove new lines. */
165                 if ((nl = strrchr(linestr, '\n')) != NULL)
166                         *nl = '\0';
167
168                 /* Skip comments. */
169                 if (linestr[0] == '#')
170                         continue;
171
172                 /* Get the next event structure. */
173                 if (eventfromstr(linestr, e) == NULL)
174                         return (NULL);
175                 break;
176         }
177
178         return (e);
179 }
180
181 struct au_event_ent *
182 getauevent_r(struct au_event_ent *e)
183 {
184         struct au_event_ent *ep;
185
186 #ifdef HAVE_PTHREAD_MUTEX_LOCK
187         pthread_mutex_lock(&mutex);
188 #endif
189         ep = getauevent_r_locked(e);
190 #ifdef HAVE_PTHREAD_MUTEX_LOCK
191         pthread_mutex_unlock(&mutex);
192 #endif
193         return (ep);
194 }
195
196 struct au_event_ent *
197 getauevent(void)
198 {
199         static char event_ent_name[AU_EVENT_NAME_MAX];
200         static char event_ent_desc[AU_EVENT_DESC_MAX];
201         static struct au_event_ent e;
202
203         bzero(&e, sizeof(e));
204         bzero(event_ent_name, sizeof(event_ent_name));
205         bzero(event_ent_desc, sizeof(event_ent_desc));
206         e.ae_name = event_ent_name;
207         e.ae_desc = event_ent_desc;
208         return (getauevent_r(&e));
209 }
210
211 /*
212  * Search for an audit event structure having the given event name.
213  *
214  * XXXRW: Why accept NULL name?
215  */
216 static struct au_event_ent *
217 getauevnam_r_locked(struct au_event_ent *e, const char *name)
218 {
219         char *nl;
220
221         if (name == NULL)
222                 return (NULL);
223
224         /* Rewind to beginning of the file. */
225         setauevent_locked();
226
227         if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
228                 return (NULL);
229
230         while (fgets(linestr, AU_LINE_MAX, fp) != NULL) {
231                 /* Remove new lines. */
232                 if ((nl = strrchr(linestr, '\n')) != NULL)
233                         *nl = '\0';
234
235                 if (eventfromstr(linestr, e) != NULL) {
236                         if (strcmp(name, e->ae_name) == 0)
237                                 return (e);
238                 }
239         }
240
241         return (NULL);
242 }
243
244 struct au_event_ent *
245 getauevnam_r(struct au_event_ent *e, const char *name)
246 {
247         struct au_event_ent *ep;
248
249 #ifdef HAVE_PTHREAD_MUTEX_LOCK
250         pthread_mutex_lock(&mutex);
251 #endif
252         ep = getauevnam_r_locked(e, name);
253 #ifdef HAVE_PTHREAD_MUTEX_LOCK
254         pthread_mutex_unlock(&mutex);
255 #endif
256         return (ep);
257 }
258
259 struct au_event_ent *
260 getauevnam(const char *name)
261 {
262         static char event_ent_name[AU_EVENT_NAME_MAX];
263         static char event_ent_desc[AU_EVENT_DESC_MAX];
264         static struct au_event_ent e;
265
266         bzero(&e, sizeof(e));
267         bzero(event_ent_name, sizeof(event_ent_name));
268         bzero(event_ent_desc, sizeof(event_ent_desc));
269         e.ae_name = event_ent_name;
270         e.ae_desc = event_ent_desc;
271         return (getauevnam_r(&e, name));
272 }
273
274 /*
275  * Search for an audit event structure having the given event number.
276  */
277 static struct au_event_ent *
278 getauevnum_r_locked(struct au_event_ent *e, au_event_t event_number)
279 {
280         char *nl;
281
282         /* Rewind to beginning of the file. */
283         setauevent_locked();
284
285         if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
286                 return (NULL);
287
288         while (fgets(linestr, AU_LINE_MAX, fp) != NULL) {
289                 /* Remove new lines. */
290                 if ((nl = strrchr(linestr, '\n')) != NULL)
291                         *nl = '\0';
292
293                 if (eventfromstr(linestr, e) != NULL) {
294                         if (event_number == e->ae_number)
295                                 return (e);
296                 }
297         }
298
299         return (NULL);
300 }
301
302 struct au_event_ent *
303 getauevnum_r(struct au_event_ent *e, au_event_t event_number)
304 {
305         struct au_event_ent *ep;
306
307 #ifdef HAVE_PTHREAD_MUTEX_LOCK
308         pthread_mutex_lock(&mutex);
309 #endif
310         ep = getauevnum_r_locked(e, event_number);
311 #ifdef HAVE_PTHREAD_MUTEX_LOCK
312         pthread_mutex_unlock(&mutex);
313 #endif
314         return (ep);
315 }
316
317 struct au_event_ent *
318 getauevnum(au_event_t event_number)
319 {
320         static char event_ent_name[AU_EVENT_NAME_MAX];
321         static char event_ent_desc[AU_EVENT_DESC_MAX];
322         static struct au_event_ent e;
323
324         bzero(&e, sizeof(e));
325         bzero(event_ent_name, sizeof(event_ent_name));
326         bzero(event_ent_desc, sizeof(event_ent_desc));
327         e.ae_name = event_ent_name;
328         e.ae_desc = event_ent_desc;
329         return (getauevnum_r(&e, event_number));
330 }
331
332 /*
333  * Search for an audit_event entry with a given event_name and returns the
334  * corresponding event number.
335  */
336 au_event_t *
337 getauevnonam_r(au_event_t *ev, const char *event_name)
338 {
339         static char event_ent_name[AU_EVENT_NAME_MAX];
340         static char event_ent_desc[AU_EVENT_DESC_MAX];
341         static struct au_event_ent e, *ep;
342
343         bzero(event_ent_name, sizeof(event_ent_name));
344         bzero(event_ent_desc, sizeof(event_ent_desc));
345         bzero(&e, sizeof(e));
346         e.ae_name = event_ent_name;
347         e.ae_desc = event_ent_desc;
348
349         ep = getauevnam_r(&e, event_name);
350         if (ep == NULL)
351                 return (NULL);
352
353         *ev = e.ae_number;
354         return (ev);
355 }
356
357 au_event_t *
358 getauevnonam(const char *event_name)
359 {
360         static au_event_t event;
361
362         return (getauevnonam_r(&event, event_name));
363 }