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