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