1/*- |
2 * Copyright (c) 2004,2009 Apple Inc. |
3 * Copyright (c) 2006 Robert N. M. Watson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. --- 11 unchanged lines hidden (view full) --- 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 * |
30 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#28 $ |
31 */ 32 33#include <config/config.h> 34 35#include <bsm/libbsm.h> 36 |
37#include <ctype.h> |
38#include <errno.h> 39#include <string.h> 40#ifdef HAVE_PTHREAD_MUTEX_LOCK 41#include <pthread.h> 42#endif 43#include <stdio.h> 44#include <stdlib.h> 45 --- 15 unchanged lines hidden (view full) --- 61static char inacdir = 0; 62static char ptrmoved = 0; 63 64#ifdef HAVE_PTHREAD_MUTEX_LOCK 65static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 66#endif 67 68/* |
69 * Audit policy string token table for au_poltostr() and au_strtopol(). 70 */ 71struct audit_polstr { 72 long ap_policy; 73 const char *ap_str; 74}; 75 76static struct audit_polstr au_polstr[] = { 77 { AUDIT_CNT, "cnt" }, 78 { AUDIT_AHLT, "ahlt" }, 79 { AUDIT_ARGV, "argv" }, 80 { AUDIT_ARGE, "arge" }, 81 { AUDIT_SEQ, "seq" }, 82 { AUDIT_WINDATA, "windata" }, 83 { AUDIT_USER, "user" }, 84 { AUDIT_GROUP, "group" }, 85 { AUDIT_TRAIL, "trail" }, 86 { AUDIT_PATH, "path" }, 87 { AUDIT_SCNT, "scnt" }, 88 { AUDIT_PUBLIC, "public" }, 89 { AUDIT_ZONENAME, "zonename" }, 90 { AUDIT_PERZONE, "perzone" }, 91 { -1, NULL } 92}; 93 94/* |
95 * Returns the string value corresponding to the given label from the 96 * configuration file. 97 * 98 * Must be called with mutex held. 99 */ 100static int 101getstrfromtype_locked(char *name, char **str) 102{ --- 31 unchanged lines hidden (view full) --- 134 } 135 return (0); /* Success */ 136 } 137 } 138 } 139} 140 141/* |
142 * Convert a given time value with a multiplier (seconds, hours, days, years) to 143 * seconds. Return 0 on success. 144 */ 145static int 146au_timetosec(time_t *seconds, u_long value, char mult) 147{ 148 if (NULL == seconds) 149 return (-1); 150 151 switch(mult) { 152 case 's': 153 /* seconds */ 154 *seconds = (time_t)value; 155 break; 156 157 case 'h': 158 /* hours */ 159 *seconds = (time_t)value * 60 * 60; 160 break; 161 162 case 'd': 163 /* days */ 164 *seconds = (time_t)value * 60 * 60 * 24; 165 break; 166 167 case 'y': 168 /* years. Add a day for each 4th (leap) year. */ 169 *seconds = (time_t)value * 60 * 60 * 24 * 364 + 170 ((time_t)value / 4) * 60 * 60 * 24; 171 break; 172 173 default: 174 return (-1); 175 } 176 return (0); 177} 178 179/* 180 * Convert a given disk space value with a multiplier (bytes, kilobytes, 181 * megabytes, gigabytes) to bytes. Return 0 on success. 182 */ 183static int 184au_spacetobytes(size_t *bytes, u_long value, char mult) 185{ 186 if (NULL == bytes) 187 return (-1); 188 189 switch(mult) { 190 case 'B': 191 case ' ': 192 /* Bytes */ 193 *bytes = (size_t)value; 194 break; 195 196 case 'K': 197 /* Kilobytes */ 198 *bytes = (size_t)value * 1024; 199 break; 200 201 case 'M': 202 /* Megabytes */ 203 *bytes = (size_t)value * 1024 * 1024; 204 break; 205 206 case 'G': 207 /* Gigabytes */ 208 *bytes = (size_t)value * 1024 * 1024 * 1024; 209 break; 210 211 default: 212 return (-1); 213 } 214 return (0); 215} 216 217/* |
218 * Convert a policy to a string. Return -1 on failure, or >= 0 representing 219 * the actual size of the string placed in the buffer (excluding terminating 220 * nul). 221 */ 222ssize_t 223au_poltostr(long policy, size_t maxsize, char *buf) 224{ |
225 int first = 1; 226 int i = 0; |
227 228 if (maxsize < 1) 229 return (-1); |
230 buf[0] = '\0'; 231 |
232 do { 233 if (policy & au_polstr[i].ap_policy) { 234 if (!first && strlcat(buf, ",", maxsize) >= maxsize) |
235 return (-1); |
236 if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= 237 maxsize) |
238 return (-1); |
239 first = 0; |
240 } |
241 } while (NULL != au_polstr[++i].ap_str); 242 |
243 return (strlen(buf)); 244} 245 246/* 247 * Convert a string to a policy. Return -1 on failure (with errno EINVAL, 248 * ENOMEM) or 0 on success. 249 */ 250int 251au_strtopol(const char *polstr, long *policy) 252{ 253 char *bufp, *string; 254 char *buffer; |
255 int i, matched; |
256 257 *policy = 0; 258 buffer = strdup(polstr); 259 if (buffer == NULL) 260 return (-1); 261 262 bufp = buffer; 263 while ((string = strsep(&bufp, ",")) != NULL) { |
264 matched = i = 0; 265 266 do { 267 if (strcmp(string, au_polstr[i].ap_str) == 0) { 268 *policy |= au_polstr[i].ap_policy; 269 matched = 1; 270 break; 271 } 272 } while (NULL != au_polstr[++i].ap_str); 273 274 if (!matched) { |
275 free(buffer); 276 errno = EINVAL; 277 return (-1); 278 } 279 } 280 free(buffer); 281 return (0); 282} --- 122 unchanged lines hidden (view full) --- 405} 406 407/* 408 * Return the desired trail rotation size from the audit control file. 409 */ 410int 411getacfilesz(size_t *filesz_val) 412{ |
413 char *str; 414 size_t val; 415 char mult; 416 int nparsed; |
417 418#ifdef HAVE_PTHREAD_MUTEX_LOCK 419 pthread_mutex_lock(&mutex); 420#endif 421 setac_locked(); |
422 if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { |
423#ifdef HAVE_PTHREAD_MUTEX_LOCK 424 pthread_mutex_unlock(&mutex); 425#endif 426 return (-2); 427 } |
428 if (str == NULL) { |
429#ifdef HAVE_PTHREAD_MUTEX_LOCK 430 pthread_mutex_unlock(&mutex); 431#endif 432 errno = EINVAL; 433 return (1); 434 } |
435 436 /* Trim off any leading white space. */ 437 while (*str == ' ' || *str == '\t') 438 str++; 439 440 nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult); 441 442 switch (nparsed) { 443 case 1: 444 /* If no multiplier then assume 'B' (bytes). */ 445 mult = 'B'; 446 /* fall through */ 447 case 2: 448 if (au_spacetobytes(filesz_val, val, mult) == 0) 449 break; 450 /* fall through */ 451 default: 452 errno = EINVAL; |
453#ifdef HAVE_PTHREAD_MUTEX_LOCK 454 pthread_mutex_unlock(&mutex); 455#endif |
456 return (-1); 457 } |
458 |
459 /* 460 * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 461 * indicates no rotation size. 462 */ |
463 if (*filesz_val < 0 || (*filesz_val > 0 && 464 *filesz_val < MIN_AUDIT_FILE_SIZE)) { |
465#ifdef HAVE_PTHREAD_MUTEX_LOCK 466 pthread_mutex_unlock(&mutex); 467#endif |
468 filesz_val = 0L; |
469 errno = EINVAL; 470 return (-1); 471 } |
472#ifdef HAVE_PTHREAD_MUTEX_LOCK 473 pthread_mutex_unlock(&mutex); 474#endif 475 return (0); 476} 477 478/* 479 * Return the system audit value from the audit contol file. --- 128 unchanged lines hidden (view full) --- 608 return (1); 609 } 610 if (strlen(str) >= len) { 611#ifdef HAVE_PTHREAD_MUTEX_LOCK 612 pthread_mutex_unlock(&mutex); 613#endif 614 return (-3); 615 } |
616 strlcpy(auditstr, str, len); |
617#ifdef HAVE_PTHREAD_MUTEX_LOCK 618 pthread_mutex_unlock(&mutex); 619#endif 620 return (0); 621} |
622 623/* 624 * Set expiration conditions. 625 */ 626static int 627setexpirecond(time_t *age, size_t *size, u_long value, char mult) 628{ 629 630 if (isupper(mult) || ' ' == mult) 631 return (au_spacetobytes(size, value, mult)); 632 else 633 return (au_timetosec(age, value, mult)); 634} 635 636/* 637 * Return the expire-after field from the audit control file. 638 */ 639int 640getacexpire(int *andflg, time_t *age, size_t *size) 641{ 642 char *str; 643 int nparsed; 644 u_long val1, val2; 645 char mult1, mult2; 646 char andor[AU_LINE_MAX]; 647 648 *age = 0L; 649 *size = 0LL; 650 *andflg = 0; 651 652#ifdef HAVE_PTHREAD_MUTEX_LOCK 653 pthread_mutex_lock(&mutex); 654#endif 655 setac_locked(); 656 if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) { 657#ifdef HAVE_PTHREAD_MUTEX_LOCK 658 pthread_mutex_unlock(&mutex); 659#endif 660 return (-2); 661 } 662 if (str == NULL) { 663#ifdef HAVE_PTHREAD_MUTEX_LOCK 664 pthread_mutex_unlock(&mutex); 665#endif 666 return (1); 667 } 668 669 /* First, trim off any leading white space. */ 670 while (*str == ' ' || *str == '\t') 671 str++; 672 673 nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1, 674 andor, &val2, &mult2); 675 676 switch (nparsed) { 677 case 1: 678 /* If no multiplier then assume 'B' (Bytes). */ 679 mult1 = 'B'; 680 /* fall through */ 681 case 2: 682 /* One expiration condition. */ 683 if (setexpirecond(age, size, val1, mult1) != 0) { 684#ifdef HAVE_PTHREAD_MUTEX_LOCK 685 pthread_mutex_unlock(&mutex); 686#endif 687 return (-1); 688 } 689 break; 690 691 case 5: 692 /* Two expiration conditions. */ 693 if (setexpirecond(age, size, val1, mult1) != 0 || 694 setexpirecond(age, size, val2, mult2) != 0) { 695#ifdef HAVE_PTHREAD_MUTEX_LOCK 696 pthread_mutex_unlock(&mutex); 697#endif 698 return (-1); 699 } 700 if (strcasestr(andor, "and") != NULL) 701 *andflg = 1; 702 else if (strcasestr(andor, "or") != NULL) 703 *andflg = 0; 704 else { 705#ifdef HAVE_PTHREAD_MUTEX_LOCK 706 pthread_mutex_unlock(&mutex); 707#endif 708 return (-1); 709 } 710 break; 711 712 default: 713#ifdef HAVE_PTHREAD_MUTEX_LOCK 714 pthread_mutex_unlock(&mutex); 715#endif 716 return (-1); 717 } 718 719#ifdef HAVE_PTHREAD_MUTEX_LOCK 720 pthread_mutex_unlock(&mutex); 721#endif 722 return (0); 723} |