152267f74SRobert Watson /*- 206edd2f1SRobert Watson * Copyright (c) 2004, 2009 Apple Inc. 3bb97b418SRobert 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. 1452267f74SRobert Watson * 3. Neither the name of Apple 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 * 30597df30eSRobert Watson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#34 $ 31ca0716f5SRobert Watson */ 32ca0716f5SRobert Watson 3352267f74SRobert Watson #include <config/config.h> 3452267f74SRobert Watson 35ca0716f5SRobert Watson #include <bsm/libbsm.h> 36ca0716f5SRobert Watson 3706edd2f1SRobert Watson #include <ctype.h> 38ca0716f5SRobert Watson #include <errno.h> 39ca0716f5SRobert Watson #include <string.h> 407a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 41ca0716f5SRobert Watson #include <pthread.h> 427a0a89d2SRobert Watson #endif 43ca0716f5SRobert Watson #include <stdio.h> 44ca0716f5SRobert Watson #include <stdlib.h> 45ca0716f5SRobert Watson 46bb97b418SRobert Watson #ifndef HAVE_STRLCAT 47bb97b418SRobert Watson #include <compat/strlcat.h> 48bb97b418SRobert Watson #endif 4952267f74SRobert Watson #ifndef HAVE_STRLCPY 5052267f74SRobert Watson #include <compat/strlcpy.h> 5152267f74SRobert Watson #endif 52bb97b418SRobert Watson 53c0020399SRobert Watson #include <sys/stat.h> 54c0020399SRobert Watson 55ca0716f5SRobert Watson /* 56ca0716f5SRobert Watson * Parse the contents of the audit_control file to return the audit control 57bb97b418SRobert Watson * parameters. These static fields are protected by 'mutex'. 58ca0716f5SRobert Watson */ 59ca0716f5SRobert Watson static FILE *fp = NULL; 60ca0716f5SRobert Watson static char linestr[AU_LINE_MAX]; 61ca0716f5SRobert Watson static char *delim = ":"; 62ca0716f5SRobert Watson 63ca0716f5SRobert Watson static char inacdir = 0; 64ca0716f5SRobert Watson static char ptrmoved = 0; 65ca0716f5SRobert Watson 667a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 67ca0716f5SRobert Watson static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 687a0a89d2SRobert Watson #endif 69ca0716f5SRobert Watson 70ca0716f5SRobert Watson /* 7106edd2f1SRobert Watson * Audit policy string token table for au_poltostr() and au_strtopol(). 7206edd2f1SRobert Watson */ 7306edd2f1SRobert Watson struct audit_polstr { 7406edd2f1SRobert Watson long ap_policy; 7506edd2f1SRobert Watson const char *ap_str; 7606edd2f1SRobert Watson }; 7706edd2f1SRobert Watson 7806edd2f1SRobert Watson static struct audit_polstr au_polstr[] = { 7906edd2f1SRobert Watson { AUDIT_CNT, "cnt" }, 8006edd2f1SRobert Watson { AUDIT_AHLT, "ahlt" }, 8106edd2f1SRobert Watson { AUDIT_ARGV, "argv" }, 8206edd2f1SRobert Watson { AUDIT_ARGE, "arge" }, 8306edd2f1SRobert Watson { AUDIT_SEQ, "seq" }, 8406edd2f1SRobert Watson { AUDIT_WINDATA, "windata" }, 8506edd2f1SRobert Watson { AUDIT_USER, "user" }, 8606edd2f1SRobert Watson { AUDIT_GROUP, "group" }, 8706edd2f1SRobert Watson { AUDIT_TRAIL, "trail" }, 8806edd2f1SRobert Watson { AUDIT_PATH, "path" }, 8906edd2f1SRobert Watson { AUDIT_SCNT, "scnt" }, 9006edd2f1SRobert Watson { AUDIT_PUBLIC, "public" }, 9106edd2f1SRobert Watson { AUDIT_ZONENAME, "zonename" }, 9206edd2f1SRobert Watson { AUDIT_PERZONE, "perzone" }, 9306edd2f1SRobert Watson { -1, NULL } 9406edd2f1SRobert Watson }; 9506edd2f1SRobert Watson 9606edd2f1SRobert Watson /* 97ca0716f5SRobert Watson * Returns the string value corresponding to the given label from the 98ca0716f5SRobert Watson * configuration file. 99ca0716f5SRobert Watson * 100ca0716f5SRobert Watson * Must be called with mutex held. 101ca0716f5SRobert Watson */ 102ca0716f5SRobert Watson static int 103ca0716f5SRobert Watson getstrfromtype_locked(char *name, char **str) 104ca0716f5SRobert Watson { 105ca0716f5SRobert Watson char *type, *nl; 106ca0716f5SRobert Watson char *tokptr; 107ca0716f5SRobert Watson char *last; 108ca0716f5SRobert Watson 109ca0716f5SRobert Watson *str = NULL; 110ca0716f5SRobert Watson 111ca0716f5SRobert Watson if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL)) 112ca0716f5SRobert Watson return (-1); /* Error */ 113ca0716f5SRobert Watson 114ca0716f5SRobert Watson while (1) { 115ca0716f5SRobert Watson if (fgets(linestr, AU_LINE_MAX, fp) == NULL) { 116ca0716f5SRobert Watson if (ferror(fp)) 117ca0716f5SRobert Watson return (-1); 118ca0716f5SRobert Watson return (0); /* EOF */ 119ca0716f5SRobert Watson } 120ca0716f5SRobert Watson 121ca0716f5SRobert Watson if (linestr[0] == '#') 122ca0716f5SRobert Watson continue; 123ca0716f5SRobert Watson 124597df30eSRobert Watson /* Remove trailing new line character and white space. */ 125597df30eSRobert Watson nl = strchr(linestr, '\0') - 1; 126597df30eSRobert Watson while (nl >= linestr && ('\n' == *nl || ' ' == *nl || 127597df30eSRobert Watson '\t' == *nl)) { 128ca0716f5SRobert Watson *nl = '\0'; 129597df30eSRobert Watson nl--; 130597df30eSRobert Watson } 131ca0716f5SRobert Watson 132ca0716f5SRobert Watson tokptr = linestr; 133ca0716f5SRobert Watson if ((type = strtok_r(tokptr, delim, &last)) != NULL) { 134ca0716f5SRobert Watson if (strcmp(name, type) == 0) { 135ca0716f5SRobert Watson /* Found matching name. */ 136ca0716f5SRobert Watson *str = strtok_r(NULL, delim, &last); 137ca0716f5SRobert Watson if (*str == NULL) { 138ca0716f5SRobert Watson errno = EINVAL; 139ca0716f5SRobert Watson return (-1); /* Parse error in file */ 140ca0716f5SRobert Watson } 141ca0716f5SRobert Watson return (0); /* Success */ 142ca0716f5SRobert Watson } 143ca0716f5SRobert Watson } 144ca0716f5SRobert Watson } 145ca0716f5SRobert Watson } 146ca0716f5SRobert Watson 147ca0716f5SRobert Watson /* 14806edd2f1SRobert Watson * Convert a given time value with a multiplier (seconds, hours, days, years) to 14906edd2f1SRobert Watson * seconds. Return 0 on success. 15006edd2f1SRobert Watson */ 15106edd2f1SRobert Watson static int 15206edd2f1SRobert Watson au_timetosec(time_t *seconds, u_long value, char mult) 15306edd2f1SRobert Watson { 15406edd2f1SRobert Watson if (NULL == seconds) 15506edd2f1SRobert Watson return (-1); 15606edd2f1SRobert Watson 15706edd2f1SRobert Watson switch(mult) { 15806edd2f1SRobert Watson case 's': 15906edd2f1SRobert Watson /* seconds */ 16006edd2f1SRobert Watson *seconds = (time_t)value; 16106edd2f1SRobert Watson break; 16206edd2f1SRobert Watson 16306edd2f1SRobert Watson case 'h': 16406edd2f1SRobert Watson /* hours */ 16506edd2f1SRobert Watson *seconds = (time_t)value * 60 * 60; 16606edd2f1SRobert Watson break; 16706edd2f1SRobert Watson 16806edd2f1SRobert Watson case 'd': 16906edd2f1SRobert Watson /* days */ 17006edd2f1SRobert Watson *seconds = (time_t)value * 60 * 60 * 24; 17106edd2f1SRobert Watson break; 17206edd2f1SRobert Watson 17306edd2f1SRobert Watson case 'y': 17406edd2f1SRobert Watson /* years. Add a day for each 4th (leap) year. */ 17506edd2f1SRobert Watson *seconds = (time_t)value * 60 * 60 * 24 * 364 + 17606edd2f1SRobert Watson ((time_t)value / 4) * 60 * 60 * 24; 17706edd2f1SRobert Watson break; 17806edd2f1SRobert Watson 17906edd2f1SRobert Watson default: 18006edd2f1SRobert Watson return (-1); 18106edd2f1SRobert Watson } 18206edd2f1SRobert Watson return (0); 18306edd2f1SRobert Watson } 18406edd2f1SRobert Watson 18506edd2f1SRobert Watson /* 18606edd2f1SRobert Watson * Convert a given disk space value with a multiplier (bytes, kilobytes, 18706edd2f1SRobert Watson * megabytes, gigabytes) to bytes. Return 0 on success. 18806edd2f1SRobert Watson */ 18906edd2f1SRobert Watson static int 19006edd2f1SRobert Watson au_spacetobytes(size_t *bytes, u_long value, char mult) 19106edd2f1SRobert Watson { 19206edd2f1SRobert Watson if (NULL == bytes) 19306edd2f1SRobert Watson return (-1); 19406edd2f1SRobert Watson 19506edd2f1SRobert Watson switch(mult) { 19606edd2f1SRobert Watson case 'B': 19706edd2f1SRobert Watson case ' ': 19806edd2f1SRobert Watson /* Bytes */ 19906edd2f1SRobert Watson *bytes = (size_t)value; 20006edd2f1SRobert Watson break; 20106edd2f1SRobert Watson 20206edd2f1SRobert Watson case 'K': 20306edd2f1SRobert Watson /* Kilobytes */ 20406edd2f1SRobert Watson *bytes = (size_t)value * 1024; 20506edd2f1SRobert Watson break; 20606edd2f1SRobert Watson 20706edd2f1SRobert Watson case 'M': 20806edd2f1SRobert Watson /* Megabytes */ 20906edd2f1SRobert Watson *bytes = (size_t)value * 1024 * 1024; 21006edd2f1SRobert Watson break; 21106edd2f1SRobert Watson 21206edd2f1SRobert Watson case 'G': 21306edd2f1SRobert Watson /* Gigabytes */ 21406edd2f1SRobert Watson *bytes = (size_t)value * 1024 * 1024 * 1024; 21506edd2f1SRobert Watson break; 21606edd2f1SRobert Watson 21706edd2f1SRobert Watson default: 21806edd2f1SRobert Watson return (-1); 21906edd2f1SRobert Watson } 22006edd2f1SRobert Watson return (0); 22106edd2f1SRobert Watson } 22206edd2f1SRobert Watson 22306edd2f1SRobert Watson /* 224bb97b418SRobert Watson * Convert a policy to a string. Return -1 on failure, or >= 0 representing 225bb97b418SRobert Watson * the actual size of the string placed in the buffer (excluding terminating 226bb97b418SRobert Watson * nul). 227bb97b418SRobert Watson */ 228bb97b418SRobert Watson ssize_t 229c0020399SRobert Watson au_poltostr(int policy, size_t maxsize, char *buf) 230bb97b418SRobert Watson { 23106edd2f1SRobert Watson int first = 1; 23206edd2f1SRobert Watson int i = 0; 233bb97b418SRobert Watson 234bb97b418SRobert Watson if (maxsize < 1) 235bb97b418SRobert Watson return (-1); 236bb97b418SRobert Watson buf[0] = '\0'; 237bb97b418SRobert Watson 23806edd2f1SRobert Watson do { 23906edd2f1SRobert Watson if (policy & au_polstr[i].ap_policy) { 24006edd2f1SRobert Watson if (!first && strlcat(buf, ",", maxsize) >= maxsize) 24106edd2f1SRobert Watson return (-1); 24206edd2f1SRobert Watson if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= 24306edd2f1SRobert Watson maxsize) 244bb97b418SRobert Watson return (-1); 245bb97b418SRobert Watson first = 0; 246bb97b418SRobert Watson } 24706edd2f1SRobert Watson } while (NULL != au_polstr[++i].ap_str); 24806edd2f1SRobert Watson 249bb97b418SRobert Watson return (strlen(buf)); 250bb97b418SRobert Watson } 251bb97b418SRobert Watson 252bb97b418SRobert Watson /* 253bb97b418SRobert Watson * Convert a string to a policy. Return -1 on failure (with errno EINVAL, 254bb97b418SRobert Watson * ENOMEM) or 0 on success. 255bb97b418SRobert Watson */ 256bb97b418SRobert Watson int 257c0020399SRobert Watson au_strtopol(const char *polstr, int *policy) 258bb97b418SRobert Watson { 259bb97b418SRobert Watson char *bufp, *string; 260bb97b418SRobert Watson char *buffer; 26106edd2f1SRobert Watson int i, matched; 262bb97b418SRobert Watson 263bb97b418SRobert Watson *policy = 0; 264bb97b418SRobert Watson buffer = strdup(polstr); 265bb97b418SRobert Watson if (buffer == NULL) 266bb97b418SRobert Watson return (-1); 267bb97b418SRobert Watson 268bb97b418SRobert Watson bufp = buffer; 269bb97b418SRobert Watson while ((string = strsep(&bufp, ",")) != NULL) { 27006edd2f1SRobert Watson matched = i = 0; 27106edd2f1SRobert Watson 27206edd2f1SRobert Watson do { 27306edd2f1SRobert Watson if (strcmp(string, au_polstr[i].ap_str) == 0) { 27406edd2f1SRobert Watson *policy |= au_polstr[i].ap_policy; 27506edd2f1SRobert Watson matched = 1; 27606edd2f1SRobert Watson break; 27706edd2f1SRobert Watson } 27806edd2f1SRobert Watson } while (NULL != au_polstr[++i].ap_str); 27906edd2f1SRobert Watson 28006edd2f1SRobert Watson if (!matched) { 281bb97b418SRobert Watson free(buffer); 282bb97b418SRobert Watson errno = EINVAL; 283bb97b418SRobert Watson return (-1); 284bb97b418SRobert Watson } 285bb97b418SRobert Watson } 286bb97b418SRobert Watson free(buffer); 287bb97b418SRobert Watson return (0); 288bb97b418SRobert Watson } 289bb97b418SRobert Watson 290bb97b418SRobert Watson /* 291ca0716f5SRobert Watson * Rewind the file pointer to beginning. 292ca0716f5SRobert Watson */ 293bb97b418SRobert Watson static void 294bb97b418SRobert Watson setac_locked(void) 295bb97b418SRobert Watson { 296c0020399SRobert Watson static time_t lastctime = 0; 297c0020399SRobert Watson struct stat sbuf; 298bb97b418SRobert Watson 299bb97b418SRobert Watson ptrmoved = 1; 300c0020399SRobert Watson if (fp != NULL) { 301c0020399SRobert Watson /* 302c0020399SRobert Watson * Check to see if the file on disk has changed. If so, 303c0020399SRobert Watson * force a re-read of the file by closing it. 304c0020399SRobert Watson */ 305c0020399SRobert Watson if (fstat(fileno(fp), &sbuf) < 0) 306c0020399SRobert Watson goto closefp; 307c0020399SRobert Watson if (lastctime != sbuf.st_ctime) { 308c0020399SRobert Watson lastctime = sbuf.st_ctime; 309c0020399SRobert Watson closefp: 310c0020399SRobert Watson fclose(fp); 311c0020399SRobert Watson fp = NULL; 312c0020399SRobert Watson return; 313c0020399SRobert Watson } 314c0020399SRobert Watson 315bb97b418SRobert Watson fseek(fp, 0, SEEK_SET); 316bb97b418SRobert Watson } 317c0020399SRobert Watson } 318bb97b418SRobert Watson 319ca0716f5SRobert Watson void 320ca0716f5SRobert Watson setac(void) 321ca0716f5SRobert Watson { 322ca0716f5SRobert Watson 3237a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 324ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 3257a0a89d2SRobert Watson #endif 326bb97b418SRobert Watson setac_locked(); 3277a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 328ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 3297a0a89d2SRobert Watson #endif 330ca0716f5SRobert Watson } 331ca0716f5SRobert Watson 332ca0716f5SRobert Watson /* 333bb97b418SRobert Watson * Close the audit_control file. 334ca0716f5SRobert Watson */ 335ca0716f5SRobert Watson void 336ca0716f5SRobert Watson endac(void) 337ca0716f5SRobert Watson { 338ca0716f5SRobert Watson 3397a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 340ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 3417a0a89d2SRobert Watson #endif 342ca0716f5SRobert Watson ptrmoved = 1; 343ca0716f5SRobert Watson if (fp != NULL) { 344ca0716f5SRobert Watson fclose(fp); 345ca0716f5SRobert Watson fp = NULL; 346ca0716f5SRobert Watson } 3477a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 348ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 3497a0a89d2SRobert Watson #endif 350ca0716f5SRobert Watson } 351ca0716f5SRobert Watson 352ca0716f5SRobert Watson /* 353ca0716f5SRobert Watson * Return audit directory information from the audit control file. 354ca0716f5SRobert Watson */ 355ca0716f5SRobert Watson int 356ca0716f5SRobert Watson getacdir(char *name, int len) 357ca0716f5SRobert Watson { 358ca0716f5SRobert Watson char *dir; 359ca0716f5SRobert Watson int ret = 0; 360ca0716f5SRobert Watson 361ca0716f5SRobert Watson /* 362bb97b418SRobert Watson * Check if another function was called between successive calls to 363bb97b418SRobert Watson * getacdir. 364ca0716f5SRobert Watson */ 3657a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 366bb97b418SRobert Watson pthread_mutex_lock(&mutex); 3677a0a89d2SRobert Watson #endif 368ca0716f5SRobert Watson if (inacdir && ptrmoved) { 369ca0716f5SRobert Watson ptrmoved = 0; 370ca0716f5SRobert Watson if (fp != NULL) 371ca0716f5SRobert Watson fseek(fp, 0, SEEK_SET); 372ca0716f5SRobert Watson ret = 2; 373ca0716f5SRobert Watson } 374ca0716f5SRobert Watson if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) { 3757a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 376ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 3777a0a89d2SRobert Watson #endif 378ca0716f5SRobert Watson return (-2); 379ca0716f5SRobert Watson } 380bb97b418SRobert Watson if (dir == NULL) { 3817a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 382ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 3837a0a89d2SRobert Watson #endif 384ca0716f5SRobert Watson return (-1); 385bb97b418SRobert Watson } 38652267f74SRobert Watson if (strlen(dir) >= (size_t)len) { 3877a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 388bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 3897a0a89d2SRobert Watson #endif 390ca0716f5SRobert Watson return (-3); 391bb97b418SRobert Watson } 39252267f74SRobert Watson strlcpy(name, dir, len); 3937a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 394bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 3957a0a89d2SRobert Watson #endif 396ca0716f5SRobert Watson return (ret); 397ca0716f5SRobert Watson } 398ca0716f5SRobert Watson 399ca0716f5SRobert Watson /* 400bb97b418SRobert Watson * Return the minimum free diskspace value from the audit control file. 401ca0716f5SRobert Watson */ 402ca0716f5SRobert Watson int 403ca0716f5SRobert Watson getacmin(int *min_val) 404ca0716f5SRobert Watson { 405ca0716f5SRobert Watson char *min; 406ca0716f5SRobert Watson 4077a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 408ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 4097a0a89d2SRobert Watson #endif 410bb97b418SRobert Watson setac_locked(); 411ca0716f5SRobert Watson if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) { 4127a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 413ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 4147a0a89d2SRobert Watson #endif 415ca0716f5SRobert Watson return (-2); 416ca0716f5SRobert Watson } 417bb97b418SRobert Watson if (min == NULL) { 4187a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 419ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 4207a0a89d2SRobert Watson #endif 421ca0716f5SRobert Watson return (1); 422bb97b418SRobert Watson } 423ca0716f5SRobert Watson *min_val = atoi(min); 4247a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 425bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 4267a0a89d2SRobert Watson #endif 427ca0716f5SRobert Watson return (0); 428ca0716f5SRobert Watson } 429ca0716f5SRobert Watson 430ca0716f5SRobert Watson /* 4314bd0c025SRobert Watson * Return the desired trail rotation size from the audit control file. 4324bd0c025SRobert Watson */ 4334bd0c025SRobert Watson int 4344bd0c025SRobert Watson getacfilesz(size_t *filesz_val) 4354bd0c025SRobert Watson { 43606edd2f1SRobert Watson char *str; 43706edd2f1SRobert Watson size_t val; 43806edd2f1SRobert Watson char mult; 43906edd2f1SRobert Watson int nparsed; 4404bd0c025SRobert Watson 4417a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4424bd0c025SRobert Watson pthread_mutex_lock(&mutex); 4437a0a89d2SRobert Watson #endif 4444bd0c025SRobert Watson setac_locked(); 44506edd2f1SRobert Watson if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { 4467a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4474bd0c025SRobert Watson pthread_mutex_unlock(&mutex); 4487a0a89d2SRobert Watson #endif 4494bd0c025SRobert Watson return (-2); 4504bd0c025SRobert Watson } 45106edd2f1SRobert Watson if (str == NULL) { 4527a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4534bd0c025SRobert Watson pthread_mutex_unlock(&mutex); 4547a0a89d2SRobert Watson #endif 4554bd0c025SRobert Watson errno = EINVAL; 4564bd0c025SRobert Watson return (1); 4574bd0c025SRobert Watson } 45806edd2f1SRobert Watson 45906edd2f1SRobert Watson /* Trim off any leading white space. */ 46006edd2f1SRobert Watson while (*str == ' ' || *str == '\t') 46106edd2f1SRobert Watson str++; 46206edd2f1SRobert Watson 46306edd2f1SRobert Watson nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult); 46406edd2f1SRobert Watson 46506edd2f1SRobert Watson switch (nparsed) { 46606edd2f1SRobert Watson case 1: 46706edd2f1SRobert Watson /* If no multiplier then assume 'B' (bytes). */ 46806edd2f1SRobert Watson mult = 'B'; 46906edd2f1SRobert Watson /* fall through */ 47006edd2f1SRobert Watson case 2: 47106edd2f1SRobert Watson if (au_spacetobytes(filesz_val, val, mult) == 0) 47206edd2f1SRobert Watson break; 47306edd2f1SRobert Watson /* fall through */ 47406edd2f1SRobert Watson default: 47506edd2f1SRobert Watson errno = EINVAL; 4767a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4774bd0c025SRobert Watson pthread_mutex_unlock(&mutex); 4787a0a89d2SRobert Watson #endif 4794bd0c025SRobert Watson return (-1); 4804bd0c025SRobert Watson } 48106edd2f1SRobert Watson 4824bd0c025SRobert Watson /* 4834bd0c025SRobert Watson * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 4844bd0c025SRobert Watson * indicates no rotation size. 4854bd0c025SRobert Watson */ 48606edd2f1SRobert Watson if (*filesz_val < 0 || (*filesz_val > 0 && 48706edd2f1SRobert Watson *filesz_val < MIN_AUDIT_FILE_SIZE)) { 4887a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4894bd0c025SRobert Watson pthread_mutex_unlock(&mutex); 4907a0a89d2SRobert Watson #endif 49106edd2f1SRobert Watson filesz_val = 0L; 4924bd0c025SRobert Watson errno = EINVAL; 4934bd0c025SRobert Watson return (-1); 4944bd0c025SRobert Watson } 4957a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 4964bd0c025SRobert Watson pthread_mutex_unlock(&mutex); 4977a0a89d2SRobert Watson #endif 4984bd0c025SRobert Watson return (0); 4994bd0c025SRobert Watson } 5004bd0c025SRobert Watson 5014bd0c025SRobert Watson /* 502ca0716f5SRobert Watson * Return the system audit value from the audit contol file. 503ca0716f5SRobert Watson */ 504ca0716f5SRobert Watson int 505ca0716f5SRobert Watson getacflg(char *auditstr, int len) 506ca0716f5SRobert Watson { 507ca0716f5SRobert Watson char *str; 508ca0716f5SRobert Watson 5097a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 510ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 5117a0a89d2SRobert Watson #endif 512bb97b418SRobert Watson setac_locked(); 513ca0716f5SRobert Watson if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) { 5147a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 515ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 5167a0a89d2SRobert Watson #endif 517ca0716f5SRobert Watson return (-2); 518ca0716f5SRobert Watson } 519bb97b418SRobert Watson if (str == NULL) { 5207a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 521ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 5227a0a89d2SRobert Watson #endif 523ca0716f5SRobert Watson return (1); 524bb97b418SRobert Watson } 52552267f74SRobert Watson if (strlen(str) >= (size_t)len) { 5267a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 527bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 5287a0a89d2SRobert Watson #endif 529ca0716f5SRobert Watson return (-3); 530bb97b418SRobert Watson } 53152267f74SRobert Watson strlcpy(auditstr, str, len); 5327a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 533bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 5347a0a89d2SRobert Watson #endif 535ca0716f5SRobert Watson return (0); 536ca0716f5SRobert Watson } 537ca0716f5SRobert Watson 538ca0716f5SRobert Watson /* 539ca0716f5SRobert Watson * Return the non attributable flags from the audit contol file. 540ca0716f5SRobert Watson */ 541ca0716f5SRobert Watson int 542ca0716f5SRobert Watson getacna(char *auditstr, int len) 543ca0716f5SRobert Watson { 544ca0716f5SRobert Watson char *str; 545ca0716f5SRobert Watson 5467a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 547ca0716f5SRobert Watson pthread_mutex_lock(&mutex); 5487a0a89d2SRobert Watson #endif 549bb97b418SRobert Watson setac_locked(); 550ca0716f5SRobert Watson if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) { 5517a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 552ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 5537a0a89d2SRobert Watson #endif 554ca0716f5SRobert Watson return (-2); 555ca0716f5SRobert Watson } 556bb97b418SRobert Watson if (str == NULL) { 5577a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 558ca0716f5SRobert Watson pthread_mutex_unlock(&mutex); 5597a0a89d2SRobert Watson #endif 560ca0716f5SRobert Watson return (1); 561bb97b418SRobert Watson } 56252267f74SRobert Watson if (strlen(str) >= (size_t)len) { 5637a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 564bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 5657a0a89d2SRobert Watson #endif 566ca0716f5SRobert Watson return (-3); 567bb97b418SRobert Watson } 56852267f74SRobert Watson strlcpy(auditstr, str, len); 5697a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 57052267f74SRobert Watson pthread_mutex_unlock(&mutex); 5717a0a89d2SRobert Watson #endif 572bb97b418SRobert Watson return (0); 573bb97b418SRobert Watson } 574ca0716f5SRobert Watson 575bb97b418SRobert Watson /* 576bb97b418SRobert Watson * Return the policy field from the audit control file. 577bb97b418SRobert Watson */ 578bb97b418SRobert Watson int 579bb97b418SRobert Watson getacpol(char *auditstr, size_t len) 580bb97b418SRobert Watson { 581bb97b418SRobert Watson char *str; 582bb97b418SRobert Watson 5837a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 584bb97b418SRobert Watson pthread_mutex_lock(&mutex); 5857a0a89d2SRobert Watson #endif 586bb97b418SRobert Watson setac_locked(); 587bb97b418SRobert Watson if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) { 5887a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 589bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 5907a0a89d2SRobert Watson #endif 591bb97b418SRobert Watson return (-2); 592bb97b418SRobert Watson } 593bb97b418SRobert Watson if (str == NULL) { 5947a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 595bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 5967a0a89d2SRobert Watson #endif 597bb97b418SRobert Watson return (-1); 598bb97b418SRobert Watson } 599bb97b418SRobert Watson if (strlen(str) >= len) { 6007a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 601bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 6027a0a89d2SRobert Watson #endif 603bb97b418SRobert Watson return (-3); 604bb97b418SRobert Watson } 60552267f74SRobert Watson strlcpy(auditstr, str, len); 6067a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 60752267f74SRobert Watson pthread_mutex_unlock(&mutex); 6087a0a89d2SRobert Watson #endif 60952267f74SRobert Watson return (0); 61052267f74SRobert Watson } 61152267f74SRobert Watson 61252267f74SRobert Watson int 61352267f74SRobert Watson getachost(char *auditstr, size_t len) 61452267f74SRobert Watson { 61552267f74SRobert Watson char *str; 61652267f74SRobert Watson 6177a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 61852267f74SRobert Watson pthread_mutex_lock(&mutex); 6197a0a89d2SRobert Watson #endif 62052267f74SRobert Watson setac_locked(); 62152267f74SRobert Watson if (getstrfromtype_locked(AUDIT_HOST_CONTROL_ENTRY, &str) < 0) { 6227a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 62352267f74SRobert Watson pthread_mutex_unlock(&mutex); 6247a0a89d2SRobert Watson #endif 62552267f74SRobert Watson return (-2); 62652267f74SRobert Watson } 62752267f74SRobert Watson if (str == NULL) { 6287a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 62952267f74SRobert Watson pthread_mutex_unlock(&mutex); 6307a0a89d2SRobert Watson #endif 63152267f74SRobert Watson return (1); 63252267f74SRobert Watson } 63352267f74SRobert Watson if (strlen(str) >= len) { 6347a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 63552267f74SRobert Watson pthread_mutex_unlock(&mutex); 6367a0a89d2SRobert Watson #endif 63752267f74SRobert Watson return (-3); 63852267f74SRobert Watson } 63906edd2f1SRobert Watson strlcpy(auditstr, str, len); 64006edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 64106edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 64206edd2f1SRobert Watson #endif 64306edd2f1SRobert Watson return (0); 64406edd2f1SRobert Watson } 64506edd2f1SRobert Watson 64606edd2f1SRobert Watson /* 64706edd2f1SRobert Watson * Set expiration conditions. 64806edd2f1SRobert Watson */ 64906edd2f1SRobert Watson static int 65006edd2f1SRobert Watson setexpirecond(time_t *age, size_t *size, u_long value, char mult) 65106edd2f1SRobert Watson { 65206edd2f1SRobert Watson 65306edd2f1SRobert Watson if (isupper(mult) || ' ' == mult) 65406edd2f1SRobert Watson return (au_spacetobytes(size, value, mult)); 65506edd2f1SRobert Watson else 65606edd2f1SRobert Watson return (au_timetosec(age, value, mult)); 65706edd2f1SRobert Watson } 65806edd2f1SRobert Watson 65906edd2f1SRobert Watson /* 66006edd2f1SRobert Watson * Return the expire-after field from the audit control file. 66106edd2f1SRobert Watson */ 66206edd2f1SRobert Watson int 66306edd2f1SRobert Watson getacexpire(int *andflg, time_t *age, size_t *size) 66406edd2f1SRobert Watson { 66506edd2f1SRobert Watson char *str; 66606edd2f1SRobert Watson int nparsed; 66706edd2f1SRobert Watson u_long val1, val2; 66806edd2f1SRobert Watson char mult1, mult2; 66906edd2f1SRobert Watson char andor[AU_LINE_MAX]; 67006edd2f1SRobert Watson 67106edd2f1SRobert Watson *age = 0L; 67206edd2f1SRobert Watson *size = 0LL; 67306edd2f1SRobert Watson *andflg = 0; 67406edd2f1SRobert Watson 67506edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 67606edd2f1SRobert Watson pthread_mutex_lock(&mutex); 67706edd2f1SRobert Watson #endif 67806edd2f1SRobert Watson setac_locked(); 67906edd2f1SRobert Watson if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) { 68006edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 68106edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 68206edd2f1SRobert Watson #endif 68306edd2f1SRobert Watson return (-2); 68406edd2f1SRobert Watson } 68506edd2f1SRobert Watson if (str == NULL) { 68606edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 68706edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 68806edd2f1SRobert Watson #endif 68906edd2f1SRobert Watson return (1); 69006edd2f1SRobert Watson } 69106edd2f1SRobert Watson 69206edd2f1SRobert Watson /* First, trim off any leading white space. */ 69306edd2f1SRobert Watson while (*str == ' ' || *str == '\t') 69406edd2f1SRobert Watson str++; 69506edd2f1SRobert Watson 69606edd2f1SRobert Watson nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, 69706edd2f1SRobert Watson andor, &val2, &mult2); 69806edd2f1SRobert Watson 69906edd2f1SRobert Watson switch (nparsed) { 70006edd2f1SRobert Watson case 1: 70106edd2f1SRobert Watson /* If no multiplier then assume 'B' (Bytes). */ 70206edd2f1SRobert Watson mult1 = 'B'; 70306edd2f1SRobert Watson /* fall through */ 70406edd2f1SRobert Watson case 2: 70506edd2f1SRobert Watson /* One expiration condition. */ 70606edd2f1SRobert Watson if (setexpirecond(age, size, val1, mult1) != 0) { 70706edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 70806edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 70906edd2f1SRobert Watson #endif 71006edd2f1SRobert Watson return (-1); 71106edd2f1SRobert Watson } 71206edd2f1SRobert Watson break; 71306edd2f1SRobert Watson 71406edd2f1SRobert Watson case 5: 71506edd2f1SRobert Watson /* Two expiration conditions. */ 71606edd2f1SRobert Watson if (setexpirecond(age, size, val1, mult1) != 0 || 71706edd2f1SRobert Watson setexpirecond(age, size, val2, mult2) != 0) { 71806edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 71906edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 72006edd2f1SRobert Watson #endif 72106edd2f1SRobert Watson return (-1); 72206edd2f1SRobert Watson } 72306edd2f1SRobert Watson if (strcasestr(andor, "and") != NULL) 72406edd2f1SRobert Watson *andflg = 1; 72506edd2f1SRobert Watson else if (strcasestr(andor, "or") != NULL) 72606edd2f1SRobert Watson *andflg = 0; 72706edd2f1SRobert Watson else { 72806edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 72906edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 73006edd2f1SRobert Watson #endif 73106edd2f1SRobert Watson return (-1); 73206edd2f1SRobert Watson } 73306edd2f1SRobert Watson break; 73406edd2f1SRobert Watson 73506edd2f1SRobert Watson default: 73606edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 73706edd2f1SRobert Watson pthread_mutex_unlock(&mutex); 73806edd2f1SRobert Watson #endif 73906edd2f1SRobert Watson return (-1); 74006edd2f1SRobert Watson } 74106edd2f1SRobert Watson 7427a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK 743bb97b418SRobert Watson pthread_mutex_unlock(&mutex); 7447a0a89d2SRobert Watson #endif 745ca0716f5SRobert Watson return (0); 746ca0716f5SRobert Watson } 747