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 * 3022ccb20dSRobert Watson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_event.c#12 $ 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 6522ccb20dSRobert Watson if ((evno == NULL) || (evname == NULL)) 66ca0716f5SRobert Watson return (NULL); 67ca0716f5SRobert Watson 68ca0716f5SRobert Watson if (strlen(evname) >= AU_EVENT_NAME_MAX) 69ca0716f5SRobert Watson return (NULL); 70ca0716f5SRobert Watson 71ca0716f5SRobert Watson strcpy(e->ae_name, evname); 7222ccb20dSRobert Watson if (evdesc != NULL) { 73ca0716f5SRobert Watson if (strlen(evdesc) >= AU_EVENT_DESC_MAX) 74ca0716f5SRobert Watson return (NULL); 75ca0716f5SRobert Watson strcpy(e->ae_desc, evdesc); 7622ccb20dSRobert Watson } else 7722ccb20dSRobert Watson strcpy(e->ae_desc, ""); 78ca0716f5SRobert Watson 79ca0716f5SRobert Watson e->ae_number = atoi(evno); 80ca0716f5SRobert Watson 81ca0716f5SRobert Watson /* 82ca0716f5SRobert Watson * Find out the mask that corresponds to the given list of classes. 83ca0716f5SRobert Watson */ 8422ccb20dSRobert Watson if (evclass != NULL) { 85ca0716f5SRobert Watson if (getauditflagsbin(evclass, &evmask) != 0) 86ca0716f5SRobert Watson e->ae_class = AU_NULL; 87ca0716f5SRobert Watson else 88ca0716f5SRobert Watson e->ae_class = evmask.am_success; 8922ccb20dSRobert Watson } else 9022ccb20dSRobert Watson e->ae_class = AU_NULL; 91ca0716f5SRobert Watson 92ca0716f5SRobert Watson return (e); 93ca0716f5SRobert Watson } 94ca0716f5SRobert Watson 95ca0716f5SRobert Watson /* 96ca0716f5SRobert Watson * Rewind the audit_event file. 97ca0716f5SRobert Watson */ 98ca0716f5SRobert Watson static void 99ca0716f5SRobert Watson setauevent_locked(void) 100ca0716f5SRobert Watson { 101ca0716f5SRobert Watson 102ca0716f5SRobert Watson if (fp != NULL) 103ca0716f5SRobert Watson fseek(fp, 0, SEEK_SET); 104ca0716f5SRobert Watson } 105ca0716f5SRobert Watson 106ca0716f5SRobert Watson void 107ca0716f5SRobert Watson setauevent(void) 108ca0716f5SRobert Watson { 109ca0716f5SRobert Watson 110ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 111ca0716f5SRobert Watson setauevent_locked(); 112ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 113ca0716f5SRobert Watson } 114ca0716f5SRobert Watson 115ca0716f5SRobert Watson /* 116ca0716f5SRobert Watson * Close the open file pointers. 117ca0716f5SRobert Watson */ 118ca0716f5SRobert Watson void 119ca0716f5SRobert Watson endauevent(void) 120ca0716f5SRobert Watson { 121ca0716f5SRobert Watson 122ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 123ca0716f5SRobert Watson if (fp != NULL) { 124ca0716f5SRobert Watson fclose(fp); 125ca0716f5SRobert Watson fp = NULL; 126ca0716f5SRobert Watson } 127ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 128ca0716f5SRobert Watson } 129ca0716f5SRobert Watson 130ca0716f5SRobert Watson /* 131ca0716f5SRobert Watson * Enumerate the au_event_ent entries. 132ca0716f5SRobert Watson */ 133ca0716f5SRobert Watson static struct au_event_ent * 134ca0716f5SRobert Watson getauevent_r_locked(struct au_event_ent *e) 135ca0716f5SRobert Watson { 136ca0716f5SRobert Watson char *nl; 137ca0716f5SRobert Watson 138ca0716f5SRobert Watson if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 139ca0716f5SRobert Watson return (NULL); 140ca0716f5SRobert Watson 141ca0716f5SRobert Watson while (1) { 142ca0716f5SRobert Watson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) 143ca0716f5SRobert Watson return (NULL); 144ca0716f5SRobert Watson 145ca0716f5SRobert Watson /* Remove new lines. */ 146ca0716f5SRobert Watson if ((nl = strrchr(linestr, '\n')) != NULL) 147ca0716f5SRobert Watson *nl = '\0'; 148ca0716f5SRobert Watson 149ca0716f5SRobert Watson /* Skip comments. */ 150ca0716f5SRobert Watson if (linestr[0] == '#') 151ca0716f5SRobert Watson continue; 152ca0716f5SRobert Watson 153ca0716f5SRobert Watson /* Get the next event structure. */ 154ca0716f5SRobert Watson if (eventfromstr(linestr, e) == NULL) 155ca0716f5SRobert Watson return (NULL); 156ca0716f5SRobert Watson break; 157ca0716f5SRobert Watson } 158ca0716f5SRobert Watson 159ca0716f5SRobert Watson return (e); 160ca0716f5SRobert Watson } 161ca0716f5SRobert Watson 162ca0716f5SRobert Watson struct au_event_ent * 163ca0716f5SRobert Watson getauevent_r(struct au_event_ent *e) 164ca0716f5SRobert Watson { 165ca0716f5SRobert Watson struct au_event_ent *ep; 166ca0716f5SRobert Watson 167ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 168ca0716f5SRobert Watson ep = getauevent_r_locked(e); 169ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 170ca0716f5SRobert Watson return (ep); 171ca0716f5SRobert Watson } 172ca0716f5SRobert Watson 173ca0716f5SRobert Watson struct au_event_ent * 174ca0716f5SRobert Watson getauevent(void) 175ca0716f5SRobert Watson { 176ca0716f5SRobert Watson static char event_ent_name[AU_EVENT_NAME_MAX]; 177ca0716f5SRobert Watson static char event_ent_desc[AU_EVENT_DESC_MAX]; 178ca0716f5SRobert Watson static struct au_event_ent e; 179ca0716f5SRobert Watson 180ca0716f5SRobert Watson bzero(&e, sizeof(e)); 181ca0716f5SRobert Watson bzero(event_ent_name, sizeof(event_ent_name)); 182ca0716f5SRobert Watson bzero(event_ent_desc, sizeof(event_ent_desc)); 183ca0716f5SRobert Watson e.ae_name = event_ent_name; 184ca0716f5SRobert Watson e.ae_desc = event_ent_desc; 185ca0716f5SRobert Watson return (getauevent_r(&e)); 186ca0716f5SRobert Watson } 187ca0716f5SRobert Watson 188ca0716f5SRobert Watson /* 189ca0716f5SRobert Watson * Search for an audit event structure having the given event name. 190ca0716f5SRobert Watson * 191ca0716f5SRobert Watson * XXXRW: Why accept NULL name? 192ca0716f5SRobert Watson */ 193ca0716f5SRobert Watson static struct au_event_ent * 194ca0716f5SRobert Watson getauevnam_r_locked(struct au_event_ent *e, const char *name) 195ca0716f5SRobert Watson { 196ca0716f5SRobert Watson char *nl; 197ca0716f5SRobert Watson 198ca0716f5SRobert Watson if (name == NULL) 199ca0716f5SRobert Watson return (NULL); 200ca0716f5SRobert Watson 201ca0716f5SRobert Watson /* Rewind to beginning of the file. */ 202ca0716f5SRobert Watson setauevent_locked(); 203ca0716f5SRobert Watson 204ca0716f5SRobert Watson if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 205ca0716f5SRobert Watson return (NULL); 206ca0716f5SRobert Watson 207ca0716f5SRobert Watson while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { 208ca0716f5SRobert Watson /* Remove new lines. */ 209ca0716f5SRobert Watson if ((nl = strrchr(linestr, '\n')) != NULL) 210ca0716f5SRobert Watson *nl = '\0'; 211ca0716f5SRobert Watson 212ca0716f5SRobert Watson if (eventfromstr(linestr, e) != NULL) { 213ca0716f5SRobert Watson if (strcmp(name, e->ae_name) == 0) 214ca0716f5SRobert Watson return (e); 215ca0716f5SRobert Watson } 216ca0716f5SRobert Watson } 217ca0716f5SRobert Watson 218ca0716f5SRobert Watson return (NULL); 219ca0716f5SRobert Watson } 220ca0716f5SRobert Watson 221ca0716f5SRobert Watson struct au_event_ent * 222ca0716f5SRobert Watson getauevnam_r(struct au_event_ent *e, const char *name) 223ca0716f5SRobert Watson { 224ca0716f5SRobert Watson struct au_event_ent *ep; 225ca0716f5SRobert Watson 226ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 227ca0716f5SRobert Watson ep = getauevnam_r_locked(e, name); 228ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 229ca0716f5SRobert Watson return (ep); 230ca0716f5SRobert Watson } 231ca0716f5SRobert Watson 232ca0716f5SRobert Watson struct au_event_ent * 233ca0716f5SRobert Watson getauevnam(const char *name) 234ca0716f5SRobert Watson { 235ca0716f5SRobert Watson static char event_ent_name[AU_EVENT_NAME_MAX]; 236ca0716f5SRobert Watson static char event_ent_desc[AU_EVENT_DESC_MAX]; 237ca0716f5SRobert Watson static struct au_event_ent e; 238ca0716f5SRobert Watson 239ca0716f5SRobert Watson bzero(&e, sizeof(e)); 240ca0716f5SRobert Watson bzero(event_ent_name, sizeof(event_ent_name)); 241ca0716f5SRobert Watson bzero(event_ent_desc, sizeof(event_ent_desc)); 242ca0716f5SRobert Watson e.ae_name = event_ent_name; 243ca0716f5SRobert Watson e.ae_desc = event_ent_desc; 244ca0716f5SRobert Watson return (getauevnam_r(&e, name)); 245ca0716f5SRobert Watson } 246ca0716f5SRobert Watson 247ca0716f5SRobert Watson /* 248ca0716f5SRobert Watson * Search for an audit event structure having the given event number. 249ca0716f5SRobert Watson */ 250ca0716f5SRobert Watson static struct au_event_ent * 251ca0716f5SRobert Watson getauevnum_r_locked(struct au_event_ent *e, au_event_t event_number) 252ca0716f5SRobert Watson { 253ca0716f5SRobert Watson char *nl; 254ca0716f5SRobert Watson 255ca0716f5SRobert Watson /* Rewind to beginning of the file. */ 256ca0716f5SRobert Watson setauevent_locked(); 257ca0716f5SRobert Watson 258ca0716f5SRobert Watson if ((fp == NULL) && ((fp = fopen(AUDIT_EVENT_FILE, "r")) == NULL)) 259ca0716f5SRobert Watson return (NULL); 260ca0716f5SRobert Watson 261ca0716f5SRobert Watson while (fgets(linestr, AU_LINE_MAX, fp) != NULL) { 262ca0716f5SRobert Watson /* Remove new lines. */ 263ca0716f5SRobert Watson if ((nl = strrchr(linestr, '\n')) != NULL) 264ca0716f5SRobert Watson *nl = '\0'; 265ca0716f5SRobert Watson 266ca0716f5SRobert Watson if (eventfromstr(linestr, e) != NULL) { 267ca0716f5SRobert Watson if (event_number == e->ae_number) 268ca0716f5SRobert Watson return (e); 269ca0716f5SRobert Watson } 270ca0716f5SRobert Watson } 271ca0716f5SRobert Watson 272ca0716f5SRobert Watson return (NULL); 273ca0716f5SRobert Watson } 274ca0716f5SRobert Watson 275ca0716f5SRobert Watson struct au_event_ent * 276ca0716f5SRobert Watson getauevnum_r(struct au_event_ent *e, au_event_t event_number) 277ca0716f5SRobert Watson { 278ca0716f5SRobert Watson struct au_event_ent *ep; 279ca0716f5SRobert Watson 280ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 281ca0716f5SRobert Watson ep = getauevnum_r_locked(e, event_number); 282ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 283ca0716f5SRobert Watson return (ep); 284ca0716f5SRobert Watson } 285ca0716f5SRobert Watson 286ca0716f5SRobert Watson struct au_event_ent * 287ca0716f5SRobert Watson getauevnum(au_event_t event_number) 288ca0716f5SRobert Watson { 289ca0716f5SRobert Watson static char event_ent_name[AU_EVENT_NAME_MAX]; 290ca0716f5SRobert Watson static char event_ent_desc[AU_EVENT_DESC_MAX]; 291ca0716f5SRobert Watson static struct au_event_ent e; 292ca0716f5SRobert Watson 293ca0716f5SRobert Watson bzero(&e, sizeof(e)); 294ca0716f5SRobert Watson bzero(event_ent_name, sizeof(event_ent_name)); 295ca0716f5SRobert Watson bzero(event_ent_desc, sizeof(event_ent_desc)); 296ca0716f5SRobert Watson e.ae_name = event_ent_name; 297ca0716f5SRobert Watson e.ae_desc = event_ent_desc; 298ca0716f5SRobert Watson return (getauevnum_r(&e, event_number)); 299ca0716f5SRobert Watson } 300ca0716f5SRobert Watson 301ca0716f5SRobert Watson /* 302ca0716f5SRobert Watson * Search for an audit_event entry with a given event_name and returns the 303ca0716f5SRobert Watson * corresponding event number. 304ca0716f5SRobert Watson */ 305ca0716f5SRobert Watson au_event_t * 306ca0716f5SRobert Watson getauevnonam_r(au_event_t *ev, const char *event_name) 307ca0716f5SRobert Watson { 308ca0716f5SRobert Watson static char event_ent_name[AU_EVENT_NAME_MAX]; 309ca0716f5SRobert Watson static char event_ent_desc[AU_EVENT_DESC_MAX]; 310ca0716f5SRobert Watson static struct au_event_ent e, *ep; 311ca0716f5SRobert Watson 312ca0716f5SRobert Watson bzero(event_ent_name, sizeof(event_ent_name)); 313ca0716f5SRobert Watson bzero(event_ent_desc, sizeof(event_ent_desc)); 314ca0716f5SRobert Watson bzero(&e, sizeof(e)); 315ca0716f5SRobert Watson e.ae_name = event_ent_name; 316ca0716f5SRobert Watson e.ae_desc = event_ent_desc; 317ca0716f5SRobert Watson 318ca0716f5SRobert Watson ep = getauevnam_r(&e, event_name); 319ca0716f5SRobert Watson if (ep == NULL) 320ca0716f5SRobert Watson return (NULL); 321ca0716f5SRobert Watson 322ca0716f5SRobert Watson *ev = e.ae_number; 323ca0716f5SRobert Watson return (ev); 324ca0716f5SRobert Watson } 325ca0716f5SRobert Watson 326ca0716f5SRobert Watson au_event_t * 327ca0716f5SRobert Watson getauevnonam(const char *event_name) 328ca0716f5SRobert Watson { 329ca0716f5SRobert Watson static au_event_t event; 330ca0716f5SRobert Watson 331ca0716f5SRobert Watson return (getauevnonam_r(&event, event_name)); 332ca0716f5SRobert Watson } 333