bsm_event.c revision 185573
162587Sitojun/*- 278064Sume * Copyright (c) 2004 Apple Inc. 362587Sitojun * Copyright (c) 2006 Robert N. M. Watson 453541Sshin * All rights reserved. 553541Sshin * 653541Sshin * Redistribution and use in source and binary forms, with or without 753541Sshin * modification, are permitted provided that the following conditions 853541Sshin * are met: 953541Sshin * 1. Redistributions of source code must retain the above copyright 1053541Sshin * notice, this list of conditions and the following disclaimer. 1153541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1253541Sshin * notice, this list of conditions and the following disclaimer in the 1353541Sshin * documentation and/or other materials provided with the distribution. 1453541Sshin * 3. Neither the name of Apple Inc. ("Apple") nor the names of 1553541Sshin * its contributors may be used to endorse or promote products derived 1653541Sshin * from this software without specific prior written permission. 1753541Sshin * 1853541Sshin * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 1953541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2053541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2153541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 2253541Sshin * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2353541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2453541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2553541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2653541Sshin * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2753541Sshin * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2853541Sshin * POSSIBILITY OF SUCH DAMAGE. 2953541Sshin * 3053541Sshin * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#16 $ 3153541Sshin */ 3253541Sshin 3353541Sshin#include <config/config.h> 3453541Sshin 3553541Sshin#include <bsm/libbsm.h> 3653541Sshin 3753541Sshin#include <string.h> 3853541Sshin#include <pthread.h> 3978064Sume#include <stdio.h> 4053541Sshin#include <stdlib.h> 4153541Sshin 4253541Sshin#ifndef HAVE_STRLCPY 4353541Sshin#include <compat/strlcpy.h> 4453541Sshin#endif 4553541Sshin 4653541Sshin 4753541Sshin/* 4853541Sshin * Parse the contents of the audit_event file to return 4953541Sshin * au_event_ent entries 5081127Sume */ 5153541Sshinstatic FILE *fp = NULL; 5262587Sitojunstatic char linestr[AU_LINE_MAX]; 5353541Sshinstatic const char *eventdelim = ":"; 5478064Sume 5581127Sumestatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 5653541Sshin 5753541Sshin/* 5853541Sshin * Parse one line from the audit_event file into the au_event_ent structure. 5962587Sitojun */ 6053541Sshinstatic struct au_event_ent * 6153541Sshineventfromstr(char *str, struct au_event_ent *e) 6253541Sshin{ 6362587Sitojun char *evno, *evname, *evdesc, *evclass; 6453541Sshin struct au_mask evmask; 6578064Sume char *last; 6678064Sume 6778064Sume evno = strtok_r(str, eventdelim, &last); 6878064Sume evname = strtok_r(NULL, eventdelim, &last); 6978064Sume evdesc = strtok_r(NULL, eventdelim, &last); 7078064Sume evclass = strtok_r(NULL, eventdelim, &last); 7178064Sume 7278064Sume if ((evno == NULL) || (evname == NULL)) 7381127Sume return (NULL); 7481127Sume 7581127Sume if (strlen(evname) >= AU_EVENT_NAME_MAX) 7662587Sitojun return (NULL); 7778064Sume 7862587Sitojun strlcpy(e->ae_name, evname, AU_EVENT_NAME_MAX); 7962587Sitojun if (evdesc != NULL) { 8062587Sitojun if (strlen(evdesc) >= AU_EVENT_DESC_MAX) 8162587Sitojun return (NULL); 8253541Sshin strlcpy(e->ae_desc, evdesc, AU_EVENT_DESC_MAX); 8362587Sitojun } else 8462587Sitojun strlcpy(e->ae_desc, "", AU_EVENT_DESC_MAX); 8562587Sitojun 8662587Sitojun e->ae_number = atoi(evno); 8762587Sitojun 8862587Sitojun /* 8962587Sitojun * Find out the mask that corresponds to the given list of classes. 9053541Sshin */ 9162587Sitojun if (evclass != NULL) { 9262587Sitojun if (getauditflagsbin(evclass, &evmask) != 0) 9353541Sshin e->ae_class = 0; 9453541Sshin else 9553541Sshin e->ae_class = evmask.am_success; 9653541Sshin } else 9762587Sitojun e->ae_class = 0; 9862587Sitojun 9962587Sitojun return (e); 10053541Sshin} 10153541Sshin 10262587Sitojun/* 10362587Sitojun * Rewind the audit_event file. 10495023Ssuz */ 10553541Sshinstatic void 10653541Sshinsetauevent_locked(void) 10753541Sshin{ 10853541Sshin 10953541Sshin if (fp != NULL) 11062587Sitojun fseek(fp, 0, SEEK_SET); 11162587Sitojun} 11262587Sitojun 11362587Sitojunvoid 11462587Sitojunsetauevent(void) 11562587Sitojun{ 11662587Sitojun 11753541Sshin pthread_mutex_lock(&mutex); 11853541Sshin setauevent_locked(); 11953541Sshin pthread_mutex_unlock(&mutex); 12053541Sshin} 12153541Sshin 12262587Sitojun/* 12362587Sitojun * Close the open file pointers. 12453541Sshin */ 12553541Sshinvoid 12662587Sitojunendauevent(void) 12762587Sitojun{ 12853541Sshin 12962587Sitojun pthread_mutex_lock(&mutex); 13062587Sitojun if (fp != NULL) { 13162587Sitojun fclose(fp); 13253541Sshin fp = NULL; 13353541Sshin } 13453541Sshin pthread_mutex_unlock(&mutex); 13578064Sume} 13678064Sume 13778064Sume/* 13878064Sume * Enumerate the au_event_ent entries. 13978064Sume */ 14078064Sumestatic struct au_event_ent * 14178064Sumegetauevent_r_locked(struct au_event_ent *e) 14278064Sume{ 14378064Sume char *nl; 14478064Sume 14578064Sume if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 14678064Sume return (NULL); 14778064Sume 14878064Sume while (1) { 14978064Sume if (fgets(linestr, AU_LINE_MAX, fp) == NULL) 15078064Sume return (NULL); 15178064Sume 15278064Sume /* Remove new lines. */ 15378064Sume if ((nl = strrchr(linestr, '\n')) != NULL) 15478064Sume *nl = '\0'; 155120913Sume 15678064Sume /* Skip comments. */ 15778064Sume if (linestr[0] == '#') 15878064Sume continue; 15978064Sume 16078064Sume /* Get the next event structure. */ 16178064Sume if (eventfromstr(linestr, e) == NULL) 16278064Sume return (NULL); 16378064Sume break; 16478064Sume } 16578064Sume 16678064Sume return (e); 16778064Sume} 16878064Sume 16978064Sumestruct au_event_ent * 17078064Sumegetauevent_r(struct au_event_ent *e) 17178064Sume{ 17278064Sume struct au_event_ent *ep; 17378064Sume 17478064Sume pthread_mutex_lock(&mutex); 17578064Sume ep = getauevent_r_locked(e); 17678064Sume pthread_mutex_unlock(&mutex); 17778064Sume return (ep); 17878064Sume} 17978064Sume 18078064Sumestruct au_event_ent * 18178064Sumegetauevent(void) 18278064Sume{ 18378064Sume static char event_ent_name[AU_EVENT_NAME_MAX]; 18478064Sume static char event_ent_desc[AU_EVENT_DESC_MAX]; 18578064Sume static struct au_event_ent e; 18678064Sume 18778064Sume bzero(&e, sizeof(e)); 18878064Sume bzero(event_ent_name, sizeof(event_ent_name)); 18978064Sume bzero(event_ent_desc, sizeof(event_ent_desc)); 19078064Sume e.ae_name = event_ent_name; 19178064Sume e.ae_desc = event_ent_desc; 19278064Sume return (getauevent_r(&e)); 19378064Sume} 19478064Sume 19578064Sume/* 19678064Sume * Search for an audit event structure having the given event name. 19778064Sume * 19878064Sume * XXXRW: Why accept NULL name? 19978064Sume */ 20078064Sumestatic struct au_event_ent * 20178064Sumegetauevnam_r_locked(struct au_event_ent *e, const char *name) 20278064Sume{ 203120913Sume char *nl; 20478064Sume 20578064Sume if (name == NULL) 20678064Sume return (NULL); 20778064Sume 20878064Sume /* Rewind to beginning of the file. */ 20978064Sume setauevent_locked(); 21078064Sume 21178064Sume if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 21278064Sume return (NULL); 21378064Sume 21478064Sume while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { 21578064Sume /* Remove new lines. */ 21678064Sume if ((nl = strrchr(linestr, '\n')) != NULL) 21778064Sume *nl = '\0'; 21878064Sume 21953541Sshin if (eventfromstr(linestr, e) != NULL) { 22062587Sitojun if (strcmp(name, e->ae_name) == 0) 22162587Sitojun return (e); 22253541Sshin } 22362587Sitojun } 22462587Sitojun 22562587Sitojun return (NULL); 22695023Ssuz} 22753541Sshin 22853541Sshinstruct au_event_ent * 22953541Sshingetauevnam_r(struct au_event_ent *e, const char *name) 23062587Sitojun{ 23162587Sitojun struct au_event_ent *ep; 23262587Sitojun 23362587Sitojun pthread_mutex_lock(&mutex); 23462587Sitojun ep = getauevnam_r_locked(e, name); 23553541Sshin pthread_mutex_unlock(&mutex); 23662587Sitojun return (ep); 23762587Sitojun} 238120913Sume 23962587Sitojunstruct au_event_ent * 24053541Sshingetauevnam(const char *name) 24162587Sitojun{ 24262587Sitojun static char event_ent_name[AU_EVENT_NAME_MAX]; 24362587Sitojun static char event_ent_desc[AU_EVENT_DESC_MAX]; 24462587Sitojun static struct au_event_ent e; 24562587Sitojun 24662587Sitojun bzero(&e, sizeof(e)); 24762587Sitojun bzero(event_ent_name, sizeof(event_ent_name)); 24853541Sshin bzero(event_ent_desc, sizeof(event_ent_desc)); 24953541Sshin e.ae_name = event_ent_name; 25062587Sitojun e.ae_desc = event_ent_desc; 25162587Sitojun return (getauevnam_r(&e, name)); 25253541Sshin} 25362587Sitojun 25462587Sitojun/* 25553541Sshin * Search for an audit event structure having the given event number. 25662587Sitojun */ 25762587Sitojunstatic struct au_event_ent * 25862587Sitojungetauevnum_r_locked(struct au_event_ent *e, au_event_t event_number) 25962587Sitojun{ 260120049Smdodd char *nl; 26162587Sitojun 26278064Sume /* Rewind to beginning of the file. */ 26378064Sume setauevent_locked(); 26478064Sume 26578064Sume if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 26662587Sitojun return (NULL); 26778064Sume 26878064Sume while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { 26978064Sume /* Remove new lines. */ 27053541Sshin if ((nl = strrchr(linestr, '\n')) != NULL) 27162587Sitojun *nl = '\0'; 27262587Sitojun 27362587Sitojun if (eventfromstr(linestr, e) != NULL) { 27453541Sshin if (event_number == e->ae_number) 27562587Sitojun return (e); 27662587Sitojun } 27762587Sitojun } 27862587Sitojun 27962587Sitojun return (NULL); 28062587Sitojun} 28162587Sitojun 28262587Sitojunstruct au_event_ent * 28362587Sitojungetauevnum_r(struct au_event_ent *e, au_event_t event_number) 28462587Sitojun{ 28562587Sitojun struct au_event_ent *ep; 28662587Sitojun 28762587Sitojun pthread_mutex_lock(&mutex); 28862587Sitojun ep = getauevnum_r_locked(e, event_number); 28962587Sitojun pthread_mutex_unlock(&mutex); 29062587Sitojun return (ep); 29162587Sitojun} 29262587Sitojun 29362587Sitojunstruct au_event_ent * 29462587Sitojungetauevnum(au_event_t event_number) 29562587Sitojun{ 29662587Sitojun static char event_ent_name[AU_EVENT_NAME_MAX]; 29762587Sitojun static char event_ent_desc[AU_EVENT_DESC_MAX]; 29862587Sitojun static struct au_event_ent e; 29962587Sitojun 30062587Sitojun bzero(&e, sizeof(e)); 30162587Sitojun bzero(event_ent_name, sizeof(event_ent_name)); 30262587Sitojun bzero(event_ent_desc, sizeof(event_ent_desc)); 30362587Sitojun e.ae_name = event_ent_name; 30462587Sitojun e.ae_desc = event_ent_desc; 30562587Sitojun return (getauevnum_r(&e, event_number)); 30662587Sitojun} 30762587Sitojun 30862587Sitojun/* 30962587Sitojun * Search for an audit_event entry with a given event_name and returns the 31062587Sitojun * corresponding event number. 31162587Sitojun */ 31262587Sitojunau_event_t * 31362587Sitojungetauevnonam_r(au_event_t *ev, const char *event_name) 31462587Sitojun{ 31562587Sitojun static char event_ent_name[AU_EVENT_NAME_MAX]; 31662587Sitojun static char event_ent_desc[AU_EVENT_DESC_MAX]; 31762587Sitojun static struct au_event_ent e, *ep; 31862587Sitojun 31953541Sshin bzero(event_ent_name, sizeof(event_ent_name)); 32062587Sitojun bzero(event_ent_desc, sizeof(event_ent_desc)); 32178064Sume bzero(&e, sizeof(e)); 32262587Sitojun e.ae_name = event_ent_name; 32362587Sitojun e.ae_desc = event_ent_desc; 32462587Sitojun 32562587Sitojun ep = getauevnam_r(&e, event_name); 32662587Sitojun if (ep == NULL) 32762587Sitojun return (NULL); 32862587Sitojun 32962587Sitojun *ev = e.ae_number; 33053541Sshin return (ev); 33162587Sitojun} 33262587Sitojun 33362587Sitojunau_event_t * 33462587Sitojungetauevnonam(const char *event_name) 33562587Sitojun{ 33662587Sitojun static au_event_t event; 33762587Sitojun 33862587Sitojun return (getauevnonam_r(&event, event_name)); 33962587Sitojun} 34062587Sitojun