1185573Srwatson/*-
2185573Srwatson * Copyright (c) 2004 Apple Inc.
3155131Srwatson * Copyright (c) 2006 Robert N. M. Watson
4155131Srwatson * All rights reserved.
5155131Srwatson *
6155131Srwatson * Redistribution and use in source and binary forms, with or without
7155131Srwatson * modification, are permitted provided that the following conditions
8155131Srwatson * are met:
9155131Srwatson * 1.  Redistributions of source code must retain the above copyright
10155131Srwatson *     notice, this list of conditions and the following disclaimer.
11155131Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
12155131Srwatson *     notice, this list of conditions and the following disclaimer in the
13155131Srwatson *     documentation and/or other materials provided with the distribution.
14185573Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15155131Srwatson *     its contributors may be used to endorse or promote products derived
16155131Srwatson *     from this software without specific prior written permission.
17155131Srwatson *
18155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
19155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
22155131Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26155131Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27155131Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28155131Srwatson * POSSIBILITY OF SUCH DAMAGE.
29155131Srwatson *
30186647Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#17 $
31155131Srwatson */
32155131Srwatson
33185573Srwatson#include <config/config.h>
34185573Srwatson
35155131Srwatson#include <bsm/libbsm.h>
36155131Srwatson
37155131Srwatson#include <string.h>
38186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
39155131Srwatson#include <pthread.h>
40186647Srwatson#endif
41155131Srwatson#include <stdio.h>
42155131Srwatson#include <stdlib.h>
43155131Srwatson
44185573Srwatson#ifndef HAVE_STRLCPY
45185573Srwatson#include <compat/strlcpy.h>
46185573Srwatson#endif
47185573Srwatson
48185573Srwatson
49155131Srwatson/*
50155131Srwatson * Parse the contents of the audit_event file to return
51155131Srwatson * au_event_ent entries
52155131Srwatson */
53155131Srwatsonstatic FILE		*fp = NULL;
54155131Srwatsonstatic char		 linestr[AU_LINE_MAX];
55155131Srwatsonstatic const char	*eventdelim = ":";
56155131Srwatson
57186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
58155131Srwatsonstatic pthread_mutex_t	mutex = PTHREAD_MUTEX_INITIALIZER;
59186647Srwatson#endif
60155131Srwatson
61155131Srwatson/*
62155131Srwatson * Parse one line from the audit_event file into the au_event_ent structure.
63155131Srwatson */
64155131Srwatsonstatic struct au_event_ent *
65155131Srwatsoneventfromstr(char *str, struct au_event_ent *e)
66155131Srwatson{
67155131Srwatson	char *evno, *evname, *evdesc, *evclass;
68155131Srwatson	struct au_mask evmask;
69155131Srwatson	char *last;
70155131Srwatson
71155131Srwatson	evno = strtok_r(str, eventdelim, &last);
72155131Srwatson	evname = strtok_r(NULL, eventdelim, &last);
73155131Srwatson	evdesc = strtok_r(NULL, eventdelim, &last);
74155131Srwatson	evclass = strtok_r(NULL, eventdelim, &last);
75155131Srwatson
76161630Srwatson	if ((evno == NULL) || (evname == NULL))
77155131Srwatson		return (NULL);
78155131Srwatson
79155131Srwatson	if (strlen(evname) >= AU_EVENT_NAME_MAX)
80155131Srwatson		return (NULL);
81155131Srwatson
82185573Srwatson	strlcpy(e->ae_name, evname, AU_EVENT_NAME_MAX);
83161630Srwatson	if (evdesc != NULL) {
84161630Srwatson		if (strlen(evdesc) >= AU_EVENT_DESC_MAX)
85161630Srwatson			return (NULL);
86185573Srwatson		strlcpy(e->ae_desc, evdesc, AU_EVENT_DESC_MAX);
87161630Srwatson	} else
88185573Srwatson		strlcpy(e->ae_desc, "", AU_EVENT_DESC_MAX);
89155131Srwatson
90155131Srwatson	e->ae_number = atoi(evno);
91155131Srwatson
92155131Srwatson	/*
93155131Srwatson	 * Find out the mask that corresponds to the given list of classes.
94155131Srwatson	 */
95161630Srwatson	if (evclass != NULL) {
96161630Srwatson		if (getauditflagsbin(evclass, &evmask) != 0)
97173143Srwatson			e->ae_class = 0;
98161630Srwatson		else
99161630Srwatson			e->ae_class = evmask.am_success;
100161630Srwatson	} else
101173143Srwatson		e->ae_class = 0;
102155131Srwatson
103155131Srwatson	return (e);
104155131Srwatson}
105155131Srwatson
106155131Srwatson/*
107155131Srwatson * Rewind the audit_event file.
108155131Srwatson */
109155131Srwatsonstatic void
110155131Srwatsonsetauevent_locked(void)
111155131Srwatson{
112155131Srwatson
113155131Srwatson	if (fp != NULL)
114155131Srwatson		fseek(fp, 0, SEEK_SET);
115155131Srwatson}
116155131Srwatson
117155131Srwatsonvoid
118155131Srwatsonsetauevent(void)
119155131Srwatson{
120155131Srwatson
121186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
122155131Srwatson	pthread_mutex_lock(&mutex);
123186647Srwatson#endif
124155131Srwatson	setauevent_locked();
125186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
126155131Srwatson	pthread_mutex_unlock(&mutex);
127186647Srwatson#endif
128155131Srwatson}
129155131Srwatson
130155131Srwatson/*
131155131Srwatson * Close the open file pointers.
132155131Srwatson */
133155131Srwatsonvoid
134155131Srwatsonendauevent(void)
135155131Srwatson{
136155131Srwatson
137186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
138155131Srwatson	pthread_mutex_lock(&mutex);
139186647Srwatson#endif
140155131Srwatson	if (fp != NULL) {
141155131Srwatson		fclose(fp);
142155131Srwatson		fp = NULL;
143155131Srwatson	}
144186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
145155131Srwatson	pthread_mutex_unlock(&mutex);
146186647Srwatson#endif
147155131Srwatson}
148155131Srwatson
149155131Srwatson/*
150155131Srwatson * Enumerate the au_event_ent entries.
151155131Srwatson */
152155131Srwatsonstatic struct au_event_ent *
153155131Srwatsongetauevent_r_locked(struct au_event_ent *e)
154155131Srwatson{
155155131Srwatson	char *nl;
156155131Srwatson
157155131Srwatson	if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
158155131Srwatson		return (NULL);
159155131Srwatson
160155131Srwatson	while (1) {
161155131Srwatson		if (fgets(linestr, AU_LINE_MAX, fp) == NULL)
162155131Srwatson			return (NULL);
163155131Srwatson
164155131Srwatson		/* Remove new lines. */
165155131Srwatson		if ((nl = strrchr(linestr, '\n')) != NULL)
166155131Srwatson			*nl = '\0';
167155131Srwatson
168155131Srwatson		/* Skip comments. */
169155131Srwatson		if (linestr[0] == '#')
170155131Srwatson			continue;
171155131Srwatson
172155131Srwatson		/* Get the next event structure. */
173155131Srwatson		if (eventfromstr(linestr, e) == NULL)
174155131Srwatson			return (NULL);
175155131Srwatson		break;
176155131Srwatson	}
177155131Srwatson
178155131Srwatson	return (e);
179155131Srwatson}
180155131Srwatson
181155131Srwatsonstruct au_event_ent *
182155131Srwatsongetauevent_r(struct au_event_ent *e)
183155131Srwatson{
184155131Srwatson	struct au_event_ent *ep;
185155131Srwatson
186186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
187155131Srwatson	pthread_mutex_lock(&mutex);
188186647Srwatson#endif
189155131Srwatson	ep = getauevent_r_locked(e);
190186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
191155131Srwatson	pthread_mutex_unlock(&mutex);
192186647Srwatson#endif
193155131Srwatson	return (ep);
194155131Srwatson}
195155131Srwatson
196155131Srwatsonstruct au_event_ent *
197155131Srwatsongetauevent(void)
198155131Srwatson{
199155131Srwatson	static char event_ent_name[AU_EVENT_NAME_MAX];
200155131Srwatson	static char event_ent_desc[AU_EVENT_DESC_MAX];
201155131Srwatson	static struct au_event_ent e;
202155131Srwatson
203155131Srwatson	bzero(&e, sizeof(e));
204155131Srwatson	bzero(event_ent_name, sizeof(event_ent_name));
205155131Srwatson	bzero(event_ent_desc, sizeof(event_ent_desc));
206155131Srwatson	e.ae_name = event_ent_name;
207155131Srwatson	e.ae_desc = event_ent_desc;
208155131Srwatson	return (getauevent_r(&e));
209155131Srwatson}
210155131Srwatson
211155131Srwatson/*
212155131Srwatson * Search for an audit event structure having the given event name.
213155131Srwatson *
214155131Srwatson * XXXRW: Why accept NULL name?
215155131Srwatson */
216155131Srwatsonstatic struct au_event_ent *
217155131Srwatsongetauevnam_r_locked(struct au_event_ent *e, const char *name)
218155131Srwatson{
219155131Srwatson	char *nl;
220155131Srwatson
221155131Srwatson	if (name == NULL)
222155131Srwatson		return (NULL);
223155131Srwatson
224155131Srwatson	/* Rewind to beginning of the file. */
225155131Srwatson	setauevent_locked();
226155131Srwatson
227155131Srwatson	if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
228155131Srwatson		return (NULL);
229155131Srwatson
230155131Srwatson	while (fgets(linestr, AU_LINE_MAX, fp) != NULL) {
231155131Srwatson		/* Remove new lines. */
232155131Srwatson		if ((nl = strrchr(linestr, '\n')) != NULL)
233155131Srwatson			*nl = '\0';
234155131Srwatson
235155131Srwatson		if (eventfromstr(linestr, e) != NULL) {
236155131Srwatson			if (strcmp(name, e->ae_name) == 0)
237155131Srwatson				return (e);
238155131Srwatson		}
239155131Srwatson	}
240155131Srwatson
241155131Srwatson	return (NULL);
242155131Srwatson}
243155131Srwatson
244155131Srwatsonstruct au_event_ent *
245155131Srwatsongetauevnam_r(struct au_event_ent *e, const char *name)
246155131Srwatson{
247155131Srwatson	struct au_event_ent *ep;
248155131Srwatson
249186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
250155131Srwatson	pthread_mutex_lock(&mutex);
251186647Srwatson#endif
252155131Srwatson	ep = getauevnam_r_locked(e, name);
253186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
254155131Srwatson	pthread_mutex_unlock(&mutex);
255186647Srwatson#endif
256155131Srwatson	return (ep);
257155131Srwatson}
258155131Srwatson
259155131Srwatsonstruct au_event_ent *
260155131Srwatsongetauevnam(const char *name)
261155131Srwatson{
262155131Srwatson	static char event_ent_name[AU_EVENT_NAME_MAX];
263155131Srwatson	static char event_ent_desc[AU_EVENT_DESC_MAX];
264155131Srwatson	static struct au_event_ent e;
265155131Srwatson
266155131Srwatson	bzero(&e, sizeof(e));
267155131Srwatson	bzero(event_ent_name, sizeof(event_ent_name));
268155131Srwatson	bzero(event_ent_desc, sizeof(event_ent_desc));
269155131Srwatson	e.ae_name = event_ent_name;
270155131Srwatson	e.ae_desc = event_ent_desc;
271155131Srwatson	return (getauevnam_r(&e, name));
272155131Srwatson}
273155131Srwatson
274155131Srwatson/*
275155131Srwatson * Search for an audit event structure having the given event number.
276155131Srwatson */
277155131Srwatsonstatic struct au_event_ent *
278155131Srwatsongetauevnum_r_locked(struct au_event_ent *e, au_event_t event_number)
279155131Srwatson{
280155131Srwatson	char *nl;
281155131Srwatson
282155131Srwatson	/* Rewind to beginning of the file. */
283155131Srwatson	setauevent_locked();
284155131Srwatson
285155131Srwatson	if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL))
286155131Srwatson		return (NULL);
287155131Srwatson
288155131Srwatson	while (fgets(linestr, AU_LINE_MAX, fp) != NULL) {
289155131Srwatson		/* Remove new lines. */
290155131Srwatson		if ((nl = strrchr(linestr, '\n')) != NULL)
291155131Srwatson			*nl = '\0';
292155131Srwatson
293155131Srwatson		if (eventfromstr(linestr, e) != NULL) {
294155131Srwatson			if (event_number == e->ae_number)
295155131Srwatson				return (e);
296155131Srwatson		}
297155131Srwatson	}
298155131Srwatson
299155131Srwatson	return (NULL);
300155131Srwatson}
301155131Srwatson
302155131Srwatsonstruct au_event_ent *
303155131Srwatsongetauevnum_r(struct au_event_ent *e, au_event_t event_number)
304155131Srwatson{
305155131Srwatson	struct au_event_ent *ep;
306155131Srwatson
307186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
308155131Srwatson	pthread_mutex_lock(&mutex);
309186647Srwatson#endif
310155131Srwatson	ep = getauevnum_r_locked(e, event_number);
311186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK
312155131Srwatson	pthread_mutex_unlock(&mutex);
313186647Srwatson#endif
314155131Srwatson	return (ep);
315155131Srwatson}
316155131Srwatson
317155131Srwatsonstruct au_event_ent *
318155131Srwatsongetauevnum(au_event_t event_number)
319155131Srwatson{
320155131Srwatson	static char event_ent_name[AU_EVENT_NAME_MAX];
321155131Srwatson	static char event_ent_desc[AU_EVENT_DESC_MAX];
322155131Srwatson	static struct au_event_ent e;
323155131Srwatson
324155131Srwatson	bzero(&e, sizeof(e));
325155131Srwatson	bzero(event_ent_name, sizeof(event_ent_name));
326155131Srwatson	bzero(event_ent_desc, sizeof(event_ent_desc));
327155131Srwatson	e.ae_name = event_ent_name;
328155131Srwatson	e.ae_desc = event_ent_desc;
329155131Srwatson	return (getauevnum_r(&e, event_number));
330155131Srwatson}
331155131Srwatson
332155131Srwatson/*
333155131Srwatson * Search for an audit_event entry with a given event_name and returns the
334155131Srwatson * corresponding event number.
335155131Srwatson */
336155131Srwatsonau_event_t *
337155131Srwatsongetauevnonam_r(au_event_t *ev, const char *event_name)
338155131Srwatson{
339155131Srwatson	static char event_ent_name[AU_EVENT_NAME_MAX];
340155131Srwatson	static char event_ent_desc[AU_EVENT_DESC_MAX];
341155131Srwatson	static struct au_event_ent e, *ep;
342155131Srwatson
343155131Srwatson	bzero(event_ent_name, sizeof(event_ent_name));
344155131Srwatson	bzero(event_ent_desc, sizeof(event_ent_desc));
345155131Srwatson	bzero(&e, sizeof(e));
346155131Srwatson	e.ae_name = event_ent_name;
347155131Srwatson	e.ae_desc = event_ent_desc;
348155131Srwatson
349155131Srwatson	ep = getauevnam_r(&e, event_name);
350155131Srwatson	if (ep == NULL)
351155131Srwatson		return (NULL);
352155131Srwatson
353155131Srwatson	*ev = e.ae_number;
354155131Srwatson	return (ev);
355155131Srwatson}
356155131Srwatson
357155131Srwatsonau_event_t *
358155131Srwatsongetauevnonam(const char *event_name)
359155131Srwatson{
360155131Srwatson	static au_event_t event;
361155131Srwatson
362155131Srwatson	return (getauevnonam_r(&event, event_name));
363155131Srwatson}
364