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 * 30244390Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#41 $ 31155131Srwatson */ 32155131Srwatson 33185573Srwatson#include <config/config.h> 34185573Srwatson 35155131Srwatson#include <bsm/libbsm.h> 36155131Srwatson 37189279Srwatson#include <ctype.h> 38155131Srwatson#include <errno.h> 39155131Srwatson#include <string.h> 40244390Srwatson#include <strings.h> 41186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 42155131Srwatson#include <pthread.h> 43186647Srwatson#endif 44155131Srwatson#include <stdio.h> 45155131Srwatson#include <stdlib.h> 46155131Srwatson 47162503Srwatson#ifndef HAVE_STRLCAT 48162503Srwatson#include <compat/strlcat.h> 49162503Srwatson#endif 50185573Srwatson#ifndef HAVE_STRLCPY 51185573Srwatson#include <compat/strlcpy.h> 52185573Srwatson#endif 53162503Srwatson 54191273Srwatson#include <sys/stat.h> 55191273Srwatson 56155131Srwatson/* 57155131Srwatson * Parse the contents of the audit_control file to return the audit control 58162503Srwatson * parameters. These static fields are protected by 'mutex'. 59155131Srwatson */ 60155131Srwatsonstatic FILE *fp = NULL; 61155131Srwatsonstatic char linestr[AU_LINE_MAX]; 62155131Srwatsonstatic char *delim = ":"; 63155131Srwatson 64155131Srwatsonstatic char inacdir = 0; 65155131Srwatsonstatic char ptrmoved = 0; 66155131Srwatson 67186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 68155131Srwatsonstatic pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 69186647Srwatson#endif 70155131Srwatson 71155131Srwatson/* 72189279Srwatson * Audit policy string token table for au_poltostr() and au_strtopol(). 73189279Srwatson */ 74189279Srwatsonstruct audit_polstr { 75244390Srwatson long ap_policy; 76244390Srwatson const char *ap_str; 77189279Srwatson}; 78189279Srwatson 79189279Srwatsonstatic struct audit_polstr au_polstr[] = { 80189279Srwatson { AUDIT_CNT, "cnt" }, 81189279Srwatson { AUDIT_AHLT, "ahlt" }, 82189279Srwatson { AUDIT_ARGV, "argv" }, 83189279Srwatson { AUDIT_ARGE, "arge" }, 84189279Srwatson { AUDIT_SEQ, "seq" }, 85189279Srwatson { AUDIT_WINDATA, "windata" }, 86189279Srwatson { AUDIT_USER, "user" }, 87189279Srwatson { AUDIT_GROUP, "group" }, 88189279Srwatson { AUDIT_TRAIL, "trail" }, 89189279Srwatson { AUDIT_PATH, "path" }, 90189279Srwatson { AUDIT_SCNT, "scnt" }, 91189279Srwatson { AUDIT_PUBLIC, "public" }, 92189279Srwatson { AUDIT_ZONENAME, "zonename" }, 93189279Srwatson { AUDIT_PERZONE, "perzone" }, 94189279Srwatson { -1, NULL } 95189279Srwatson}; 96189279Srwatson 97189279Srwatson/* 98155131Srwatson * Returns the string value corresponding to the given label from the 99155131Srwatson * configuration file. 100155131Srwatson * 101155131Srwatson * Must be called with mutex held. 102155131Srwatson */ 103155131Srwatsonstatic int 104244390Srwatsongetstrfromtype_locked(const char *name, char **str) 105155131Srwatson{ 106155131Srwatson char *type, *nl; 107155131Srwatson char *tokptr; 108155131Srwatson char *last; 109155131Srwatson 110155131Srwatson *str = NULL; 111155131Srwatson 112155131Srwatson if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL)) 113155131Srwatson return (-1); /* Error */ 114155131Srwatson 115155131Srwatson while (1) { 116155131Srwatson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) { 117155131Srwatson if (ferror(fp)) 118155131Srwatson return (-1); 119155131Srwatson return (0); /* EOF */ 120155131Srwatson } 121155131Srwatson 122155131Srwatson if (linestr[0] == '#') 123155131Srwatson continue; 124155131Srwatson 125195740Srwatson /* Remove trailing new line character and white space. */ 126195740Srwatson nl = strchr(linestr, '\0') - 1; 127195740Srwatson while (nl >= linestr && ('\n' == *nl || ' ' == *nl || 128195740Srwatson '\t' == *nl)) { 129155131Srwatson *nl = '\0'; 130195740Srwatson nl--; 131195740Srwatson } 132155131Srwatson 133155131Srwatson tokptr = linestr; 134155131Srwatson if ((type = strtok_r(tokptr, delim, &last)) != NULL) { 135155131Srwatson if (strcmp(name, type) == 0) { 136155131Srwatson /* Found matching name. */ 137155131Srwatson *str = strtok_r(NULL, delim, &last); 138155131Srwatson if (*str == NULL) { 139155131Srwatson errno = EINVAL; 140155131Srwatson return (-1); /* Parse error in file */ 141155131Srwatson } 142155131Srwatson return (0); /* Success */ 143155131Srwatson } 144155131Srwatson } 145155131Srwatson } 146155131Srwatson} 147155131Srwatson 148155131Srwatson/* 149189279Srwatson * Convert a given time value with a multiplier (seconds, hours, days, years) to 150189279Srwatson * seconds. Return 0 on success. 151189279Srwatson */ 152189279Srwatsonstatic int 153189279Srwatsonau_timetosec(time_t *seconds, u_long value, char mult) 154189279Srwatson{ 155189279Srwatson if (NULL == seconds) 156189279Srwatson return (-1); 157189279Srwatson 158189279Srwatson switch(mult) { 159189279Srwatson case 's': 160189279Srwatson /* seconds */ 161189279Srwatson *seconds = (time_t)value; 162189279Srwatson break; 163189279Srwatson 164189279Srwatson case 'h': 165189279Srwatson /* hours */ 166189279Srwatson *seconds = (time_t)value * 60 * 60; 167189279Srwatson break; 168189279Srwatson 169189279Srwatson case 'd': 170189279Srwatson /* days */ 171189279Srwatson *seconds = (time_t)value * 60 * 60 * 24; 172189279Srwatson break; 173189279Srwatson 174189279Srwatson case 'y': 175189279Srwatson /* years. Add a day for each 4th (leap) year. */ 176189279Srwatson *seconds = (time_t)value * 60 * 60 * 24 * 364 + 177189279Srwatson ((time_t)value / 4) * 60 * 60 * 24; 178189279Srwatson break; 179189279Srwatson 180189279Srwatson default: 181189279Srwatson return (-1); 182189279Srwatson } 183189279Srwatson return (0); 184189279Srwatson} 185189279Srwatson 186189279Srwatson/* 187244390Srwatson * Convert a given disk space value with a multiplier (bytes, kilobytes, 188189279Srwatson * megabytes, gigabytes) to bytes. Return 0 on success. 189189279Srwatson */ 190189279Srwatsonstatic int 191189279Srwatsonau_spacetobytes(size_t *bytes, u_long value, char mult) 192189279Srwatson{ 193189279Srwatson if (NULL == bytes) 194189279Srwatson return (-1); 195189279Srwatson 196189279Srwatson switch(mult) { 197189279Srwatson case 'B': 198189279Srwatson case ' ': 199189279Srwatson /* Bytes */ 200189279Srwatson *bytes = (size_t)value; 201189279Srwatson break; 202189279Srwatson 203189279Srwatson case 'K': 204189279Srwatson /* Kilobytes */ 205189279Srwatson *bytes = (size_t)value * 1024; 206189279Srwatson break; 207189279Srwatson 208189279Srwatson case 'M': 209189279Srwatson /* Megabytes */ 210189279Srwatson *bytes = (size_t)value * 1024 * 1024; 211189279Srwatson break; 212189279Srwatson 213189279Srwatson case 'G': 214189279Srwatson /* Gigabytes */ 215189279Srwatson *bytes = (size_t)value * 1024 * 1024 * 1024; 216189279Srwatson break; 217189279Srwatson 218189279Srwatson default: 219189279Srwatson return (-1); 220189279Srwatson } 221189279Srwatson return (0); 222189279Srwatson} 223189279Srwatson 224189279Srwatson/* 225162503Srwatson * Convert a policy to a string. Return -1 on failure, or >= 0 representing 226162503Srwatson * the actual size of the string placed in the buffer (excluding terminating 227162503Srwatson * nul). 228162503Srwatson */ 229162503Srwatsonssize_t 230191273Srwatsonau_poltostr(int policy, size_t maxsize, char *buf) 231162503Srwatson{ 232189279Srwatson int first = 1; 233189279Srwatson int i = 0; 234162503Srwatson 235162503Srwatson if (maxsize < 1) 236162503Srwatson return (-1); 237162503Srwatson buf[0] = '\0'; 238162503Srwatson 239189279Srwatson do { 240189279Srwatson if (policy & au_polstr[i].ap_policy) { 241189279Srwatson if (!first && strlcat(buf, ",", maxsize) >= maxsize) 242162503Srwatson return (-1); 243189279Srwatson if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= 244189279Srwatson maxsize) 245162503Srwatson return (-1); 246189279Srwatson first = 0; 247162503Srwatson } 248189279Srwatson } while (NULL != au_polstr[++i].ap_str); 249189279Srwatson 250162503Srwatson return (strlen(buf)); 251162503Srwatson} 252162503Srwatson 253162503Srwatson/* 254162503Srwatson * Convert a string to a policy. Return -1 on failure (with errno EINVAL, 255162503Srwatson * ENOMEM) or 0 on success. 256162503Srwatson */ 257162503Srwatsonint 258191273Srwatsonau_strtopol(const char *polstr, int *policy) 259162503Srwatson{ 260162503Srwatson char *bufp, *string; 261162503Srwatson char *buffer; 262189279Srwatson int i, matched; 263162503Srwatson 264162503Srwatson *policy = 0; 265162503Srwatson buffer = strdup(polstr); 266162503Srwatson if (buffer == NULL) 267162503Srwatson return (-1); 268162503Srwatson 269162503Srwatson bufp = buffer; 270162503Srwatson while ((string = strsep(&bufp, ",")) != NULL) { 271189279Srwatson matched = i = 0; 272189279Srwatson 273189279Srwatson do { 274189279Srwatson if (strcmp(string, au_polstr[i].ap_str) == 0) { 275189279Srwatson *policy |= au_polstr[i].ap_policy; 276189279Srwatson matched = 1; 277189279Srwatson break; 278189279Srwatson } 279189279Srwatson } while (NULL != au_polstr[++i].ap_str); 280189279Srwatson 281189279Srwatson if (!matched) { 282162503Srwatson free(buffer); 283162503Srwatson errno = EINVAL; 284162503Srwatson return (-1); 285162503Srwatson } 286162503Srwatson } 287162503Srwatson free(buffer); 288162503Srwatson return (0); 289162503Srwatson} 290162503Srwatson 291162503Srwatson/* 292155131Srwatson * Rewind the file pointer to beginning. 293155131Srwatson */ 294162503Srwatsonstatic void 295162503Srwatsonsetac_locked(void) 296162503Srwatson{ 297191273Srwatson static time_t lastctime = 0; 298191273Srwatson struct stat sbuf; 299162503Srwatson 300162503Srwatson ptrmoved = 1; 301191273Srwatson if (fp != NULL) { 302191273Srwatson /* 303191273Srwatson * Check to see if the file on disk has changed. If so, 304191273Srwatson * force a re-read of the file by closing it. 305191273Srwatson */ 306191273Srwatson if (fstat(fileno(fp), &sbuf) < 0) 307191273Srwatson goto closefp; 308191273Srwatson if (lastctime != sbuf.st_ctime) { 309191273Srwatson lastctime = sbuf.st_ctime; 310191273Srwatsonclosefp: 311191273Srwatson fclose(fp); 312191273Srwatson fp = NULL; 313191273Srwatson return; 314191273Srwatson } 315191273Srwatson 316162503Srwatson fseek(fp, 0, SEEK_SET); 317191273Srwatson } 318162503Srwatson} 319162503Srwatson 320155131Srwatsonvoid 321155131Srwatsonsetac(void) 322155131Srwatson{ 323155131Srwatson 324186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 325155131Srwatson pthread_mutex_lock(&mutex); 326186647Srwatson#endif 327162503Srwatson setac_locked(); 328186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 329155131Srwatson pthread_mutex_unlock(&mutex); 330186647Srwatson#endif 331155131Srwatson} 332155131Srwatson 333155131Srwatson/* 334162503Srwatson * Close the audit_control file. 335155131Srwatson */ 336155131Srwatsonvoid 337155131Srwatsonendac(void) 338155131Srwatson{ 339155131Srwatson 340186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 341155131Srwatson pthread_mutex_lock(&mutex); 342186647Srwatson#endif 343155131Srwatson ptrmoved = 1; 344155131Srwatson if (fp != NULL) { 345155131Srwatson fclose(fp); 346155131Srwatson fp = NULL; 347155131Srwatson } 348186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 349155131Srwatson pthread_mutex_unlock(&mutex); 350186647Srwatson#endif 351155131Srwatson} 352155131Srwatson 353155131Srwatson/* 354155131Srwatson * Return audit directory information from the audit control file. 355155131Srwatson */ 356155131Srwatsonint 357155131Srwatsongetacdir(char *name, int len) 358155131Srwatson{ 359155131Srwatson char *dir; 360155131Srwatson int ret = 0; 361155131Srwatson 362155131Srwatson /* 363162503Srwatson * Check if another function was called between successive calls to 364162503Srwatson * getacdir. 365155131Srwatson */ 366186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 367162503Srwatson pthread_mutex_lock(&mutex); 368186647Srwatson#endif 369155131Srwatson if (inacdir && ptrmoved) { 370155131Srwatson ptrmoved = 0; 371155131Srwatson if (fp != NULL) 372155131Srwatson fseek(fp, 0, SEEK_SET); 373155131Srwatson ret = 2; 374155131Srwatson } 375155131Srwatson if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) { 376186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 377155131Srwatson pthread_mutex_unlock(&mutex); 378186647Srwatson#endif 379155131Srwatson return (-2); 380155131Srwatson } 381162503Srwatson if (dir == NULL) { 382186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 383162503Srwatson pthread_mutex_unlock(&mutex); 384186647Srwatson#endif 385155131Srwatson return (-1); 386162503Srwatson } 387185573Srwatson if (strlen(dir) >= (size_t)len) { 388186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 389162503Srwatson pthread_mutex_unlock(&mutex); 390186647Srwatson#endif 391155131Srwatson return (-3); 392162503Srwatson } 393185573Srwatson strlcpy(name, dir, len); 394186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 395162503Srwatson pthread_mutex_unlock(&mutex); 396186647Srwatson#endif 397155131Srwatson return (ret); 398155131Srwatson} 399155131Srwatson 400155131Srwatson/* 401244390Srwatson * Return 1 if dist value is set to 'yes' or 'on'. 402244390Srwatson * Return 0 if dist value is set to something else. 403244390Srwatson * Return negative value on error. 404244390Srwatson */ 405244390Srwatsonint 406244390Srwatsongetacdist(void) 407244390Srwatson{ 408244390Srwatson char *str; 409244390Srwatson int ret; 410244390Srwatson 411244390Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 412244390Srwatson pthread_mutex_lock(&mutex); 413244390Srwatson#endif 414244390Srwatson setac_locked(); 415244390Srwatson if (getstrfromtype_locked(DIST_CONTROL_ENTRY, &str) < 0) { 416244390Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 417244390Srwatson pthread_mutex_unlock(&mutex); 418244390Srwatson#endif 419244390Srwatson return (-2); 420244390Srwatson } 421244390Srwatson if (str == NULL) { 422244390Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 423244390Srwatson pthread_mutex_unlock(&mutex); 424244390Srwatson#endif 425244390Srwatson return (0); 426244390Srwatson } 427244390Srwatson if (strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0) 428244390Srwatson ret = 1; 429244390Srwatson else 430244390Srwatson ret = 0; 431244390Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 432244390Srwatson pthread_mutex_unlock(&mutex); 433244390Srwatson#endif 434244390Srwatson return (ret); 435244390Srwatson} 436244390Srwatson 437244390Srwatson/* 438162503Srwatson * Return the minimum free diskspace value from the audit control file. 439155131Srwatson */ 440155131Srwatsonint 441155131Srwatsongetacmin(int *min_val) 442155131Srwatson{ 443155131Srwatson char *min; 444155131Srwatson 445186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 446155131Srwatson pthread_mutex_lock(&mutex); 447186647Srwatson#endif 448162503Srwatson setac_locked(); 449155131Srwatson if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) { 450186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 451155131Srwatson pthread_mutex_unlock(&mutex); 452186647Srwatson#endif 453155131Srwatson return (-2); 454155131Srwatson } 455162503Srwatson if (min == NULL) { 456186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 457162503Srwatson pthread_mutex_unlock(&mutex); 458186647Srwatson#endif 459244390Srwatson return (-1); 460162503Srwatson } 461155131Srwatson *min_val = atoi(min); 462186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 463162503Srwatson pthread_mutex_unlock(&mutex); 464186647Srwatson#endif 465155131Srwatson return (0); 466155131Srwatson} 467155131Srwatson 468155131Srwatson/* 469162621Srwatson * Return the desired trail rotation size from the audit control file. 470162621Srwatson */ 471162621Srwatsonint 472162621Srwatsongetacfilesz(size_t *filesz_val) 473162621Srwatson{ 474189279Srwatson char *str; 475189279Srwatson size_t val; 476189279Srwatson char mult; 477189279Srwatson int nparsed; 478162621Srwatson 479186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 480162621Srwatson pthread_mutex_lock(&mutex); 481186647Srwatson#endif 482162621Srwatson setac_locked(); 483189279Srwatson if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { 484186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 485162621Srwatson pthread_mutex_unlock(&mutex); 486186647Srwatson#endif 487162621Srwatson return (-2); 488162621Srwatson } 489189279Srwatson if (str == NULL) { 490186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 491162621Srwatson pthread_mutex_unlock(&mutex); 492186647Srwatson#endif 493162621Srwatson errno = EINVAL; 494244390Srwatson return (-1); 495162621Srwatson } 496189279Srwatson 497189279Srwatson /* Trim off any leading white space. */ 498189279Srwatson while (*str == ' ' || *str == '\t') 499189279Srwatson str++; 500189279Srwatson 501189279Srwatson nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult); 502189279Srwatson 503189279Srwatson switch (nparsed) { 504189279Srwatson case 1: 505189279Srwatson /* If no multiplier then assume 'B' (bytes). */ 506189279Srwatson mult = 'B'; 507189279Srwatson /* fall through */ 508189279Srwatson case 2: 509189279Srwatson if (au_spacetobytes(filesz_val, val, mult) == 0) 510189279Srwatson break; 511189279Srwatson /* fall through */ 512189279Srwatson default: 513189279Srwatson errno = EINVAL; 514186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 515162621Srwatson pthread_mutex_unlock(&mutex); 516186647Srwatson#endif 517162621Srwatson return (-1); 518162621Srwatson } 519189279Srwatson 520162621Srwatson /* 521162621Srwatson * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 522162621Srwatson * indicates no rotation size. 523162621Srwatson */ 524189279Srwatson if (*filesz_val < 0 || (*filesz_val > 0 && 525189279Srwatson *filesz_val < MIN_AUDIT_FILE_SIZE)) { 526186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 527162621Srwatson pthread_mutex_unlock(&mutex); 528186647Srwatson#endif 529189279Srwatson filesz_val = 0L; 530162621Srwatson errno = EINVAL; 531162621Srwatson return (-1); 532162621Srwatson } 533186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 534162621Srwatson pthread_mutex_unlock(&mutex); 535186647Srwatson#endif 536162621Srwatson return (0); 537162621Srwatson} 538162621Srwatson 539244390Srwatsonstatic int 540244390Srwatsongetaccommon(const char *name, char *auditstr, int len) 541155131Srwatson{ 542155131Srwatson char *str; 543155131Srwatson 544186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 545155131Srwatson pthread_mutex_lock(&mutex); 546186647Srwatson#endif 547162503Srwatson setac_locked(); 548244390Srwatson if (getstrfromtype_locked(name, &str) < 0) { 549186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 550155131Srwatson pthread_mutex_unlock(&mutex); 551186647Srwatson#endif 552155131Srwatson return (-2); 553155131Srwatson } 554162503Srwatson if (str == NULL) { 555186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 556162503Srwatson pthread_mutex_unlock(&mutex); 557186647Srwatson#endif 558244390Srwatson return (-1); 559162503Srwatson } 560185573Srwatson if (strlen(str) >= (size_t)len) { 561186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 562162503Srwatson pthread_mutex_unlock(&mutex); 563186647Srwatson#endif 564155131Srwatson return (-3); 565162503Srwatson } 566185573Srwatson strlcpy(auditstr, str, len); 567186647Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 568162503Srwatson pthread_mutex_unlock(&mutex); 569186647Srwatson#endif 570155131Srwatson return (0); 571155131Srwatson} 572155131Srwatson 573155131Srwatson/* 574244390Srwatson * Return the system audit value from the audit contol file. 575244390Srwatson */ 576244390Srwatsonint 577244390Srwatsongetacflg(char *auditstr, int len) 578244390Srwatson{ 579244390Srwatson 580244390Srwatson return (getaccommon(FLAGS_CONTROL_ENTRY, auditstr, len)); 581244390Srwatson} 582244390Srwatson 583244390Srwatson/* 584155131Srwatson * Return the non attributable flags from the audit contol file. 585155131Srwatson */ 586155131Srwatsonint 587155131Srwatsongetacna(char *auditstr, int len) 588155131Srwatson{ 589155131Srwatson 590244390Srwatson return (getaccommon(NA_CONTROL_ENTRY, auditstr, len)); 591162503Srwatson} 592155131Srwatson 593162503Srwatson/* 594162503Srwatson * Return the policy field from the audit control file. 595162503Srwatson */ 596162503Srwatsonint 597162503Srwatsongetacpol(char *auditstr, size_t len) 598162503Srwatson{ 599162503Srwatson 600244390Srwatson return (getaccommon(POLICY_CONTROL_ENTRY, auditstr, len)); 601185573Srwatson} 602185573Srwatson 603185573Srwatsonint 604185573Srwatsongetachost(char *auditstr, size_t len) 605185573Srwatson{ 606185573Srwatson 607244390Srwatson return (getaccommon(HOST_CONTROL_ENTRY, auditstr, len)); 608155131Srwatson} 609189279Srwatson 610189279Srwatson/* 611189279Srwatson * Set expiration conditions. 612189279Srwatson */ 613189279Srwatsonstatic int 614189279Srwatsonsetexpirecond(time_t *age, size_t *size, u_long value, char mult) 615189279Srwatson{ 616189279Srwatson 617189279Srwatson if (isupper(mult) || ' ' == mult) 618189279Srwatson return (au_spacetobytes(size, value, mult)); 619189279Srwatson else 620189279Srwatson return (au_timetosec(age, value, mult)); 621189279Srwatson} 622189279Srwatson 623189279Srwatson/* 624189279Srwatson * Return the expire-after field from the audit control file. 625189279Srwatson */ 626189279Srwatsonint 627189279Srwatsongetacexpire(int *andflg, time_t *age, size_t *size) 628189279Srwatson{ 629189279Srwatson char *str; 630189279Srwatson int nparsed; 631189279Srwatson u_long val1, val2; 632189279Srwatson char mult1, mult2; 633189279Srwatson char andor[AU_LINE_MAX]; 634189279Srwatson 635189279Srwatson *age = 0L; 636189279Srwatson *size = 0LL; 637189279Srwatson *andflg = 0; 638189279Srwatson 639189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 640189279Srwatson pthread_mutex_lock(&mutex); 641189279Srwatson#endif 642189279Srwatson setac_locked(); 643189279Srwatson if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) { 644189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 645189279Srwatson pthread_mutex_unlock(&mutex); 646189279Srwatson#endif 647189279Srwatson return (-2); 648189279Srwatson } 649189279Srwatson if (str == NULL) { 650189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 651189279Srwatson pthread_mutex_unlock(&mutex); 652189279Srwatson#endif 653244390Srwatson return (-1); 654189279Srwatson } 655189279Srwatson 656189279Srwatson /* First, trim off any leading white space. */ 657189279Srwatson while (*str == ' ' || *str == '\t') 658244390Srwatson str++; 659189279Srwatson 660189279Srwatson nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, 661189279Srwatson andor, &val2, &mult2); 662189279Srwatson 663189279Srwatson switch (nparsed) { 664189279Srwatson case 1: 665189279Srwatson /* If no multiplier then assume 'B' (Bytes). */ 666189279Srwatson mult1 = 'B'; 667189279Srwatson /* fall through */ 668189279Srwatson case 2: 669189279Srwatson /* One expiration condition. */ 670189279Srwatson if (setexpirecond(age, size, val1, mult1) != 0) { 671189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 672189279Srwatson pthread_mutex_unlock(&mutex); 673189279Srwatson#endif 674189279Srwatson return (-1); 675189279Srwatson } 676189279Srwatson break; 677189279Srwatson 678189279Srwatson case 5: 679189279Srwatson /* Two expiration conditions. */ 680244390Srwatson if (setexpirecond(age, size, val1, mult1) != 0 || 681189279Srwatson setexpirecond(age, size, val2, mult2) != 0) { 682189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 683189279Srwatson pthread_mutex_unlock(&mutex); 684189279Srwatson#endif 685189279Srwatson return (-1); 686189279Srwatson } 687189279Srwatson if (strcasestr(andor, "and") != NULL) 688189279Srwatson *andflg = 1; 689189279Srwatson else if (strcasestr(andor, "or") != NULL) 690189279Srwatson *andflg = 0; 691189279Srwatson else { 692189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 693189279Srwatson pthread_mutex_unlock(&mutex); 694189279Srwatson#endif 695189279Srwatson return (-1); 696189279Srwatson } 697189279Srwatson break; 698189279Srwatson 699189279Srwatson default: 700189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 701189279Srwatson pthread_mutex_unlock(&mutex); 702189279Srwatson#endif 703189279Srwatson return (-1); 704189279Srwatson } 705189279Srwatson 706189279Srwatson#ifdef HAVE_PTHREAD_MUTEX_LOCK 707189279Srwatson pthread_mutex_unlock(&mutex); 708189279Srwatson#endif 709189279Srwatson return (0); 710189279Srwatson} 711