1185573Srwatson/*- 2191273Srwatson * Copyright (c) 2004, 2009 Apple Inc. 3162503Srwatson * 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 */ 30155131Srwatson 31185573Srwatson#include <config/config.h> 32185573Srwatson 33155131Srwatson#include <bsm/libbsm.h> 34155131Srwatson 35189279Srwatson#include <ctype.h> 36155131Srwatson#include <errno.h> 37155131Srwatson#include <string.h> 38243750Srwatson#include <strings.h> 39186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 40155131Srwatson#include <pthread.h> 41186647Srwatson#endif 42155131Srwatson#include <stdio.h> 43155131Srwatson#include <stdlib.h> 44155131Srwatson 45162503Srwatson#ifndef HAVE_STRLCAT 46162503Srwatson#include <compat/strlcat.h> 47162503Srwatson#endif 48185573Srwatson#ifndef HAVE_STRLCPY 49185573Srwatson#include <compat/strlcpy.h> 50185573Srwatson#endif 51162503Srwatson 52191273Srwatson#include <sys/stat.h> 53191273Srwatson 54155131Srwatson/* 55155131Srwatson * Parse the contents of the audit_control file to return the audit control 56162503Srwatson * parameters. These static fields are protected by 'mutex'. 57155131Srwatson */ 58155131Srwatsonstatic FILE *fp = NULL; 59155131Srwatsonstatic char linestr[AU_LINE_MAX]; 60155131Srwatsonstatic char *delim = ":"; 61155131Srwatson 62155131Srwatsonstatic char inacdir = 0; 63155131Srwatsonstatic char ptrmoved = 0; 64155131Srwatson 65186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 66155131Srwatsonstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 67186647Srwatson#endif 68155131Srwatson 69155131Srwatson/* 70189279Srwatson * Audit policy string token table for au_poltostr() and au_strtopol(). 71189279Srwatson */ 72189279Srwatsonstruct audit_polstr { 73243750Srwatson long ap_policy; 74243750Srwatson const char *ap_str; 75189279Srwatson}; 76189279Srwatson 77189279Srwatsonstatic struct audit_polstr au_polstr[] = { 78189279Srwatson { AUDIT_CNT, "cnt" }, 79189279Srwatson { AUDIT_AHLT, "ahlt" }, 80189279Srwatson { AUDIT_ARGV, "argv" }, 81189279Srwatson { AUDIT_ARGE, "arge" }, 82189279Srwatson { AUDIT_SEQ, "seq" }, 83189279Srwatson { AUDIT_WINDATA, "windata" }, 84189279Srwatson { AUDIT_USER, "user" }, 85189279Srwatson { AUDIT_GROUP, "group" }, 86189279Srwatson { AUDIT_TRAIL, "trail" }, 87189279Srwatson { AUDIT_PATH, "path" }, 88189279Srwatson { AUDIT_SCNT, "scnt" }, 89189279Srwatson { AUDIT_PUBLIC, "public" }, 90189279Srwatson { AUDIT_ZONENAME, "zonename" }, 91189279Srwatson { AUDIT_PERZONE, "perzone" }, 92189279Srwatson { -1, NULL } 93189279Srwatson}; 94189279Srwatson 95189279Srwatson/* 96155131Srwatson * Returns the string value corresponding to the given label from the 97155131Srwatson * configuration file. 98155131Srwatson * 99155131Srwatson * Must be called with mutex held. 100155131Srwatson */ 101155131Srwatsonstatic int 102243750Srwatsongetstrfromtype_locked(const char *name, char **str) 103155131Srwatson{ 104155131Srwatson char *type, *nl; 105155131Srwatson char *tokptr; 106155131Srwatson char *last; 107155131Srwatson 108155131Srwatson *str = NULL; 109155131Srwatson 110155131Srwatson if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL)) 111155131Srwatson return (-1); /* Error */ 112155131Srwatson 113155131Srwatson while (1) { 114155131Srwatson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) { 115155131Srwatson if (ferror(fp)) 116155131Srwatson return (-1); 117155131Srwatson return (0); /* EOF */ 118155131Srwatson } 119155131Srwatson 120155131Srwatson if (linestr[0] == '#') 121155131Srwatson continue; 122155131Srwatson 123195740Srwatson /* Remove trailing new line character and white space. */ 124195740Srwatson nl = strchr(linestr, '\0') - 1; 125195740Srwatson while (nl >= linestr && ('\n' == *nl || ' ' == *nl || 126195740Srwatson '\t' == *nl)) { 127155131Srwatson *nl = '\0'; 128195740Srwatson nl--; 129195740Srwatson } 130155131Srwatson 131155131Srwatson tokptr = linestr; 132155131Srwatson if ((type = strtok_r(tokptr, delim, &last)) != NULL) { 133155131Srwatson if (strcmp(name, type) == 0) { 134155131Srwatson /* Found matching name. */ 135155131Srwatson *str = strtok_r(NULL, delim, &last); 136155131Srwatson if (*str == NULL) { 137155131Srwatson errno = EINVAL; 138155131Srwatson return (-1); /* Parse error in file */ 139155131Srwatson } 140155131Srwatson return (0); /* Success */ 141155131Srwatson } 142155131Srwatson } 143155131Srwatson } 144155131Srwatson} 145155131Srwatson 146155131Srwatson/* 147189279Srwatson * Convert a given time value with a multiplier (seconds, hours, days, years) to 148189279Srwatson * seconds. Return 0 on success. 149189279Srwatson */ 150189279Srwatsonstatic int 151189279Srwatsonau_timetosec(time_t *seconds, u_long value, char mult) 152189279Srwatson{ 153189279Srwatson if (NULL == seconds) 154189279Srwatson return (-1); 155189279Srwatson 156189279Srwatson switch(mult) { 157189279Srwatson case 's': 158189279Srwatson /* seconds */ 159189279Srwatson *seconds = (time_t)value; 160189279Srwatson break; 161189279Srwatson 162189279Srwatson case 'h': 163189279Srwatson /* hours */ 164189279Srwatson *seconds = (time_t)value * 60 * 60; 165189279Srwatson break; 166189279Srwatson 167189279Srwatson case 'd': 168189279Srwatson /* days */ 169189279Srwatson *seconds = (time_t)value * 60 * 60 * 24; 170189279Srwatson break; 171189279Srwatson 172189279Srwatson case 'y': 173189279Srwatson /* years. Add a day for each 4th (leap) year. */ 174189279Srwatson *seconds = (time_t)value * 60 * 60 * 24 * 364 + 175189279Srwatson ((time_t)value / 4) * 60 * 60 * 24; 176189279Srwatson break; 177189279Srwatson 178189279Srwatson default: 179189279Srwatson return (-1); 180189279Srwatson } 181189279Srwatson return (0); 182189279Srwatson} 183189279Srwatson 184189279Srwatson/* 185243750Srwatson * Convert a given disk space value with a multiplier (bytes, kilobytes, 186189279Srwatson * megabytes, gigabytes) to bytes. Return 0 on success. 187189279Srwatson */ 188189279Srwatsonstatic int 189189279Srwatsonau_spacetobytes(size_t *bytes, u_long value, char mult) 190189279Srwatson{ 191189279Srwatson if (NULL == bytes) 192189279Srwatson return (-1); 193189279Srwatson 194189279Srwatson switch(mult) { 195189279Srwatson case 'B': 196189279Srwatson case ' ': 197189279Srwatson /* Bytes */ 198189279Srwatson *bytes = (size_t)value; 199189279Srwatson break; 200189279Srwatson 201189279Srwatson case 'K': 202189279Srwatson /* Kilobytes */ 203189279Srwatson *bytes = (size_t)value * 1024; 204189279Srwatson break; 205189279Srwatson 206189279Srwatson case 'M': 207189279Srwatson /* Megabytes */ 208189279Srwatson *bytes = (size_t)value * 1024 * 1024; 209189279Srwatson break; 210189279Srwatson 211189279Srwatson case 'G': 212189279Srwatson /* Gigabytes */ 213189279Srwatson *bytes = (size_t)value * 1024 * 1024 * 1024; 214189279Srwatson break; 215189279Srwatson 216189279Srwatson default: 217189279Srwatson return (-1); 218189279Srwatson } 219189279Srwatson return (0); 220189279Srwatson} 221189279Srwatson 222189279Srwatson/* 223162503Srwatson * Convert a policy to a string. Return -1 on failure, or >= 0 representing 224162503Srwatson * the actual size of the string placed in the buffer (excluding terminating 225162503Srwatson * nul). 226162503Srwatson */ 227162503Srwatsonssize_t 228191273Srwatsonau_poltostr(int policy, size_t maxsize, char *buf) 229162503Srwatson{ 230189279Srwatson int first = 1; 231189279Srwatson int i = 0; 232162503Srwatson 233162503Srwatson if (maxsize < 1) 234162503Srwatson return (-1); 235162503Srwatson buf[0] = '\0'; 236162503Srwatson 237189279Srwatson do { 238189279Srwatson if (policy & au_polstr[i].ap_policy) { 239189279Srwatson if (!first && strlcat(buf, ",", maxsize) >= maxsize) 240162503Srwatson return (-1); 241189279Srwatson if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= 242189279Srwatson maxsize) 243162503Srwatson return (-1); 244189279Srwatson first = 0; 245162503Srwatson } 246189279Srwatson } while (NULL != au_polstr[++i].ap_str); 247189279Srwatson 248162503Srwatson return (strlen(buf)); 249162503Srwatson} 250162503Srwatson 251162503Srwatson/* 252162503Srwatson * Convert a string to a policy. Return -1 on failure (with errno EINVAL, 253162503Srwatson * ENOMEM) or 0 on success. 254162503Srwatson */ 255162503Srwatsonint 256191273Srwatsonau_strtopol(const char *polstr, int *policy) 257162503Srwatson{ 258162503Srwatson char *bufp, *string; 259162503Srwatson char *buffer; 260189279Srwatson int i, matched; 261162503Srwatson 262162503Srwatson *policy = 0; 263162503Srwatson buffer = strdup(polstr); 264162503Srwatson if (buffer == NULL) 265162503Srwatson return (-1); 266162503Srwatson 267162503Srwatson bufp = buffer; 268162503Srwatson while ((string = strsep(&bufp, ",")) != NULL) { 269189279Srwatson matched = i = 0; 270189279Srwatson 271189279Srwatson do { 272189279Srwatson if (strcmp(string, au_polstr[i].ap_str) == 0) { 273189279Srwatson *policy |= au_polstr[i].ap_policy; 274189279Srwatson matched = 1; 275189279Srwatson break; 276189279Srwatson } 277189279Srwatson } while (NULL != au_polstr[++i].ap_str); 278189279Srwatson 279189279Srwatson if (!matched) { 280162503Srwatson free(buffer); 281162503Srwatson errno = EINVAL; 282162503Srwatson return (-1); 283162503Srwatson } 284162503Srwatson } 285162503Srwatson free(buffer); 286162503Srwatson return (0); 287162503Srwatson} 288162503Srwatson 289162503Srwatson/* 290155131Srwatson * Rewind the file pointer to beginning. 291155131Srwatson */ 292162503Srwatsonstatic void 293162503Srwatsonsetac_locked(void) 294162503Srwatson{ 295191273Srwatson static time_t lastctime = 0; 296191273Srwatson struct stat sbuf; 297162503Srwatson 298162503Srwatson ptrmoved = 1; 299191273Srwatson if (fp != NULL) { 300191273Srwatson /* 301191273Srwatson * Check to see if the file on disk has changed. If so, 302191273Srwatson * force a re-read of the file by closing it. 303191273Srwatson */ 304191273Srwatson if (fstat(fileno(fp), &sbuf) < 0) 305191273Srwatson goto closefp; 306191273Srwatson if (lastctime != sbuf.st_ctime) { 307191273Srwatson lastctime = sbuf.st_ctime; 308191273Srwatsonclosefp: 309191273Srwatson fclose(fp); 310191273Srwatson fp = NULL; 311191273Srwatson return; 312191273Srwatson } 313191273Srwatson 314162503Srwatson fseek(fp, 0, SEEK_SET); 315191273Srwatson } 316162503Srwatson} 317162503Srwatson 318155131Srwatsonvoid 319155131Srwatsonsetac(void) 320155131Srwatson{ 321155131Srwatson 322186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 323155131Srwatson pthread_mutex_lock(&mutex); 324186647Srwatson#endif 325162503Srwatson setac_locked(); 326186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 327155131Srwatson pthread_mutex_unlock(&mutex); 328186647Srwatson#endif 329155131Srwatson} 330155131Srwatson 331155131Srwatson/* 332162503Srwatson * Close the audit_control file. 333155131Srwatson */ 334155131Srwatsonvoid 335155131Srwatsonendac(void) 336155131Srwatson{ 337155131Srwatson 338186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 339155131Srwatson pthread_mutex_lock(&mutex); 340186647Srwatson#endif 341155131Srwatson ptrmoved = 1; 342155131Srwatson if (fp != NULL) { 343155131Srwatson fclose(fp); 344155131Srwatson fp = NULL; 345155131Srwatson } 346186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 347155131Srwatson pthread_mutex_unlock(&mutex); 348186647Srwatson#endif 349155131Srwatson} 350155131Srwatson 351155131Srwatson/* 352155131Srwatson * Return audit directory information from the audit control file. 353155131Srwatson */ 354155131Srwatsonint 355155131Srwatsongetacdir(char *name, int len) 356155131Srwatson{ 357155131Srwatson char *dir; 358155131Srwatson int ret = 0; 359155131Srwatson 360155131Srwatson /* 361162503Srwatson * Check if another function was called between successive calls to 362162503Srwatson * getacdir. 363155131Srwatson */ 364186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 365162503Srwatson pthread_mutex_lock(&mutex); 366186647Srwatson#endif 367155131Srwatson if (inacdir && ptrmoved) { 368155131Srwatson ptrmoved = 0; 369155131Srwatson if (fp != NULL) 370155131Srwatson fseek(fp, 0, SEEK_SET); 371155131Srwatson ret = 2; 372155131Srwatson } 373155131Srwatson if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) { 374186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 375155131Srwatson pthread_mutex_unlock(&mutex); 376186647Srwatson#endif 377155131Srwatson return (-2); 378155131Srwatson } 379162503Srwatson if (dir == NULL) { 380186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 381162503Srwatson pthread_mutex_unlock(&mutex); 382186647Srwatson#endif 383155131Srwatson return (-1); 384162503Srwatson } 385185573Srwatson if (strlen(dir) >= (size_t)len) { 386186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 387162503Srwatson pthread_mutex_unlock(&mutex); 388186647Srwatson#endif 389155131Srwatson return (-3); 390162503Srwatson } 391185573Srwatson strlcpy(name, dir, len); 392186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 393162503Srwatson pthread_mutex_unlock(&mutex); 394186647Srwatson#endif 395155131Srwatson return (ret); 396155131Srwatson} 397155131Srwatson 398155131Srwatson/* 399243750Srwatson * Return 1 if dist value is set to 'yes' or 'on'. 400243750Srwatson * Return 0 if dist value is set to something else. 401243750Srwatson * Return negative value on error. 402243750Srwatson */ 403243750Srwatsonint 404243750Srwatsongetacdist(void) 405243750Srwatson{ 406243750Srwatson char *str; 407243750Srwatson int ret; 408243750Srwatson 409243750Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 410243750Srwatson pthread_mutex_lock(&mutex); 411243750Srwatson#endif 412243750Srwatson setac_locked(); 413243750Srwatson if (getstrfromtype_locked(DIST_CONTROL_ENTRY, &str) < 0) { 414243750Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 415243750Srwatson pthread_mutex_unlock(&mutex); 416243750Srwatson#endif 417243750Srwatson return (-2); 418243750Srwatson } 419243750Srwatson if (str == NULL) { 420243750Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 421243750Srwatson pthread_mutex_unlock(&mutex); 422243750Srwatson#endif 423243750Srwatson return (0); 424243750Srwatson } 425243750Srwatson if (strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) 426243750Srwatson ret = 1; 427243750Srwatson else 428243750Srwatson ret = 0; 429243750Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 430243750Srwatson pthread_mutex_unlock(&mutex); 431243750Srwatson#endif 432243750Srwatson return (ret); 433243750Srwatson} 434243750Srwatson 435243750Srwatson/* 436162503Srwatson * Return the minimum free diskspace value from the audit control file. 437155131Srwatson */ 438155131Srwatsonint 439155131Srwatsongetacmin(int *min_val) 440155131Srwatson{ 441155131Srwatson char *min; 442155131Srwatson 443186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 444155131Srwatson pthread_mutex_lock(&mutex); 445186647Srwatson#endif 446162503Srwatson setac_locked(); 447155131Srwatson if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) { 448186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 449155131Srwatson pthread_mutex_unlock(&mutex); 450186647Srwatson#endif 451155131Srwatson return (-2); 452155131Srwatson } 453162503Srwatson if (min == NULL) { 454186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 455162503Srwatson pthread_mutex_unlock(&mutex); 456186647Srwatson#endif 457243750Srwatson return (-1); 458162503Srwatson } 459155131Srwatson *min_val = atoi(min); 460186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 461162503Srwatson pthread_mutex_unlock(&mutex); 462186647Srwatson#endif 463155131Srwatson return (0); 464155131Srwatson} 465155131Srwatson 466155131Srwatson/* 467162621Srwatson * Return the desired trail rotation size from the audit control file. 468162621Srwatson */ 469162621Srwatsonint 470162621Srwatsongetacfilesz(size_t *filesz_val) 471162621Srwatson{ 472189279Srwatson char *str; 473189279Srwatson size_t val; 474189279Srwatson char mult; 475189279Srwatson int nparsed; 476162621Srwatson 477186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 478162621Srwatson pthread_mutex_lock(&mutex); 479186647Srwatson#endif 480162621Srwatson setac_locked(); 481189279Srwatson if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { 482186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 483162621Srwatson pthread_mutex_unlock(&mutex); 484186647Srwatson#endif 485162621Srwatson return (-2); 486162621Srwatson } 487189279Srwatson if (str == NULL) { 488186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 489162621Srwatson pthread_mutex_unlock(&mutex); 490186647Srwatson#endif 491162621Srwatson errno = EINVAL; 492243750Srwatson return (-1); 493162621Srwatson } 494189279Srwatson 495189279Srwatson /* Trim off any leading white space. */ 496189279Srwatson while (*str == ' ' || *str == '\t') 497189279Srwatson str++; 498189279Srwatson 499189279Srwatson nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult); 500189279Srwatson 501189279Srwatson switch (nparsed) { 502189279Srwatson case 1: 503189279Srwatson /* If no multiplier then assume 'B' (bytes). */ 504189279Srwatson mult = 'B'; 505189279Srwatson /* fall through */ 506189279Srwatson case 2: 507189279Srwatson if (au_spacetobytes(filesz_val, val, mult) == 0) 508189279Srwatson break; 509189279Srwatson /* fall through */ 510189279Srwatson default: 511189279Srwatson errno = EINVAL; 512186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 513162621Srwatson pthread_mutex_unlock(&mutex); 514186647Srwatson#endif 515162621Srwatson return (-1); 516162621Srwatson } 517189279Srwatson 518162621Srwatson /* 519162621Srwatson * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 520162621Srwatson * indicates no rotation size. 521162621Srwatson */ 522189279Srwatson if (*filesz_val < 0 || (*filesz_val > 0 && 523189279Srwatson *filesz_val < MIN_AUDIT_FILE_SIZE)) { 524186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 525162621Srwatson pthread_mutex_unlock(&mutex); 526186647Srwatson#endif 527189279Srwatson filesz_val = 0L; 528162621Srwatson errno = EINVAL; 529162621Srwatson return (-1); 530162621Srwatson } 531186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 532162621Srwatson pthread_mutex_unlock(&mutex); 533186647Srwatson#endif 534162621Srwatson return (0); 535162621Srwatson} 536162621Srwatson 537243750Srwatsonstatic int 538243750Srwatsongetaccommon(const char *name, char *auditstr, int len) 539155131Srwatson{ 540155131Srwatson char *str; 541155131Srwatson 542186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 543155131Srwatson pthread_mutex_lock(&mutex); 544186647Srwatson#endif 545162503Srwatson setac_locked(); 546243750Srwatson if (getstrfromtype_locked(name, &str) < 0) { 547186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 548155131Srwatson pthread_mutex_unlock(&mutex); 549186647Srwatson#endif 550155131Srwatson return (-2); 551155131Srwatson } 552162503Srwatson if (str == NULL) { 553186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 554162503Srwatson pthread_mutex_unlock(&mutex); 555186647Srwatson#endif 556243750Srwatson return (-1); 557162503Srwatson } 558185573Srwatson if (strlen(str) >= (size_t)len) { 559186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 560162503Srwatson pthread_mutex_unlock(&mutex); 561186647Srwatson#endif 562155131Srwatson return (-3); 563162503Srwatson } 564185573Srwatson strlcpy(auditstr, str, len); 565186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 566162503Srwatson pthread_mutex_unlock(&mutex); 567186647Srwatson#endif 568155131Srwatson return (0); 569155131Srwatson} 570155131Srwatson 571155131Srwatson/* 572243750Srwatson * Return the system audit value from the audit contol file. 573243750Srwatson */ 574243750Srwatsonint 575243750Srwatsongetacflg(char *auditstr, int len) 576243750Srwatson{ 577243750Srwatson 578243750Srwatson return (getaccommon(FLAGS_CONTROL_ENTRY, auditstr, len)); 579243750Srwatson} 580243750Srwatson 581243750Srwatson/* 582155131Srwatson * Return the non attributable flags from the audit contol file. 583155131Srwatson */ 584155131Srwatsonint 585155131Srwatsongetacna(char *auditstr, int len) 586155131Srwatson{ 587155131Srwatson 588243750Srwatson return (getaccommon(NA_CONTROL_ENTRY, auditstr, len)); 589162503Srwatson} 590155131Srwatson 591162503Srwatson/* 592162503Srwatson * Return the policy field from the audit control file. 593162503Srwatson */ 594162503Srwatsonint 595162503Srwatsongetacpol(char *auditstr, size_t len) 596162503Srwatson{ 597162503Srwatson 598243750Srwatson return (getaccommon(POLICY_CONTROL_ENTRY, auditstr, len)); 599185573Srwatson} 600185573Srwatson 601185573Srwatsonint 602185573Srwatsongetachost(char *auditstr, size_t len) 603185573Srwatson{ 604185573Srwatson 605243750Srwatson return (getaccommon(HOST_CONTROL_ENTRY, auditstr, len)); 606155131Srwatson} 607189279Srwatson 608189279Srwatson/* 609189279Srwatson * Set expiration conditions. 610189279Srwatson */ 611189279Srwatsonstatic int 612189279Srwatsonsetexpirecond(time_t *age, size_t *size, u_long value, char mult) 613189279Srwatson{ 614189279Srwatson 615189279Srwatson if (isupper(mult) || ' ' == mult) 616189279Srwatson return (au_spacetobytes(size, value, mult)); 617189279Srwatson else 618189279Srwatson return (au_timetosec(age, value, mult)); 619189279Srwatson} 620189279Srwatson 621189279Srwatson/* 622189279Srwatson * Return the expire-after field from the audit control file. 623189279Srwatson */ 624189279Srwatsonint 625189279Srwatsongetacexpire(int *andflg, time_t *age, size_t *size) 626189279Srwatson{ 627189279Srwatson char *str; 628189279Srwatson int nparsed; 629189279Srwatson u_long val1, val2; 630189279Srwatson char mult1, mult2; 631189279Srwatson char andor[AU_LINE_MAX]; 632189279Srwatson 633189279Srwatson *age = 0L; 634189279Srwatson *size = 0LL; 635189279Srwatson *andflg = 0; 636189279Srwatson 637189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 638189279Srwatson pthread_mutex_lock(&mutex); 639189279Srwatson#endif 640189279Srwatson setac_locked(); 641189279Srwatson if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) { 642189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 643189279Srwatson pthread_mutex_unlock(&mutex); 644189279Srwatson#endif 645189279Srwatson return (-2); 646189279Srwatson } 647189279Srwatson if (str == NULL) { 648189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 649189279Srwatson pthread_mutex_unlock(&mutex); 650189279Srwatson#endif 651243750Srwatson return (-1); 652189279Srwatson } 653189279Srwatson 654189279Srwatson /* First, trim off any leading white space. */ 655189279Srwatson while (*str == ' ' || *str == '\t') 656243750Srwatson str++; 657189279Srwatson 658189279Srwatson nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, 659189279Srwatson andor, &val2, &mult2); 660189279Srwatson 661189279Srwatson switch (nparsed) { 662189279Srwatson case 1: 663189279Srwatson /* If no multiplier then assume 'B' (Bytes). */ 664189279Srwatson mult1 = 'B'; 665189279Srwatson /* fall through */ 666189279Srwatson case 2: 667189279Srwatson /* One expiration condition. */ 668189279Srwatson if (setexpirecond(age, size, val1, mult1) != 0) { 669189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 670189279Srwatson pthread_mutex_unlock(&mutex); 671189279Srwatson#endif 672189279Srwatson return (-1); 673189279Srwatson } 674189279Srwatson break; 675189279Srwatson 676189279Srwatson case 5: 677189279Srwatson /* Two expiration conditions. */ 678243750Srwatson if (setexpirecond(age, size, val1, mult1) != 0 || 679189279Srwatson setexpirecond(age, size, val2, mult2) != 0) { 680189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 681189279Srwatson pthread_mutex_unlock(&mutex); 682189279Srwatson#endif 683189279Srwatson return (-1); 684189279Srwatson } 685189279Srwatson if (strcasestr(andor, "and") != NULL) 686189279Srwatson *andflg = 1; 687189279Srwatson else if (strcasestr(andor, "or") != NULL) 688189279Srwatson *andflg = 0; 689189279Srwatson else { 690189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 691189279Srwatson pthread_mutex_unlock(&mutex); 692189279Srwatson#endif 693189279Srwatson return (-1); 694189279Srwatson } 695189279Srwatson break; 696189279Srwatson 697189279Srwatson default: 698189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 699189279Srwatson pthread_mutex_unlock(&mutex); 700189279Srwatson#endif 701189279Srwatson return (-1); 702189279Srwatson } 703189279Srwatson 704189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 705189279Srwatson pthread_mutex_unlock(&mutex); 706189279Srwatson#endif 707189279Srwatson return (0); 708189279Srwatson} 709