Deleted Added
full compact
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 * 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 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.
17 *
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.
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 * 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 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.
17 *
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.
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
45#ifndef HAVE_STRLCAT
46#include <compat/strlcat.h>
47#endif
48#ifndef HAVE_STRLCPY
49#include <compat/strlcpy.h>
50#endif
51
52/*
53 * Parse the contents of the audit_control file to return the audit control
54 * parameters. These static fields are protected by 'mutex'.
55 */
56static FILE *fp = NULL;
57static char linestr[AU_LINE_MAX];
58static char *delim = ":";
59
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
46#ifndef HAVE_STRLCAT
47#include <compat/strlcat.h>
48#endif
49#ifndef HAVE_STRLCPY
50#include <compat/strlcpy.h>
51#endif
52
53/*
54 * Parse the contents of the audit_control file to return the audit control
55 * parameters. These static fields are protected by 'mutex'.
56 */
57static FILE *fp = NULL;
58static char linestr[AU_LINE_MAX];
59static char *delim = ":";
60
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{
76 char *type, *nl;
77 char *tokptr;
78 char *last;
79
80 *str = NULL;
81
82 if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL))
83 return (-1); /* Error */
84
85 while (1) {
86 if (fgets(linestr, AU_LINE_MAX, fp) == NULL) {
87 if (ferror(fp))
88 return (-1);
89 return (0); /* EOF */
90 }
91
92 if (linestr[0] == '#')
93 continue;
94
95 /* Remove trailing new line character. */
96 if ((nl = strrchr(linestr, '\n')) != NULL)
97 *nl = '\0';
98
99 tokptr = linestr;
100 if ((type = strtok_r(tokptr, delim, &last)) != NULL) {
101 if (strcmp(name, type) == 0) {
102 /* Found matching name. */
103 *str = strtok_r(NULL, delim, &last);
104 if (*str == NULL) {
105 errno = EINVAL;
106 return (-1); /* Parse error in file */
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{
103 char *type, *nl;
104 char *tokptr;
105 char *last;
106
107 *str = NULL;
108
109 if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL))
110 return (-1); /* Error */
111
112 while (1) {
113 if (fgets(linestr, AU_LINE_MAX, fp) == NULL) {
114 if (ferror(fp))
115 return (-1);
116 return (0); /* EOF */
117 }
118
119 if (linestr[0] == '#')
120 continue;
121
122 /* Remove trailing new line character. */
123 if ((nl = strrchr(linestr, '\n')) != NULL)
124 *nl = '\0';
125
126 tokptr = linestr;
127 if ((type = strtok_r(tokptr, delim, &last)) != NULL) {
128 if (strcmp(name, type) == 0) {
129 /* Found matching name. */
130 *str = strtok_r(NULL, delim, &last);
131 if (*str == NULL) {
132 errno = EINVAL;
133 return (-1); /* Parse error in file */
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}
308
309/*
310 * Rewind the file pointer to beginning.
311 */
312static void
313setac_locked(void)
314{
315
316 ptrmoved = 1;
317 if (fp != NULL)
318 fseek(fp, 0, SEEK_SET);
319}
320
321void
322setac(void)
323{
324
325#ifdef HAVE_PTHREAD_MUTEX_LOCK
326 pthread_mutex_lock(&mutex);
327#endif
328 setac_locked();
329#ifdef HAVE_PTHREAD_MUTEX_LOCK
330 pthread_mutex_unlock(&mutex);
331#endif
332}
333
334/*
335 * Close the audit_control file.
336 */
337void
338endac(void)
339{
340
341#ifdef HAVE_PTHREAD_MUTEX_LOCK
342 pthread_mutex_lock(&mutex);
343#endif
344 ptrmoved = 1;
345 if (fp != NULL) {
346 fclose(fp);
347 fp = NULL;
348 }
349#ifdef HAVE_PTHREAD_MUTEX_LOCK
350 pthread_mutex_unlock(&mutex);
351#endif
352}
353
354/*
355 * Return audit directory information from the audit control file.
356 */
357int
358getacdir(char *name, int len)
359{
360 char *dir;
361 int ret = 0;
362
363 /*
364 * Check if another function was called between successive calls to
365 * getacdir.
366 */
367#ifdef HAVE_PTHREAD_MUTEX_LOCK
368 pthread_mutex_lock(&mutex);
369#endif
370 if (inacdir && ptrmoved) {
371 ptrmoved = 0;
372 if (fp != NULL)
373 fseek(fp, 0, SEEK_SET);
374 ret = 2;
375 }
376 if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
377#ifdef HAVE_PTHREAD_MUTEX_LOCK
378 pthread_mutex_unlock(&mutex);
379#endif
380 return (-2);
381 }
382 if (dir == NULL) {
383#ifdef HAVE_PTHREAD_MUTEX_LOCK
384 pthread_mutex_unlock(&mutex);
385#endif
386 return (-1);
387 }
388 if (strlen(dir) >= (size_t)len) {
389#ifdef HAVE_PTHREAD_MUTEX_LOCK
390 pthread_mutex_unlock(&mutex);
391#endif
392 return (-3);
393 }
394 strlcpy(name, dir, len);
395#ifdef HAVE_PTHREAD_MUTEX_LOCK
396 pthread_mutex_unlock(&mutex);
397#endif
398 return (ret);
399}
400
401/*
402 * Return the minimum free diskspace value from the audit control file.
403 */
404int
405getacmin(int *min_val)
406{
407 char *min;
408
409#ifdef HAVE_PTHREAD_MUTEX_LOCK
410 pthread_mutex_lock(&mutex);
411#endif
412 setac_locked();
413 if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
414#ifdef HAVE_PTHREAD_MUTEX_LOCK
415 pthread_mutex_unlock(&mutex);
416#endif
417 return (-2);
418 }
419 if (min == NULL) {
420#ifdef HAVE_PTHREAD_MUTEX_LOCK
421 pthread_mutex_unlock(&mutex);
422#endif
423 return (1);
424 }
425 *min_val = atoi(min);
426#ifdef HAVE_PTHREAD_MUTEX_LOCK
427 pthread_mutex_unlock(&mutex);
428#endif
429 return (0);
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}
283
284/*
285 * Rewind the file pointer to beginning.
286 */
287static void
288setac_locked(void)
289{
290
291 ptrmoved = 1;
292 if (fp != NULL)
293 fseek(fp, 0, SEEK_SET);
294}
295
296void
297setac(void)
298{
299
300#ifdef HAVE_PTHREAD_MUTEX_LOCK
301 pthread_mutex_lock(&mutex);
302#endif
303 setac_locked();
304#ifdef HAVE_PTHREAD_MUTEX_LOCK
305 pthread_mutex_unlock(&mutex);
306#endif
307}
308
309/*
310 * Close the audit_control file.
311 */
312void
313endac(void)
314{
315
316#ifdef HAVE_PTHREAD_MUTEX_LOCK
317 pthread_mutex_lock(&mutex);
318#endif
319 ptrmoved = 1;
320 if (fp != NULL) {
321 fclose(fp);
322 fp = NULL;
323 }
324#ifdef HAVE_PTHREAD_MUTEX_LOCK
325 pthread_mutex_unlock(&mutex);
326#endif
327}
328
329/*
330 * Return audit directory information from the audit control file.
331 */
332int
333getacdir(char *name, int len)
334{
335 char *dir;
336 int ret = 0;
337
338 /*
339 * Check if another function was called between successive calls to
340 * getacdir.
341 */
342#ifdef HAVE_PTHREAD_MUTEX_LOCK
343 pthread_mutex_lock(&mutex);
344#endif
345 if (inacdir && ptrmoved) {
346 ptrmoved = 0;
347 if (fp != NULL)
348 fseek(fp, 0, SEEK_SET);
349 ret = 2;
350 }
351 if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
352#ifdef HAVE_PTHREAD_MUTEX_LOCK
353 pthread_mutex_unlock(&mutex);
354#endif
355 return (-2);
356 }
357 if (dir == NULL) {
358#ifdef HAVE_PTHREAD_MUTEX_LOCK
359 pthread_mutex_unlock(&mutex);
360#endif
361 return (-1);
362 }
363 if (strlen(dir) >= (size_t)len) {
364#ifdef HAVE_PTHREAD_MUTEX_LOCK
365 pthread_mutex_unlock(&mutex);
366#endif
367 return (-3);
368 }
369 strlcpy(name, dir, len);
370#ifdef HAVE_PTHREAD_MUTEX_LOCK
371 pthread_mutex_unlock(&mutex);
372#endif
373 return (ret);
374}
375
376/*
377 * Return the minimum free diskspace value from the audit control file.
378 */
379int
380getacmin(int *min_val)
381{
382 char *min;
383
384#ifdef HAVE_PTHREAD_MUTEX_LOCK
385 pthread_mutex_lock(&mutex);
386#endif
387 setac_locked();
388 if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
389#ifdef HAVE_PTHREAD_MUTEX_LOCK
390 pthread_mutex_unlock(&mutex);
391#endif
392 return (-2);
393 }
394 if (min == NULL) {
395#ifdef HAVE_PTHREAD_MUTEX_LOCK
396 pthread_mutex_unlock(&mutex);
397#endif
398 return (1);
399 }
400 *min_val = atoi(min);
401#ifdef HAVE_PTHREAD_MUTEX_LOCK
402 pthread_mutex_unlock(&mutex);
403#endif
404 return (0);
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.
486 */
487int
488getacflg(char *auditstr, int len)
489{
490 char *str;
491
492#ifdef HAVE_PTHREAD_MUTEX_LOCK
493 pthread_mutex_lock(&mutex);
494#endif
495 setac_locked();
496 if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) {
497#ifdef HAVE_PTHREAD_MUTEX_LOCK
498 pthread_mutex_unlock(&mutex);
499#endif
500 return (-2);
501 }
502 if (str == NULL) {
503#ifdef HAVE_PTHREAD_MUTEX_LOCK
504 pthread_mutex_unlock(&mutex);
505#endif
506 return (1);
507 }
508 if (strlen(str) >= (size_t)len) {
509#ifdef HAVE_PTHREAD_MUTEX_LOCK
510 pthread_mutex_unlock(&mutex);
511#endif
512 return (-3);
513 }
514 strlcpy(auditstr, str, len);
515#ifdef HAVE_PTHREAD_MUTEX_LOCK
516 pthread_mutex_unlock(&mutex);
517#endif
518 return (0);
519}
520
521/*
522 * Return the non attributable flags from the audit contol file.
523 */
524int
525getacna(char *auditstr, int len)
526{
527 char *str;
528
529#ifdef HAVE_PTHREAD_MUTEX_LOCK
530 pthread_mutex_lock(&mutex);
531#endif
532 setac_locked();
533 if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) {
534#ifdef HAVE_PTHREAD_MUTEX_LOCK
535 pthread_mutex_unlock(&mutex);
536#endif
537 return (-2);
538 }
539 if (str == NULL) {
540#ifdef HAVE_PTHREAD_MUTEX_LOCK
541 pthread_mutex_unlock(&mutex);
542#endif
543 return (1);
544 }
545 if (strlen(str) >= (size_t)len) {
546#ifdef HAVE_PTHREAD_MUTEX_LOCK
547 pthread_mutex_unlock(&mutex);
548#endif
549 return (-3);
550 }
551 strlcpy(auditstr, str, len);
552#ifdef HAVE_PTHREAD_MUTEX_LOCK
553 pthread_mutex_unlock(&mutex);
554#endif
555 return (0);
556}
557
558/*
559 * Return the policy field from the audit control file.
560 */
561int
562getacpol(char *auditstr, size_t len)
563{
564 char *str;
565
566#ifdef HAVE_PTHREAD_MUTEX_LOCK
567 pthread_mutex_lock(&mutex);
568#endif
569 setac_locked();
570 if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) {
571#ifdef HAVE_PTHREAD_MUTEX_LOCK
572 pthread_mutex_unlock(&mutex);
573#endif
574 return (-2);
575 }
576 if (str == NULL) {
577#ifdef HAVE_PTHREAD_MUTEX_LOCK
578 pthread_mutex_unlock(&mutex);
579#endif
580 return (-1);
581 }
582 if (strlen(str) >= len) {
583#ifdef HAVE_PTHREAD_MUTEX_LOCK
584 pthread_mutex_unlock(&mutex);
585#endif
586 return (-3);
587 }
588 strlcpy(auditstr, str, len);
589#ifdef HAVE_PTHREAD_MUTEX_LOCK
590 pthread_mutex_unlock(&mutex);
591#endif
592 return (0);
593}
594
595int
596getachost(char *auditstr, size_t len)
597{
598 char *str;
599
600#ifdef HAVE_PTHREAD_MUTEX_LOCK
601 pthread_mutex_lock(&mutex);
602#endif
603 setac_locked();
604 if (getstrfromtype_locked(AUDIT_HOST_CONTROL_ENTRY, &str) < 0) {
605#ifdef HAVE_PTHREAD_MUTEX_LOCK
606 pthread_mutex_unlock(&mutex);
607#endif
608 return (-2);
609 }
610 if (str == NULL) {
611#ifdef HAVE_PTHREAD_MUTEX_LOCK
612 pthread_mutex_unlock(&mutex);
613#endif
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.
480 */
481int
482getacflg(char *auditstr, int len)
483{
484 char *str;
485
486#ifdef HAVE_PTHREAD_MUTEX_LOCK
487 pthread_mutex_lock(&mutex);
488#endif
489 setac_locked();
490 if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) {
491#ifdef HAVE_PTHREAD_MUTEX_LOCK
492 pthread_mutex_unlock(&mutex);
493#endif
494 return (-2);
495 }
496 if (str == NULL) {
497#ifdef HAVE_PTHREAD_MUTEX_LOCK
498 pthread_mutex_unlock(&mutex);
499#endif
500 return (1);
501 }
502 if (strlen(str) >= (size_t)len) {
503#ifdef HAVE_PTHREAD_MUTEX_LOCK
504 pthread_mutex_unlock(&mutex);
505#endif
506 return (-3);
507 }
508 strlcpy(auditstr, str, len);
509#ifdef HAVE_PTHREAD_MUTEX_LOCK
510 pthread_mutex_unlock(&mutex);
511#endif
512 return (0);
513}
514
515/*
516 * Return the non attributable flags from the audit contol file.
517 */
518int
519getacna(char *auditstr, int len)
520{
521 char *str;
522
523#ifdef HAVE_PTHREAD_MUTEX_LOCK
524 pthread_mutex_lock(&mutex);
525#endif
526 setac_locked();
527 if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) {
528#ifdef HAVE_PTHREAD_MUTEX_LOCK
529 pthread_mutex_unlock(&mutex);
530#endif
531 return (-2);
532 }
533 if (str == NULL) {
534#ifdef HAVE_PTHREAD_MUTEX_LOCK
535 pthread_mutex_unlock(&mutex);
536#endif
537 return (1);
538 }
539 if (strlen(str) >= (size_t)len) {
540#ifdef HAVE_PTHREAD_MUTEX_LOCK
541 pthread_mutex_unlock(&mutex);
542#endif
543 return (-3);
544 }
545 strlcpy(auditstr, str, len);
546#ifdef HAVE_PTHREAD_MUTEX_LOCK
547 pthread_mutex_unlock(&mutex);
548#endif
549 return (0);
550}
551
552/*
553 * Return the policy field from the audit control file.
554 */
555int
556getacpol(char *auditstr, size_t len)
557{
558 char *str;
559
560#ifdef HAVE_PTHREAD_MUTEX_LOCK
561 pthread_mutex_lock(&mutex);
562#endif
563 setac_locked();
564 if (getstrfromtype_locked(POLICY_CONTROL_ENTRY, &str) < 0) {
565#ifdef HAVE_PTHREAD_MUTEX_LOCK
566 pthread_mutex_unlock(&mutex);
567#endif
568 return (-2);
569 }
570 if (str == NULL) {
571#ifdef HAVE_PTHREAD_MUTEX_LOCK
572 pthread_mutex_unlock(&mutex);
573#endif
574 return (-1);
575 }
576 if (strlen(str) >= len) {
577#ifdef HAVE_PTHREAD_MUTEX_LOCK
578 pthread_mutex_unlock(&mutex);
579#endif
580 return (-3);
581 }
582 strlcpy(auditstr, str, len);
583#ifdef HAVE_PTHREAD_MUTEX_LOCK
584 pthread_mutex_unlock(&mutex);
585#endif
586 return (0);
587}
588
589int
590getachost(char *auditstr, size_t len)
591{
592 char *str;
593
594#ifdef HAVE_PTHREAD_MUTEX_LOCK
595 pthread_mutex_lock(&mutex);
596#endif
597 setac_locked();
598 if (getstrfromtype_locked(AUDIT_HOST_CONTROL_ENTRY, &str) < 0) {
599#ifdef HAVE_PTHREAD_MUTEX_LOCK
600 pthread_mutex_unlock(&mutex);
601#endif
602 return (-2);
603 }
604 if (str == NULL) {
605#ifdef HAVE_PTHREAD_MUTEX_LOCK
606 pthread_mutex_unlock(&mutex);
607#endif
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}