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. 14243750Srwatson * 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 * 30243750Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_class.c#16 $ 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 48155131Srwatson/* 49155131Srwatson * Parse the contents of the audit_class file to return struct au_class_ent 50155131Srwatson * entries. 51155131Srwatson */ 52155131Srwatsonstatic FILE *fp = NULL; 53155131Srwatsonstatic char linestr[AU_LINE_MAX]; 54155131Srwatsonstatic const char *classdelim = ":"; 55155131Srwatson 56186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 57155131Srwatsonstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 58186647Srwatson#endif 59155131Srwatson 60155131Srwatson/* 61155131Srwatson * Parse a single line from the audit_class file passed in str to the struct 62155131Srwatson * au_class_ent elements; store the result in c. 63155131Srwatson */ 64155131Srwatsonstatic struct au_class_ent * 65155131Srwatsonclassfromstr(char *str, struct au_class_ent *c) 66155131Srwatson{ 67155131Srwatson char *classname, *classdesc, *classflag; 68155131Srwatson char *last; 69155131Srwatson 70155131Srwatson /* Each line contains flag:name:desc. */ 71155131Srwatson classflag = strtok_r(str, classdelim, &last); 72155131Srwatson classname = strtok_r(NULL, classdelim, &last); 73155131Srwatson classdesc = strtok_r(NULL, classdelim, &last); 74155131Srwatson 75155131Srwatson if ((classflag == NULL) || (classname == NULL) || (classdesc == NULL)) 76155131Srwatson return (NULL); 77155131Srwatson 78155131Srwatson /* 79155131Srwatson * Check for very large classnames. 80155131Srwatson */ 81155131Srwatson if (strlen(classname) >= AU_CLASS_NAME_MAX) 82155131Srwatson return (NULL); 83185573Srwatson strlcpy(c->ac_name, classname, AU_CLASS_NAME_MAX); 84155131Srwatson 85155131Srwatson /* 86155131Srwatson * Check for very large class description. 87155131Srwatson */ 88155131Srwatson if (strlen(classdesc) >= AU_CLASS_DESC_MAX) 89155131Srwatson return (NULL); 90185573Srwatson strlcpy(c->ac_desc, classdesc, AU_CLASS_DESC_MAX); 91155131Srwatson c->ac_class = strtoul(classflag, (char **) NULL, 0); 92155131Srwatson 93155131Srwatson return (c); 94155131Srwatson} 95155131Srwatson 96155131Srwatson/* 97155131Srwatson * Return the next au_class_ent structure from the file setauclass should be 98155131Srwatson * called before invoking this function for the first time. 99155131Srwatson * 100155131Srwatson * Must be called with mutex held. 101155131Srwatson */ 102155131Srwatsonstatic struct au_class_ent * 103155131Srwatsongetauclassent_r_locked(struct au_class_ent *c) 104155131Srwatson{ 105155131Srwatson char *tokptr, *nl; 106155131Srwatson 107155131Srwatson if ((fp == NULL) && ((fp = fopen(AUDIT_CLASS_FILE, "r")) == NULL)) 108155131Srwatson return (NULL); 109155131Srwatson 110155131Srwatson /* 111155131Srwatson * Read until next non-comment line is found, or EOF. 112155131Srwatson */ 113155131Srwatson while (1) { 114155131Srwatson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) 115155131Srwatson return (NULL); 116155131Srwatson 117155131Srwatson /* Skip comments. */ 118155131Srwatson if (linestr[0] == '#') 119155131Srwatson continue; 120155131Srwatson 121155131Srwatson /* Remove trailing new line character. */ 122155131Srwatson if ((nl = strrchr(linestr, '\n')) != NULL) 123155131Srwatson *nl = '\0'; 124155131Srwatson 125155131Srwatson /* Parse tokptr to au_class_ent components. */ 126155131Srwatson tokptr = linestr; 127155131Srwatson if (classfromstr(tokptr, c) == NULL) 128155131Srwatson return (NULL); 129155131Srwatson break; 130155131Srwatson } 131155131Srwatson 132155131Srwatson return (c); 133155131Srwatson} 134155131Srwatson 135155131Srwatsonstruct au_class_ent * 136155131Srwatsongetauclassent_r(struct au_class_ent *c) 137155131Srwatson{ 138155131Srwatson struct au_class_ent *cp; 139155131Srwatson 140186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 141155131Srwatson pthread_mutex_lock(&mutex); 142186647Srwatson#endif 143155131Srwatson cp = getauclassent_r_locked(c); 144186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 145155131Srwatson pthread_mutex_unlock(&mutex); 146186647Srwatson#endif 147155131Srwatson return (cp); 148155131Srwatson} 149155131Srwatson 150155131Srwatsonstruct au_class_ent * 151155131Srwatsongetauclassent(void) 152155131Srwatson{ 153155131Srwatson static char class_ent_name[AU_CLASS_NAME_MAX]; 154155131Srwatson static char class_ent_desc[AU_CLASS_DESC_MAX]; 155155131Srwatson static struct au_class_ent c, *cp; 156155131Srwatson 157155131Srwatson bzero(&c, sizeof(c)); 158155131Srwatson bzero(class_ent_name, sizeof(class_ent_name)); 159155131Srwatson bzero(class_ent_desc, sizeof(class_ent_desc)); 160155131Srwatson c.ac_name = class_ent_name; 161155131Srwatson c.ac_desc = class_ent_desc; 162155131Srwatson 163186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 164155131Srwatson pthread_mutex_lock(&mutex); 165186647Srwatson#endif 166155131Srwatson cp = getauclassent_r_locked(&c); 167186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 168155131Srwatson pthread_mutex_unlock(&mutex); 169186647Srwatson#endif 170155131Srwatson return (cp); 171155131Srwatson} 172155131Srwatson 173155131Srwatson/* 174155131Srwatson * Rewind to the beginning of the enumeration. 175155131Srwatson * 176155131Srwatson * Must be called with mutex held. 177155131Srwatson */ 178155131Srwatsonstatic void 179155131Srwatsonsetauclass_locked(void) 180155131Srwatson{ 181155131Srwatson 182155131Srwatson if (fp != NULL) 183155131Srwatson fseek(fp, 0, SEEK_SET); 184155131Srwatson} 185155131Srwatson 186155131Srwatsonvoid 187155131Srwatsonsetauclass(void) 188155131Srwatson{ 189155131Srwatson 190186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 191155131Srwatson pthread_mutex_lock(&mutex); 192186647Srwatson#endif 193155131Srwatson setauclass_locked(); 194186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 195155131Srwatson pthread_mutex_unlock(&mutex); 196186647Srwatson#endif 197155131Srwatson} 198155131Srwatson 199155131Srwatson/* 200155131Srwatson * Return the next au_class_entry having the given class name. 201155131Srwatson */ 202155131Srwatsonstruct au_class_ent * 203155131Srwatsongetauclassnam_r(struct au_class_ent *c, const char *name) 204155131Srwatson{ 205155131Srwatson struct au_class_ent *cp; 206155131Srwatson 207155131Srwatson if (name == NULL) 208155131Srwatson return (NULL); 209155131Srwatson 210186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 211155131Srwatson pthread_mutex_lock(&mutex); 212186647Srwatson#endif 213155131Srwatson setauclass_locked(); 214155131Srwatson while ((cp = getauclassent_r_locked(c)) != NULL) { 215155131Srwatson if (strcmp(name, cp->ac_name) == 0) { 216186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 217155131Srwatson pthread_mutex_unlock(&mutex); 218186647Srwatson#endif 219155131Srwatson return (cp); 220155131Srwatson } 221155131Srwatson } 222186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 223155131Srwatson pthread_mutex_unlock(&mutex); 224186647Srwatson#endif 225155131Srwatson return (NULL); 226155131Srwatson} 227155131Srwatson 228155131Srwatsonstruct au_class_ent * 229155131Srwatsongetauclassnam(const char *name) 230155131Srwatson{ 231155131Srwatson static char class_ent_name[AU_CLASS_NAME_MAX]; 232155131Srwatson static char class_ent_desc[AU_CLASS_DESC_MAX]; 233155131Srwatson static struct au_class_ent c; 234155131Srwatson 235155131Srwatson bzero(&c, sizeof(c)); 236155131Srwatson bzero(class_ent_name, sizeof(class_ent_name)); 237155131Srwatson bzero(class_ent_desc, sizeof(class_ent_desc)); 238155131Srwatson c.ac_name = class_ent_name; 239155131Srwatson c.ac_desc = class_ent_desc; 240155131Srwatson 241155131Srwatson return (getauclassnam_r(&c, name)); 242155131Srwatson} 243155131Srwatson 244155131Srwatson 245155131Srwatson/* 246155131Srwatson * Return the next au_class_entry having the given class number. 247155131Srwatson * 248155131Srwatson * OpenBSM extension. 249155131Srwatson */ 250155131Srwatsonstruct au_class_ent * 251155131Srwatsongetauclassnum_r(struct au_class_ent *c, au_class_t class_number) 252155131Srwatson{ 253155131Srwatson struct au_class_ent *cp; 254155131Srwatson 255186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 256155131Srwatson pthread_mutex_lock(&mutex); 257186647Srwatson#endif 258155131Srwatson setauclass_locked(); 259155131Srwatson while ((cp = getauclassent_r_locked(c)) != NULL) { 260155131Srwatson if (class_number == cp->ac_class) 261155131Srwatson return (cp); 262155131Srwatson } 263186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 264155131Srwatson pthread_mutex_unlock(&mutex); 265186647Srwatson#endif 266155131Srwatson return (NULL); 267155131Srwatson} 268155131Srwatson 269155131Srwatsonstruct au_class_ent * 270155131Srwatsongetauclassnum(au_class_t class_number) 271155131Srwatson{ 272155131Srwatson static char class_ent_name[AU_CLASS_NAME_MAX]; 273155131Srwatson static char class_ent_desc[AU_CLASS_DESC_MAX]; 274155131Srwatson static struct au_class_ent c; 275155131Srwatson 276155131Srwatson bzero(&c, sizeof(c)); 277155131Srwatson bzero(class_ent_name, sizeof(class_ent_name)); 278155131Srwatson bzero(class_ent_desc, sizeof(class_ent_desc)); 279155131Srwatson c.ac_name = class_ent_name; 280155131Srwatson c.ac_desc = class_ent_desc; 281155131Srwatson 282155131Srwatson return (getauclassnum_r(&c, class_number)); 283155131Srwatson} 284155131Srwatson 285155131Srwatson/* 286155131Srwatson * audit_class processing is complete; close any open files. 287155131Srwatson */ 288155131Srwatsonvoid 289155131Srwatsonendauclass(void) 290155131Srwatson{ 291155131Srwatson 292186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 293155131Srwatson pthread_mutex_lock(&mutex); 294186647Srwatson#endif 295155131Srwatson if (fp != NULL) { 296155131Srwatson fclose(fp); 297155131Srwatson fp = NULL; 298155131Srwatson } 299186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 300155131Srwatson pthread_mutex_unlock(&mutex); 301186647Srwatson#endif 302155131Srwatson} 303