bsm_control.c (186647) | bsm_control.c (189279) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2004 Apple Inc. | 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 * | 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#24 $ | 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 | 31 */ 32 33#include <config/config.h> 34 35#include <bsm/libbsm.h> 36 |
37#include <ctype.h> |
|
37#include <errno.h> 38#include <string.h> 39#ifdef HAVE_PTHREAD_MUTEX_LOCK 40#include <pthread.h> 41#endif 42#include <stdio.h> 43#include <stdlib.h> 44 --- 15 unchanged lines hidden (view full) --- 60static char inacdir = 0; 61static char ptrmoved = 0; 62 63#ifdef HAVE_PTHREAD_MUTEX_LOCK 64static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 65#endif 66 67/* | 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/* |
|
68 * Returns the string value corresponding to the given label from the 69 * configuration file. 70 * 71 * Must be called with mutex held. 72 */ 73static int 74getstrfromtype_locked(char *name, char **str) 75{ --- 31 unchanged lines hidden (view full) --- 107 } 108 return (0); /* Success */ 109 } 110 } 111 } 112} 113 114/* | 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/* |
|
115 * Convert a policy to a string. Return -1 on failure, or >= 0 representing 116 * the actual size of the string placed in the buffer (excluding terminating 117 * nul). 118 */ 119ssize_t 120au_poltostr(long policy, size_t maxsize, char *buf) 121{ | 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{ |
122 int first; | 225 int first = 1; 226 int i = 0; |
123 124 if (maxsize < 1) 125 return (-1); | 227 228 if (maxsize < 1) 229 return (-1); |
126 first = 1; | |
127 buf[0] = '\0'; 128 | 230 buf[0] = '\0'; 231 |
129 if (policy & AUDIT_CNT) { 130 if (strlcat(buf, "cnt", maxsize) >= maxsize) 131 return (-1); 132 first = 0; 133 } 134 if (policy & AUDIT_AHLT) { 135 if (!first) { 136 if (strlcat(buf, ",", maxsize) >= maxsize) | 232 do { 233 if (policy & au_polstr[i].ap_policy) { 234 if (!first && strlcat(buf, ",", maxsize) >= maxsize) |
137 return (-1); | 235 return (-1); |
138 } 139 if (strlcat(buf, "ahlt", maxsize) >= maxsize) 140 return (-1); 141 first = 0; 142 } 143 if (policy & AUDIT_ARGV) { 144 if (!first) { 145 if (strlcat(buf, ",", maxsize) >= maxsize) | 236 if (strlcat(buf, au_polstr[i].ap_str, maxsize) >= 237 maxsize) |
146 return (-1); | 238 return (-1); |
239 first = 0; |
|
147 } | 240 } |
148 if (strlcat(buf, "argv", maxsize) >= maxsize) 149 return (-1); 150 first = 0; 151 } 152 if (policy & AUDIT_ARGE) { 153 if (!first) { 154 if (strlcat(buf, ",", maxsize) >= maxsize) 155 return (-1); 156 } 157 if (strlcat(buf, "arge", maxsize) >= maxsize) 158 return (-1); 159 first = 0; 160 } 161 if (policy & AUDIT_SEQ) { 162 if (!first) { 163 if (strlcat(buf, ",", maxsize) >= maxsize) 164 return (-1); 165 } 166 if (strlcat(buf, "seq", maxsize) >= maxsize) 167 return (-1); 168 first = 0; 169 } 170 if (policy & AUDIT_WINDATA) { 171 if (!first) { 172 if (strlcat(buf, ",", maxsize) >= maxsize) 173 return (-1); 174 } 175 if (strlcat(buf, "windata", maxsize) >= maxsize) 176 return (-1); 177 first = 0; 178 } 179 if (policy & AUDIT_USER) { 180 if (!first) { 181 if (strlcat(buf, ",", maxsize) >= maxsize) 182 return (-1); 183 } 184 if (strlcat(buf, "user", maxsize) >= maxsize) 185 return (-1); 186 first = 0; 187 } 188 if (policy & AUDIT_GROUP) { 189 if (!first) { 190 if (strlcat(buf, ",", maxsize) >= maxsize) 191 return (-1); 192 } 193 if (strlcat(buf, "group", maxsize) >= maxsize) 194 return (-1); 195 first = 0; 196 } 197 if (policy & AUDIT_TRAIL) { 198 if (!first) { 199 if (strlcat(buf, ",", maxsize) >= maxsize) 200 return (-1); 201 } 202 if (strlcat(buf, "trail", maxsize) >= maxsize) 203 return (-1); 204 first = 0; 205 } 206 if (policy & AUDIT_PATH) { 207 if (!first) { 208 if (strlcat(buf, ",", maxsize) >= maxsize) 209 return (-1); 210 } 211 if (strlcat(buf, "path", maxsize) >= maxsize) 212 return (-1); 213 first = 0; 214 } 215 if (policy & AUDIT_SCNT) { 216 if (!first) { 217 if (strlcat(buf, ",", maxsize) >= maxsize) 218 return (-1); 219 } 220 if (strlcat(buf, "scnt", maxsize) >= maxsize) 221 return (-1); 222 first = 0; 223 } 224 if (policy & AUDIT_PUBLIC) { 225 if (!first) { 226 if (strlcat(buf, ",", maxsize) >= maxsize) 227 return (-1); 228 } 229 if (strlcat(buf, "public", maxsize) >= maxsize) 230 return (-1); 231 first = 0; 232 } 233 if (policy & AUDIT_ZONENAME) { 234 if (!first) { 235 if (strlcat(buf, ",", maxsize) >= maxsize) 236 return (-1); 237 } 238 if (strlcat(buf, "zonename", maxsize) >= maxsize) 239 return (-1); 240 first = 0; 241 } 242 if (policy & AUDIT_PERZONE) { 243 if (!first) { 244 if (strlcat(buf, ",", maxsize) >= maxsize) 245 return (-1); 246 } 247 if (strlcat(buf, "perzone", maxsize) >= maxsize) 248 return (-1); 249 first = 0; 250 } | 241 } while (NULL != au_polstr[++i].ap_str); 242 |
251 return (strlen(buf)); 252} 253 254/* 255 * Convert a string to a policy. Return -1 on failure (with errno EINVAL, 256 * ENOMEM) or 0 on success. 257 */ 258int 259au_strtopol(const char *polstr, long *policy) 260{ 261 char *bufp, *string; 262 char *buffer; | 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; |
|
263 264 *policy = 0; 265 buffer = strdup(polstr); 266 if (buffer == NULL) 267 return (-1); 268 269 bufp = buffer; 270 while ((string = strsep(&bufp, ",")) != NULL) { | 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) { |
271 if (strcmp(string, "cnt") == 0) 272 *policy |= AUDIT_CNT; 273 else if (strcmp(string, "ahlt") == 0) 274 *policy |= AUDIT_AHLT; 275 else if (strcmp(string, "argv") == 0) 276 *policy |= AUDIT_ARGV; 277 else if (strcmp(string, "arge") == 0) 278 *policy |= AUDIT_ARGE; 279 else if (strcmp(string, "seq") == 0) 280 *policy |= AUDIT_SEQ; 281 else if (strcmp(string, "winau_fstat") == 0) 282 *policy |= AUDIT_WINDATA; 283 else if (strcmp(string, "user") == 0) 284 *policy |= AUDIT_USER; 285 else if (strcmp(string, "group") == 0) 286 *policy |= AUDIT_GROUP; 287 else if (strcmp(string, "trail") == 0) 288 *policy |= AUDIT_TRAIL; 289 else if (strcmp(string, "path") == 0) 290 *policy |= AUDIT_PATH; 291 else if (strcmp(string, "scnt") == 0) 292 *policy |= AUDIT_SCNT; 293 else if (strcmp(string, "public") == 0) 294 *policy |= AUDIT_PUBLIC; 295 else if (strcmp(string, "zonename") == 0) 296 *policy |= AUDIT_ZONENAME; 297 else if (strcmp(string, "perzone") == 0) 298 *policy |= AUDIT_PERZONE; 299 else { | 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) { |
300 free(buffer); 301 errno = EINVAL; 302 return (-1); 303 } 304 } 305 free(buffer); 306 return (0); 307} --- 122 unchanged lines hidden (view full) --- 430} 431 432/* 433 * Return the desired trail rotation size from the audit control file. 434 */ 435int 436getacfilesz(size_t *filesz_val) 437{ | 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{ |
438 char *filesz, *dummy; 439 long long ll; | 413 char *str; 414 size_t val; 415 char mult; 416 int nparsed; |
440 441#ifdef HAVE_PTHREAD_MUTEX_LOCK 442 pthread_mutex_lock(&mutex); 443#endif 444 setac_locked(); | 417 418#ifdef HAVE_PTHREAD_MUTEX_LOCK 419 pthread_mutex_lock(&mutex); 420#endif 421 setac_locked(); |
445 if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &filesz) < 0) { | 422 if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) { |
446#ifdef HAVE_PTHREAD_MUTEX_LOCK 447 pthread_mutex_unlock(&mutex); 448#endif 449 return (-2); 450 } | 423#ifdef HAVE_PTHREAD_MUTEX_LOCK 424 pthread_mutex_unlock(&mutex); 425#endif 426 return (-2); 427 } |
451 if (filesz == NULL) { | 428 if (str == NULL) { |
452#ifdef HAVE_PTHREAD_MUTEX_LOCK 453 pthread_mutex_unlock(&mutex); 454#endif 455 errno = EINVAL; 456 return (1); 457 } | 429#ifdef HAVE_PTHREAD_MUTEX_LOCK 430 pthread_mutex_unlock(&mutex); 431#endif 432 errno = EINVAL; 433 return (1); 434 } |
458 ll = strtoll(filesz, &dummy, 10); 459 if (*dummy != '\0') { | 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; |
460#ifdef HAVE_PTHREAD_MUTEX_LOCK 461 pthread_mutex_unlock(&mutex); 462#endif | 453#ifdef HAVE_PTHREAD_MUTEX_LOCK 454 pthread_mutex_unlock(&mutex); 455#endif |
463 errno = EINVAL; | |
464 return (-1); 465 } | 456 return (-1); 457 } |
458 |
|
466 /* 467 * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 468 * indicates no rotation size. 469 */ | 459 /* 460 * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0 461 * indicates no rotation size. 462 */ |
470 if (ll < 0 || (ll > 0 && ll < MIN_AUDIT_FILE_SIZE)) { | 463 if (*filesz_val < 0 || (*filesz_val > 0 && 464 *filesz_val < MIN_AUDIT_FILE_SIZE)) { |
471#ifdef HAVE_PTHREAD_MUTEX_LOCK 472 pthread_mutex_unlock(&mutex); 473#endif | 465#ifdef HAVE_PTHREAD_MUTEX_LOCK 466 pthread_mutex_unlock(&mutex); 467#endif |
468 filesz_val = 0L; |
|
474 errno = EINVAL; 475 return (-1); 476 } | 469 errno = EINVAL; 470 return (-1); 471 } |
477 *filesz_val = ll; | |
478#ifdef HAVE_PTHREAD_MUTEX_LOCK 479 pthread_mutex_unlock(&mutex); 480#endif 481 return (0); 482} 483 484/* 485 * Return the system audit value from the audit contol file. --- 128 unchanged lines hidden (view full) --- 614 return (1); 615 } 616 if (strlen(str) >= len) { 617#ifdef HAVE_PTHREAD_MUTEX_LOCK 618 pthread_mutex_unlock(&mutex); 619#endif 620 return (-3); 621 } | 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 } |
622 strcpy(auditstr, str); | 616 strlcpy(auditstr, str, len); |
623#ifdef HAVE_PTHREAD_MUTEX_LOCK 624 pthread_mutex_unlock(&mutex); 625#endif 626 return (0); 627} | 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} |
|