2 * Copyright (c) 2004 Apple Computer, Inc.
3 * Copyright (c) 2006 Robert N. M. Watson
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
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.
30 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#16 $
33 #include <bsm/libbsm.h>
41 #include <config/config.h>
43 #include <compat/strlcat.h>
47 * Parse the contents of the audit_control file to return the audit control
48 * parameters. These static fields are protected by 'mutex'.
50 static FILE *fp = NULL;
51 static char linestr[AU_LINE_MAX];
52 static char *delim = ":";
54 static char inacdir = 0;
55 static char ptrmoved = 0;
57 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
60 * Returns the string value corresponding to the given label from the
63 * Must be called with mutex held.
66 getstrfromtype_locked(char *name, char **str)
74 if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL))
75 return (-1); /* Error */
78 if (fgets(linestr, AU_LINE_MAX, fp) == NULL) {
84 if (linestr[0] == '#')
87 /* Remove trailing new line character. */
88 if ((nl = strrchr(linestr, '\n')) != NULL)
92 if ((type = strtok_r(tokptr, delim, &last)) != NULL) {
93 if (strcmp(name, type) == 0) {
94 /* Found matching name. */
95 *str = strtok_r(NULL, delim, &last);
98 return (-1); /* Parse error in file */
100 return (0); /* Success */
107 * Convert a policy to a string. Return -1 on failure, or >= 0 representing
108 * the actual size of the string placed in the buffer (excluding terminating
112 au_poltostr(long policy, size_t maxsize, char *buf)
121 if (policy & AUDIT_CNT) {
122 if (strlcat(buf, "cnt", maxsize) >= maxsize)
126 if (policy & AUDIT_AHLT) {
128 if (strlcat(buf, ",", maxsize) >= maxsize)
131 if (strlcat(buf, "ahlt", maxsize) >= maxsize)
135 if (policy & AUDIT_ARGV) {
137 if (strlcat(buf, ",", maxsize) >= maxsize)
140 if (strlcat(buf, "argv", maxsize) >= maxsize)
144 if (policy & AUDIT_ARGE) {
146 if (strlcat(buf, ",", maxsize) >= maxsize)
149 if (strlcat(buf, "arge", maxsize) >= maxsize)
153 if (policy & AUDIT_SEQ) {
155 if (strlcat(buf, ",", maxsize) >= maxsize)
158 if (strlcat(buf, "seq", maxsize) >= maxsize)
162 if (policy & AUDIT_WINDATA) {
164 if (strlcat(buf, ",", maxsize) >= maxsize)
167 if (strlcat(buf, "windata", maxsize) >= maxsize)
171 if (policy & AUDIT_USER) {
173 if (strlcat(buf, ",", maxsize) >= maxsize)
176 if (strlcat(buf, "user", maxsize) >= maxsize)
180 if (policy & AUDIT_GROUP) {
182 if (strlcat(buf, ",", maxsize) >= maxsize)
185 if (strlcat(buf, "group", maxsize) >= maxsize)
189 if (policy & AUDIT_TRAIL) {
191 if (strlcat(buf, ",", maxsize) >= maxsize)
194 if (strlcat(buf, "trail", maxsize) >= maxsize)
198 if (policy & AUDIT_PATH) {
200 if (strlcat(buf, ",", maxsize) >= maxsize)
203 if (strlcat(buf, "path", maxsize) >= maxsize)
207 if (policy & AUDIT_SCNT) {
209 if (strlcat(buf, ",", maxsize) >= maxsize)
212 if (strlcat(buf, "scnt", maxsize) >= maxsize)
216 if (policy & AUDIT_PUBLIC) {
218 if (strlcat(buf, ",", maxsize) >= maxsize)
221 if (strlcat(buf, "public", maxsize) >= maxsize)
225 if (policy & AUDIT_ZONENAME) {
227 if (strlcat(buf, ",", maxsize) >= maxsize)
230 if (strlcat(buf, "zonename", maxsize) >= maxsize)
234 if (policy & AUDIT_PERZONE) {
236 if (strlcat(buf, ",", maxsize) >= maxsize)
239 if (strlcat(buf, "perzone", maxsize) >= maxsize)
243 return (strlen(buf));
247 * Convert a string to a policy. Return -1 on failure (with errno EINVAL,
248 * ENOMEM) or 0 on success.
251 au_strtopol(const char *polstr, long *policy)
257 buffer = strdup(polstr);
262 while ((string = strsep(&bufp, ",")) != NULL) {
263 if (strcmp(string, "cnt") == 0)
264 *policy |= AUDIT_CNT;
265 else if (strcmp(string, "ahlt") == 0)
266 *policy |= AUDIT_AHLT;
267 else if (strcmp(string, "argv") == 0)
268 *policy |= AUDIT_ARGV;
269 else if (strcmp(string, "arge") == 0)
270 *policy |= AUDIT_ARGE;
271 else if (strcmp(string, "seq") == 0)
272 *policy |= AUDIT_SEQ;
273 else if (strcmp(string, "winau_fstat") == 0)
274 *policy |= AUDIT_WINDATA;
275 else if (strcmp(string, "user") == 0)
276 *policy |= AUDIT_USER;
277 else if (strcmp(string, "group") == 0)
278 *policy |= AUDIT_GROUP;
279 else if (strcmp(string, "trail") == 0)
280 *policy |= AUDIT_TRAIL;
281 else if (strcmp(string, "path") == 0)
282 *policy |= AUDIT_PATH;
283 else if (strcmp(string, "scnt") == 0)
284 *policy |= AUDIT_SCNT;
285 else if (strcmp(string, "public") == 0)
286 *policy |= AUDIT_PUBLIC;
287 else if (strcmp(string, "zonename") == 0)
288 *policy |= AUDIT_ZONENAME;
289 else if (strcmp(string, "perzone") == 0)
290 *policy |= AUDIT_PERZONE;
302 * Rewind the file pointer to beginning.
310 fseek(fp, 0, SEEK_SET);
317 pthread_mutex_lock(&mutex);
319 pthread_mutex_unlock(&mutex);
323 * Close the audit_control file.
329 pthread_mutex_lock(&mutex);
335 pthread_mutex_unlock(&mutex);
339 * Return audit directory information from the audit control file.
342 getacdir(char *name, int len)
348 * Check if another function was called between successive calls to
351 pthread_mutex_lock(&mutex);
352 if (inacdir && ptrmoved) {
355 fseek(fp, 0, SEEK_SET);
358 if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
359 pthread_mutex_unlock(&mutex);
363 pthread_mutex_unlock(&mutex);
366 if (strlen(dir) >= len) {
367 pthread_mutex_unlock(&mutex);
371 pthread_mutex_unlock(&mutex);
376 * Return the minimum free diskspace value from the audit control file.
379 getacmin(int *min_val)
383 pthread_mutex_lock(&mutex);
385 if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
386 pthread_mutex_unlock(&mutex);
390 pthread_mutex_unlock(&mutex);
393 *min_val = atoi(min);
394 pthread_mutex_unlock(&mutex);
399 * Return the desired trail rotation size from the audit control file.
402 getacfilesz(size_t *filesz_val)
404 char *filesz, *dummy;
407 pthread_mutex_lock(&mutex);
409 if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &filesz) < 0) {
410 pthread_mutex_unlock(&mutex);
413 if (filesz == NULL) {
414 pthread_mutex_unlock(&mutex);
418 ll = strtoll(filesz, &dummy, 10);
419 if (*dummy != '\0') {
420 pthread_mutex_unlock(&mutex);
425 * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE. 0
426 * indicates no rotation size.
428 if (ll < 0 || (ll > 0 && ll < MIN_AUDIT_FILE_SIZE)) {
429 pthread_mutex_unlock(&mutex);
434 pthread_mutex_unlock(&mutex);
439 * Return the system audit value from the audit contol file.
442 getacflg(char *auditstr, int len)
446 pthread_mutex_lock(&mutex);
448 if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) {
449 pthread_mutex_unlock(&mutex);
453 pthread_mutex_unlock(&mutex);
456 if (strlen(str) >= len) {
457 pthread_mutex_unlock(&mutex);
460 strcpy(auditstr, str);
461 pthread_mutex_unlock(&mutex);
466 * Return the non attributable flags from the audit contol file.
469 getacna(char *auditstr, int len)
473 pthread_mutex_lock(&mutex);
475 if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) {
476 pthread_mutex_unlock(&mutex);
480 pthread_mutex_unlock(&mutex);
483 if (strlen(str) >= len) {
484 pthread_mutex_unlock(&mutex);
487 strcpy(auditstr, str);
492 * Return the policy field from the audit control file.
495 getacpol(char *auditstr, size_t len)
499 pthread_mutex_lock(&mutex);
501 if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) {
502 pthread_mutex_unlock(&mutex);
506 pthread_mutex_unlock(&mutex);
509 if (strlen(str) >= len) {
510 pthread_mutex_unlock(&mutex);
513 strcpy(auditstr, str);
514 pthread_mutex_unlock(&mutex);