xref: /freebsd/contrib/openbsm/libbsm/bsm_control.c (revision aa77200569e397d6ff1fdb4d255d0fa254d0a128)
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  *
30*aa772005SRobert Watson  * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#41 $
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>
40*aa772005SRobert Watson #include <strings.h>
417a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
42ca0716f5SRobert Watson #include <pthread.h>
437a0a89d2SRobert Watson #endif
44ca0716f5SRobert Watson #include <stdio.h>
45ca0716f5SRobert Watson #include <stdlib.h>
46ca0716f5SRobert Watson 
47bb97b418SRobert Watson #ifndef HAVE_STRLCAT
48bb97b418SRobert Watson #include <compat/strlcat.h>
49bb97b418SRobert Watson #endif
5052267f74SRobert Watson #ifndef HAVE_STRLCPY
5152267f74SRobert Watson #include <compat/strlcpy.h>
5252267f74SRobert Watson #endif
53bb97b418SRobert Watson 
54c0020399SRobert Watson #include <sys/stat.h>
55c0020399SRobert Watson 
56ca0716f5SRobert Watson /*
57ca0716f5SRobert Watson  * Parse the contents of the audit_control file to return the audit control
58bb97b418SRobert Watson  * parameters.  These static fields are protected by 'mutex'.
59ca0716f5SRobert Watson  */
60ca0716f5SRobert Watson static FILE	*fp = NULL;
61ca0716f5SRobert Watson static char	linestr[AU_LINE_MAX];
62ca0716f5SRobert Watson static char	*delim = ":";
63ca0716f5SRobert Watson 
64ca0716f5SRobert Watson static char	inacdir = 0;
65ca0716f5SRobert Watson static char	ptrmoved = 0;
66ca0716f5SRobert Watson 
677a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
68ca0716f5SRobert Watson static pthread_mutex_t	mutex = PTHREAD_MUTEX_INITIALIZER;
697a0a89d2SRobert Watson #endif
70ca0716f5SRobert Watson 
71ca0716f5SRobert Watson /*
7206edd2f1SRobert Watson  * Audit policy string token table for au_poltostr() and au_strtopol().
7306edd2f1SRobert Watson  */
7406edd2f1SRobert Watson struct audit_polstr {
7506edd2f1SRobert Watson 	long		 ap_policy;
7606edd2f1SRobert Watson 	const char	*ap_str;
7706edd2f1SRobert Watson };
7806edd2f1SRobert Watson 
7906edd2f1SRobert Watson static struct audit_polstr au_polstr[] = {
8006edd2f1SRobert Watson 	{ AUDIT_CNT,		"cnt"		},
8106edd2f1SRobert Watson 	{ AUDIT_AHLT,		"ahlt"		},
8206edd2f1SRobert Watson 	{ AUDIT_ARGV,		"argv"		},
8306edd2f1SRobert Watson 	{ AUDIT_ARGE,		"arge"		},
8406edd2f1SRobert Watson 	{ AUDIT_SEQ,		"seq"		},
8506edd2f1SRobert Watson 	{ AUDIT_WINDATA,	"windata"	},
8606edd2f1SRobert Watson 	{ AUDIT_USER,		"user"		},
8706edd2f1SRobert Watson 	{ AUDIT_GROUP,		"group"		},
8806edd2f1SRobert Watson 	{ AUDIT_TRAIL,		"trail"		},
8906edd2f1SRobert Watson 	{ AUDIT_PATH,		"path"		},
9006edd2f1SRobert Watson 	{ AUDIT_SCNT,		"scnt"		},
9106edd2f1SRobert Watson 	{ AUDIT_PUBLIC,		"public"	},
9206edd2f1SRobert Watson 	{ AUDIT_ZONENAME,	"zonename"	},
9306edd2f1SRobert Watson 	{ AUDIT_PERZONE,	"perzone"	},
9406edd2f1SRobert Watson 	{ -1,			NULL		}
9506edd2f1SRobert Watson };
9606edd2f1SRobert Watson 
9706edd2f1SRobert Watson /*
98ca0716f5SRobert Watson  * Returns the string value corresponding to the given label from the
99ca0716f5SRobert Watson  * configuration file.
100ca0716f5SRobert Watson  *
101ca0716f5SRobert Watson  * Must be called with mutex held.
102ca0716f5SRobert Watson  */
103ca0716f5SRobert Watson static int
104*aa772005SRobert Watson getstrfromtype_locked(const char *name, char **str)
105ca0716f5SRobert Watson {
106ca0716f5SRobert Watson 	char *type, *nl;
107ca0716f5SRobert Watson 	char *tokptr;
108ca0716f5SRobert Watson 	char *last;
109ca0716f5SRobert Watson 
110ca0716f5SRobert Watson 	*str = NULL;
111ca0716f5SRobert Watson 
112ca0716f5SRobert Watson 	if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL))
113ca0716f5SRobert Watson 		return (-1); /* Error */
114ca0716f5SRobert Watson 
115ca0716f5SRobert Watson 	while (1) {
116ca0716f5SRobert Watson 		if (fgets(linestr, AU_LINE_MAX, fp) == NULL) {
117ca0716f5SRobert Watson 			if (ferror(fp))
118ca0716f5SRobert Watson 				return (-1);
119ca0716f5SRobert Watson 			return (0);	/* EOF */
120ca0716f5SRobert Watson 		}
121ca0716f5SRobert Watson 
122ca0716f5SRobert Watson 		if (linestr[0] == '#')
123ca0716f5SRobert Watson 			continue;
124ca0716f5SRobert Watson 
125597df30eSRobert Watson 		/* Remove trailing new line character and white space. */
126597df30eSRobert Watson 		nl = strchr(linestr, '\0') - 1;
127597df30eSRobert Watson 		while (nl >= linestr && ('\n' == *nl || ' ' == *nl ||
128597df30eSRobert Watson 			'\t' == *nl)) {
129ca0716f5SRobert Watson 			*nl = '\0';
130597df30eSRobert Watson 			nl--;
131597df30eSRobert Watson 		}
132ca0716f5SRobert Watson 
133ca0716f5SRobert Watson 		tokptr = linestr;
134ca0716f5SRobert Watson 		if ((type = strtok_r(tokptr, delim, &last)) != NULL) {
135ca0716f5SRobert Watson 			if (strcmp(name, type) == 0) {
136ca0716f5SRobert Watson 				/* Found matching name. */
137ca0716f5SRobert Watson 				*str = strtok_r(NULL, delim, &last);
138ca0716f5SRobert Watson 				if (*str == NULL) {
139ca0716f5SRobert Watson 					errno = EINVAL;
140ca0716f5SRobert Watson 					return (-1); /* Parse error in file */
141ca0716f5SRobert Watson 				}
142ca0716f5SRobert Watson 				return (0); /* Success */
143ca0716f5SRobert Watson 			}
144ca0716f5SRobert Watson 		}
145ca0716f5SRobert Watson 	}
146ca0716f5SRobert Watson }
147ca0716f5SRobert Watson 
148ca0716f5SRobert Watson /*
14906edd2f1SRobert Watson  * Convert a given time value with a multiplier (seconds, hours, days, years) to
15006edd2f1SRobert Watson  * seconds.  Return 0 on success.
15106edd2f1SRobert Watson  */
15206edd2f1SRobert Watson static int
15306edd2f1SRobert Watson au_timetosec(time_t *seconds, u_long value, char mult)
15406edd2f1SRobert Watson {
15506edd2f1SRobert Watson 	if (NULL == seconds)
15606edd2f1SRobert Watson 		return (-1);
15706edd2f1SRobert Watson 
15806edd2f1SRobert Watson 	switch(mult) {
15906edd2f1SRobert Watson 	case 's':
16006edd2f1SRobert Watson 		/* seconds */
16106edd2f1SRobert Watson 		*seconds = (time_t)value;
16206edd2f1SRobert Watson 		break;
16306edd2f1SRobert Watson 
16406edd2f1SRobert Watson 	case 'h':
16506edd2f1SRobert Watson 		/* hours */
16606edd2f1SRobert Watson 		*seconds = (time_t)value * 60 * 60;
16706edd2f1SRobert Watson 		break;
16806edd2f1SRobert Watson 
16906edd2f1SRobert Watson 	case 'd':
17006edd2f1SRobert Watson 		/* days */
17106edd2f1SRobert Watson 		*seconds = (time_t)value * 60 * 60 * 24;
17206edd2f1SRobert Watson 		break;
17306edd2f1SRobert Watson 
17406edd2f1SRobert Watson 	case 'y':
17506edd2f1SRobert Watson 		/* years.  Add a day for each 4th (leap) year. */
17606edd2f1SRobert Watson 		*seconds = (time_t)value * 60 * 60 * 24 * 364 +
17706edd2f1SRobert Watson 		    ((time_t)value / 4) * 60 * 60 * 24;
17806edd2f1SRobert Watson 		break;
17906edd2f1SRobert Watson 
18006edd2f1SRobert Watson 	default:
18106edd2f1SRobert Watson 		return (-1);
18206edd2f1SRobert Watson 	}
18306edd2f1SRobert Watson 	return (0);
18406edd2f1SRobert Watson }
18506edd2f1SRobert Watson 
18606edd2f1SRobert Watson /*
18706edd2f1SRobert Watson  * Convert a given disk space value with a multiplier (bytes, kilobytes,
18806edd2f1SRobert Watson  * megabytes, gigabytes) to bytes.  Return 0 on success.
18906edd2f1SRobert Watson  */
19006edd2f1SRobert Watson static int
19106edd2f1SRobert Watson au_spacetobytes(size_t *bytes, u_long value, char mult)
19206edd2f1SRobert Watson {
19306edd2f1SRobert Watson 	if (NULL == bytes)
19406edd2f1SRobert Watson 		return (-1);
19506edd2f1SRobert Watson 
19606edd2f1SRobert Watson 	switch(mult) {
19706edd2f1SRobert Watson 	case 'B':
19806edd2f1SRobert Watson 	case ' ':
19906edd2f1SRobert Watson 		/* Bytes */
20006edd2f1SRobert Watson 		*bytes = (size_t)value;
20106edd2f1SRobert Watson 		break;
20206edd2f1SRobert Watson 
20306edd2f1SRobert Watson 	case 'K':
20406edd2f1SRobert Watson 		/* Kilobytes */
20506edd2f1SRobert Watson 		*bytes = (size_t)value * 1024;
20606edd2f1SRobert Watson 		break;
20706edd2f1SRobert Watson 
20806edd2f1SRobert Watson 	case 'M':
20906edd2f1SRobert Watson 		/* Megabytes */
21006edd2f1SRobert Watson 		*bytes = (size_t)value * 1024 * 1024;
21106edd2f1SRobert Watson 		break;
21206edd2f1SRobert Watson 
21306edd2f1SRobert Watson 	case 'G':
21406edd2f1SRobert Watson 		/* Gigabytes */
21506edd2f1SRobert Watson 		*bytes = (size_t)value * 1024 * 1024 * 1024;
21606edd2f1SRobert Watson 		break;
21706edd2f1SRobert Watson 
21806edd2f1SRobert Watson 	default:
21906edd2f1SRobert Watson 		return (-1);
22006edd2f1SRobert Watson 	}
22106edd2f1SRobert Watson 	return (0);
22206edd2f1SRobert Watson }
22306edd2f1SRobert Watson 
22406edd2f1SRobert Watson /*
225bb97b418SRobert Watson  * Convert a policy to a string.  Return -1 on failure, or >= 0 representing
226bb97b418SRobert Watson  * the actual size of the string placed in the buffer (excluding terminating
227bb97b418SRobert Watson  * nul).
228bb97b418SRobert Watson  */
229bb97b418SRobert Watson ssize_t
230c0020399SRobert Watson au_poltostr(int policy, size_t maxsize, char *buf)
231bb97b418SRobert Watson {
23206edd2f1SRobert Watson 	int first = 1;
23306edd2f1SRobert Watson 	int i = 0;
234bb97b418SRobert Watson 
235bb97b418SRobert Watson 	if (maxsize < 1)
236bb97b418SRobert Watson 		return (-1);
237bb97b418SRobert Watson 	buf[0] = '\0';
238bb97b418SRobert Watson 
23906edd2f1SRobert Watson 	do {
24006edd2f1SRobert Watson 		if (policy & au_polstr[i].ap_policy) {
24106edd2f1SRobert Watson 			if (!first && strlcat(buf, ",", maxsize) >= maxsize)
24206edd2f1SRobert Watson 				return (-1);
24306edd2f1SRobert Watson 			if (strlcat(buf, au_polstr[i].ap_str, maxsize) >=
24406edd2f1SRobert Watson 			    maxsize)
245bb97b418SRobert Watson 				return (-1);
246bb97b418SRobert Watson 			first = 0;
247bb97b418SRobert Watson 		}
24806edd2f1SRobert Watson 	} while (NULL != au_polstr[++i].ap_str);
24906edd2f1SRobert Watson 
250bb97b418SRobert Watson 	return (strlen(buf));
251bb97b418SRobert Watson }
252bb97b418SRobert Watson 
253bb97b418SRobert Watson /*
254bb97b418SRobert Watson  * Convert a string to a policy.  Return -1 on failure (with errno EINVAL,
255bb97b418SRobert Watson  * ENOMEM) or 0 on success.
256bb97b418SRobert Watson  */
257bb97b418SRobert Watson int
258c0020399SRobert Watson au_strtopol(const char *polstr, int *policy)
259bb97b418SRobert Watson {
260bb97b418SRobert Watson 	char *bufp, *string;
261bb97b418SRobert Watson 	char *buffer;
26206edd2f1SRobert Watson 	int i, matched;
263bb97b418SRobert Watson 
264bb97b418SRobert Watson 	*policy = 0;
265bb97b418SRobert Watson 	buffer = strdup(polstr);
266bb97b418SRobert Watson 	if (buffer == NULL)
267bb97b418SRobert Watson 		return (-1);
268bb97b418SRobert Watson 
269bb97b418SRobert Watson 	bufp = buffer;
270bb97b418SRobert Watson 	while ((string = strsep(&bufp, ",")) != NULL) {
27106edd2f1SRobert Watson 		matched = i = 0;
27206edd2f1SRobert Watson 
27306edd2f1SRobert Watson 		do {
27406edd2f1SRobert Watson 			if (strcmp(string, au_polstr[i].ap_str) == 0) {
27506edd2f1SRobert Watson 				*policy |= au_polstr[i].ap_policy;
27606edd2f1SRobert Watson 				matched = 1;
27706edd2f1SRobert Watson 				break;
27806edd2f1SRobert Watson 			}
27906edd2f1SRobert Watson 		} while (NULL != au_polstr[++i].ap_str);
28006edd2f1SRobert Watson 
28106edd2f1SRobert Watson 		if (!matched) {
282bb97b418SRobert Watson 			free(buffer);
283bb97b418SRobert Watson 			errno = EINVAL;
284bb97b418SRobert Watson 			return (-1);
285bb97b418SRobert Watson 		}
286bb97b418SRobert Watson 	}
287bb97b418SRobert Watson 	free(buffer);
288bb97b418SRobert Watson 	return (0);
289bb97b418SRobert Watson }
290bb97b418SRobert Watson 
291bb97b418SRobert Watson /*
292ca0716f5SRobert Watson  * Rewind the file pointer to beginning.
293ca0716f5SRobert Watson  */
294bb97b418SRobert Watson static void
295bb97b418SRobert Watson setac_locked(void)
296bb97b418SRobert Watson {
297c0020399SRobert Watson 	static time_t lastctime = 0;
298c0020399SRobert Watson 	struct stat sbuf;
299bb97b418SRobert Watson 
300bb97b418SRobert Watson 	ptrmoved = 1;
301c0020399SRobert Watson 	if (fp != NULL) {
302c0020399SRobert Watson 		/*
303c0020399SRobert Watson 		 * Check to see if the file on disk has changed.  If so,
304c0020399SRobert Watson 		 * force a re-read of the file by closing it.
305c0020399SRobert Watson 		 */
306c0020399SRobert Watson 		if (fstat(fileno(fp), &sbuf) < 0)
307c0020399SRobert Watson 			goto closefp;
308c0020399SRobert Watson 		if (lastctime != sbuf.st_ctime) {
309c0020399SRobert Watson 			lastctime = sbuf.st_ctime;
310c0020399SRobert Watson closefp:
311c0020399SRobert Watson 			fclose(fp);
312c0020399SRobert Watson 			fp = NULL;
313c0020399SRobert Watson 			return;
314c0020399SRobert Watson 		}
315c0020399SRobert Watson 
316bb97b418SRobert Watson 		fseek(fp, 0, SEEK_SET);
317bb97b418SRobert Watson 	}
318c0020399SRobert Watson }
319bb97b418SRobert Watson 
320ca0716f5SRobert Watson void
321ca0716f5SRobert Watson setac(void)
322ca0716f5SRobert Watson {
323ca0716f5SRobert Watson 
3247a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
325ca0716f5SRobert Watson 	pthread_mutex_lock(&mutex);
3267a0a89d2SRobert Watson #endif
327bb97b418SRobert Watson 	setac_locked();
3287a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
329ca0716f5SRobert Watson 	pthread_mutex_unlock(&mutex);
3307a0a89d2SRobert Watson #endif
331ca0716f5SRobert Watson }
332ca0716f5SRobert Watson 
333ca0716f5SRobert Watson /*
334bb97b418SRobert Watson  * Close the audit_control file.
335ca0716f5SRobert Watson  */
336ca0716f5SRobert Watson void
337ca0716f5SRobert Watson endac(void)
338ca0716f5SRobert Watson {
339ca0716f5SRobert Watson 
3407a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
341ca0716f5SRobert Watson 	pthread_mutex_lock(&mutex);
3427a0a89d2SRobert Watson #endif
343ca0716f5SRobert Watson 	ptrmoved = 1;
344ca0716f5SRobert Watson 	if (fp != NULL) {
345ca0716f5SRobert Watson 		fclose(fp);
346ca0716f5SRobert Watson 		fp = NULL;
347ca0716f5SRobert Watson 	}
3487a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
349ca0716f5SRobert Watson 	pthread_mutex_unlock(&mutex);
3507a0a89d2SRobert Watson #endif
351ca0716f5SRobert Watson }
352ca0716f5SRobert Watson 
353ca0716f5SRobert Watson /*
354ca0716f5SRobert Watson  * Return audit directory information from the audit control file.
355ca0716f5SRobert Watson  */
356ca0716f5SRobert Watson int
357ca0716f5SRobert Watson getacdir(char *name, int len)
358ca0716f5SRobert Watson {
359ca0716f5SRobert Watson 	char *dir;
360ca0716f5SRobert Watson 	int ret = 0;
361ca0716f5SRobert Watson 
362ca0716f5SRobert Watson 	/*
363bb97b418SRobert Watson 	 * Check if another function was called between successive calls to
364bb97b418SRobert Watson 	 * getacdir.
365ca0716f5SRobert Watson 	 */
3667a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
367bb97b418SRobert Watson 	pthread_mutex_lock(&mutex);
3687a0a89d2SRobert Watson #endif
369ca0716f5SRobert Watson 	if (inacdir && ptrmoved) {
370ca0716f5SRobert Watson 		ptrmoved = 0;
371ca0716f5SRobert Watson 		if (fp != NULL)
372ca0716f5SRobert Watson 			fseek(fp, 0, SEEK_SET);
373ca0716f5SRobert Watson 		ret = 2;
374ca0716f5SRobert Watson 	}
375ca0716f5SRobert Watson 	if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
3767a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
377ca0716f5SRobert Watson 		pthread_mutex_unlock(&mutex);
3787a0a89d2SRobert Watson #endif
379ca0716f5SRobert Watson 		return (-2);
380ca0716f5SRobert Watson 	}
381bb97b418SRobert Watson 	if (dir == NULL) {
3827a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
383ca0716f5SRobert Watson 		pthread_mutex_unlock(&mutex);
3847a0a89d2SRobert Watson #endif
385ca0716f5SRobert Watson 		return (-1);
386bb97b418SRobert Watson 	}
38752267f74SRobert Watson 	if (strlen(dir) >= (size_t)len) {
3887a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
389bb97b418SRobert Watson 		pthread_mutex_unlock(&mutex);
3907a0a89d2SRobert Watson #endif
391ca0716f5SRobert Watson 		return (-3);
392bb97b418SRobert Watson 	}
39352267f74SRobert Watson 	strlcpy(name, dir, len);
3947a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
395bb97b418SRobert Watson 	pthread_mutex_unlock(&mutex);
3967a0a89d2SRobert Watson #endif
397ca0716f5SRobert Watson 	return (ret);
398ca0716f5SRobert Watson }
399ca0716f5SRobert Watson 
400ca0716f5SRobert Watson /*
401*aa772005SRobert Watson  * Return 1 if dist value is set to 'yes' or 'on'.
402*aa772005SRobert Watson  * Return 0 if dist value is set to something else.
403*aa772005SRobert Watson  * Return negative value on error.
404*aa772005SRobert Watson  */
405*aa772005SRobert Watson int
406*aa772005SRobert Watson getacdist(void)
407*aa772005SRobert Watson {
408*aa772005SRobert Watson 	char *str;
409*aa772005SRobert Watson 	int ret;
410*aa772005SRobert Watson 
411*aa772005SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
412*aa772005SRobert Watson 	pthread_mutex_lock(&mutex);
413*aa772005SRobert Watson #endif
414*aa772005SRobert Watson 	setac_locked();
415*aa772005SRobert Watson 	if (getstrfromtype_locked(DIST_CONTROL_ENTRY, &str) < 0) {
416*aa772005SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
417*aa772005SRobert Watson 		pthread_mutex_unlock(&mutex);
418*aa772005SRobert Watson #endif
419*aa772005SRobert Watson 		return (-2);
420*aa772005SRobert Watson 	}
421*aa772005SRobert Watson 	if (str == NULL) {
422*aa772005SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
423*aa772005SRobert Watson 		pthread_mutex_unlock(&mutex);
424*aa772005SRobert Watson #endif
425*aa772005SRobert Watson 		return (0);
426*aa772005SRobert Watson 	}
427*aa772005SRobert Watson 	if (strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0)
428*aa772005SRobert Watson 		ret = 1;
429*aa772005SRobert Watson 	else
430*aa772005SRobert Watson 		ret = 0;
431*aa772005SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
432*aa772005SRobert Watson 	pthread_mutex_unlock(&mutex);
433*aa772005SRobert Watson #endif
434*aa772005SRobert Watson 	return (ret);
435*aa772005SRobert Watson }
436*aa772005SRobert Watson 
437*aa772005SRobert Watson /*
438bb97b418SRobert Watson  * Return the minimum free diskspace value from the audit control file.
439ca0716f5SRobert Watson  */
440ca0716f5SRobert Watson int
441ca0716f5SRobert Watson getacmin(int *min_val)
442ca0716f5SRobert Watson {
443ca0716f5SRobert Watson 	char *min;
444ca0716f5SRobert Watson 
4457a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
446ca0716f5SRobert Watson 	pthread_mutex_lock(&mutex);
4477a0a89d2SRobert Watson #endif
448bb97b418SRobert Watson 	setac_locked();
449ca0716f5SRobert Watson 	if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
4507a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
451ca0716f5SRobert Watson 		pthread_mutex_unlock(&mutex);
4527a0a89d2SRobert Watson #endif
453ca0716f5SRobert Watson 		return (-2);
454ca0716f5SRobert Watson 	}
455bb97b418SRobert Watson 	if (min == NULL) {
4567a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
457ca0716f5SRobert Watson 		pthread_mutex_unlock(&mutex);
4587a0a89d2SRobert Watson #endif
459*aa772005SRobert Watson 		return (-1);
460bb97b418SRobert Watson 	}
461ca0716f5SRobert Watson 	*min_val = atoi(min);
4627a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
463bb97b418SRobert Watson 	pthread_mutex_unlock(&mutex);
4647a0a89d2SRobert Watson #endif
465ca0716f5SRobert Watson 	return (0);
466ca0716f5SRobert Watson }
467ca0716f5SRobert Watson 
468ca0716f5SRobert Watson /*
4694bd0c025SRobert Watson  * Return the desired trail rotation size from the audit control file.
4704bd0c025SRobert Watson  */
4714bd0c025SRobert Watson int
4724bd0c025SRobert Watson getacfilesz(size_t *filesz_val)
4734bd0c025SRobert Watson {
47406edd2f1SRobert Watson 	char *str;
47506edd2f1SRobert Watson 	size_t val;
47606edd2f1SRobert Watson 	char mult;
47706edd2f1SRobert Watson 	int nparsed;
4784bd0c025SRobert Watson 
4797a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
4804bd0c025SRobert Watson 	pthread_mutex_lock(&mutex);
4817a0a89d2SRobert Watson #endif
4824bd0c025SRobert Watson 	setac_locked();
48306edd2f1SRobert Watson 	if (getstrfromtype_locked(FILESZ_CONTROL_ENTRY, &str) < 0) {
4847a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
4854bd0c025SRobert Watson 		pthread_mutex_unlock(&mutex);
4867a0a89d2SRobert Watson #endif
4874bd0c025SRobert Watson 		return (-2);
4884bd0c025SRobert Watson 	}
48906edd2f1SRobert Watson 	if (str == NULL) {
4907a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
4914bd0c025SRobert Watson 		pthread_mutex_unlock(&mutex);
4927a0a89d2SRobert Watson #endif
4934bd0c025SRobert Watson 		errno = EINVAL;
494*aa772005SRobert Watson 		return (-1);
4954bd0c025SRobert Watson 	}
49606edd2f1SRobert Watson 
49706edd2f1SRobert Watson 	/* Trim off any leading white space. */
49806edd2f1SRobert Watson 	while (*str == ' ' || *str == '\t')
49906edd2f1SRobert Watson 		str++;
50006edd2f1SRobert Watson 
50106edd2f1SRobert Watson 	nparsed = sscanf(str, "%ju%c", (uintmax_t *)&val, &mult);
50206edd2f1SRobert Watson 
50306edd2f1SRobert Watson 	switch (nparsed) {
50406edd2f1SRobert Watson 	case 1:
50506edd2f1SRobert Watson 		/* If no multiplier then assume 'B' (bytes). */
50606edd2f1SRobert Watson 		mult = 'B';
50706edd2f1SRobert Watson 		/* fall through */
50806edd2f1SRobert Watson 	case 2:
50906edd2f1SRobert Watson 		if (au_spacetobytes(filesz_val, val, mult) == 0)
51006edd2f1SRobert Watson 			break;
51106edd2f1SRobert Watson 		/* fall through */
51206edd2f1SRobert Watson 	default:
51306edd2f1SRobert Watson 		errno = EINVAL;
5147a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
5154bd0c025SRobert Watson 		pthread_mutex_unlock(&mutex);
5167a0a89d2SRobert Watson #endif
5174bd0c025SRobert Watson 		return (-1);
5184bd0c025SRobert Watson 	}
51906edd2f1SRobert Watson 
5204bd0c025SRobert Watson 	/*
5214bd0c025SRobert Watson 	 * The file size must either be 0 or >= MIN_AUDIT_FILE_SIZE.  0
5224bd0c025SRobert Watson 	 * indicates no rotation size.
5234bd0c025SRobert Watson 	 */
52406edd2f1SRobert Watson 	if (*filesz_val < 0 || (*filesz_val > 0 &&
52506edd2f1SRobert Watson 		*filesz_val < MIN_AUDIT_FILE_SIZE)) {
5267a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
5274bd0c025SRobert Watson 		pthread_mutex_unlock(&mutex);
5287a0a89d2SRobert Watson #endif
52906edd2f1SRobert Watson 		filesz_val = 0L;
5304bd0c025SRobert Watson 		errno = EINVAL;
5314bd0c025SRobert Watson 		return (-1);
5324bd0c025SRobert Watson 	}
5337a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
5344bd0c025SRobert Watson 	pthread_mutex_unlock(&mutex);
5357a0a89d2SRobert Watson #endif
5364bd0c025SRobert Watson 	return (0);
5374bd0c025SRobert Watson }
5384bd0c025SRobert Watson 
539*aa772005SRobert Watson static int
540*aa772005SRobert Watson getaccommon(const char *name, char *auditstr, int len)
541ca0716f5SRobert Watson {
542ca0716f5SRobert Watson 	char *str;
543ca0716f5SRobert Watson 
5447a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
545ca0716f5SRobert Watson 	pthread_mutex_lock(&mutex);
5467a0a89d2SRobert Watson #endif
547bb97b418SRobert Watson 	setac_locked();
548*aa772005SRobert Watson 	if (getstrfromtype_locked(name, &str) < 0) {
5497a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
550bb97b418SRobert Watson 		pthread_mutex_unlock(&mutex);
5517a0a89d2SRobert Watson #endif
552bb97b418SRobert Watson 		return (-2);
553bb97b418SRobert Watson 	}
554bb97b418SRobert Watson 	if (str == NULL) {
5557a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
556bb97b418SRobert Watson 		pthread_mutex_unlock(&mutex);
5577a0a89d2SRobert Watson #endif
558bb97b418SRobert Watson 		return (-1);
559bb97b418SRobert Watson 	}
560*aa772005SRobert Watson 	if (strlen(str) >= (size_t)len) {
5617a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
562bb97b418SRobert Watson 		pthread_mutex_unlock(&mutex);
5637a0a89d2SRobert Watson #endif
564bb97b418SRobert Watson 		return (-3);
565bb97b418SRobert Watson 	}
56652267f74SRobert Watson 	strlcpy(auditstr, str, len);
5677a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
56852267f74SRobert Watson 	pthread_mutex_unlock(&mutex);
5697a0a89d2SRobert Watson #endif
57052267f74SRobert Watson 	return (0);
57152267f74SRobert Watson }
57252267f74SRobert Watson 
573*aa772005SRobert Watson /*
574*aa772005SRobert Watson  * Return the system audit value from the audit contol file.
575*aa772005SRobert Watson  */
576*aa772005SRobert Watson int
577*aa772005SRobert Watson getacflg(char *auditstr, int len)
578*aa772005SRobert Watson {
579*aa772005SRobert Watson 
580*aa772005SRobert Watson 	return (getaccommon(FLAGS_CONTROL_ENTRY, auditstr, len));
581*aa772005SRobert Watson }
582*aa772005SRobert Watson 
583*aa772005SRobert Watson /*
584*aa772005SRobert Watson  * Return the non attributable flags from the audit contol file.
585*aa772005SRobert Watson  */
586*aa772005SRobert Watson int
587*aa772005SRobert Watson getacna(char *auditstr, int len)
588*aa772005SRobert Watson {
589*aa772005SRobert Watson 
590*aa772005SRobert Watson 	return (getaccommon(NA_CONTROL_ENTRY, auditstr, len));
591*aa772005SRobert Watson }
592*aa772005SRobert Watson 
593*aa772005SRobert Watson /*
594*aa772005SRobert Watson  * Return the policy field from the audit control file.
595*aa772005SRobert Watson  */
596*aa772005SRobert Watson int
597*aa772005SRobert Watson getacpol(char *auditstr, size_t len)
598*aa772005SRobert Watson {
599*aa772005SRobert Watson 
600*aa772005SRobert Watson 	return (getaccommon(POLICY_CONTROL_ENTRY, auditstr, len));
601*aa772005SRobert Watson }
602*aa772005SRobert Watson 
60352267f74SRobert Watson int
60452267f74SRobert Watson getachost(char *auditstr, size_t len)
60552267f74SRobert Watson {
60652267f74SRobert Watson 
607*aa772005SRobert Watson 	return (getaccommon(HOST_CONTROL_ENTRY, auditstr, len));
60806edd2f1SRobert Watson }
60906edd2f1SRobert Watson 
61006edd2f1SRobert Watson /*
61106edd2f1SRobert Watson  * Set expiration conditions.
61206edd2f1SRobert Watson  */
61306edd2f1SRobert Watson static int
61406edd2f1SRobert Watson setexpirecond(time_t *age, size_t *size, u_long value, char mult)
61506edd2f1SRobert Watson {
61606edd2f1SRobert Watson 
61706edd2f1SRobert Watson 	if (isupper(mult) || ' ' == mult)
61806edd2f1SRobert Watson 		return (au_spacetobytes(size, value, mult));
61906edd2f1SRobert Watson 	else
62006edd2f1SRobert Watson 		return (au_timetosec(age, value, mult));
62106edd2f1SRobert Watson }
62206edd2f1SRobert Watson 
62306edd2f1SRobert Watson /*
62406edd2f1SRobert Watson  * Return the expire-after field from the audit control file.
62506edd2f1SRobert Watson  */
62606edd2f1SRobert Watson int
62706edd2f1SRobert Watson getacexpire(int *andflg, time_t *age, size_t *size)
62806edd2f1SRobert Watson {
62906edd2f1SRobert Watson 	char *str;
63006edd2f1SRobert Watson 	int nparsed;
63106edd2f1SRobert Watson 	u_long val1, val2;
63206edd2f1SRobert Watson 	char mult1, mult2;
63306edd2f1SRobert Watson 	char andor[AU_LINE_MAX];
63406edd2f1SRobert Watson 
63506edd2f1SRobert Watson 	*age = 0L;
63606edd2f1SRobert Watson 	*size = 0LL;
63706edd2f1SRobert Watson 	*andflg = 0;
63806edd2f1SRobert Watson 
63906edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
64006edd2f1SRobert Watson 	pthread_mutex_lock(&mutex);
64106edd2f1SRobert Watson #endif
64206edd2f1SRobert Watson 	setac_locked();
64306edd2f1SRobert Watson 	if (getstrfromtype_locked(EXPIRE_AFTER_CONTROL_ENTRY, &str) < 0) {
64406edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
64506edd2f1SRobert Watson 		pthread_mutex_unlock(&mutex);
64606edd2f1SRobert Watson #endif
64706edd2f1SRobert Watson 		return (-2);
64806edd2f1SRobert Watson 	}
64906edd2f1SRobert Watson 	if (str == NULL) {
65006edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
65106edd2f1SRobert Watson 		pthread_mutex_unlock(&mutex);
65206edd2f1SRobert Watson #endif
653*aa772005SRobert Watson 		return (-1);
65406edd2f1SRobert Watson 	}
65506edd2f1SRobert Watson 
65606edd2f1SRobert Watson 	/* First, trim off any leading white space. */
65706edd2f1SRobert Watson 	while (*str == ' ' || *str == '\t')
65806edd2f1SRobert Watson 		str++;
65906edd2f1SRobert Watson 
66006edd2f1SRobert Watson 	nparsed = sscanf(str, "%lu%c%[ \tadnorADNOR]%lu%c", &val1, &mult1,
66106edd2f1SRobert Watson 	    andor, &val2, &mult2);
66206edd2f1SRobert Watson 
66306edd2f1SRobert Watson 	switch (nparsed) {
66406edd2f1SRobert Watson 	case 1:
66506edd2f1SRobert Watson 		/* If no multiplier then assume 'B' (Bytes). */
66606edd2f1SRobert Watson 		mult1 = 'B';
66706edd2f1SRobert Watson 		/* fall through */
66806edd2f1SRobert Watson 	case 2:
66906edd2f1SRobert Watson 		/* One expiration condition. */
67006edd2f1SRobert Watson 		if (setexpirecond(age, size, val1, mult1) != 0) {
67106edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
67206edd2f1SRobert Watson 			pthread_mutex_unlock(&mutex);
67306edd2f1SRobert Watson #endif
67406edd2f1SRobert Watson 			return (-1);
67506edd2f1SRobert Watson 		}
67606edd2f1SRobert Watson 		break;
67706edd2f1SRobert Watson 
67806edd2f1SRobert Watson 	case 5:
67906edd2f1SRobert Watson 		/* Two expiration conditions. */
68006edd2f1SRobert Watson 		if (setexpirecond(age, size, val1, mult1) != 0 ||
68106edd2f1SRobert Watson 		    setexpirecond(age, size, val2, mult2) != 0) {
68206edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
68306edd2f1SRobert Watson 			pthread_mutex_unlock(&mutex);
68406edd2f1SRobert Watson #endif
68506edd2f1SRobert Watson 			return (-1);
68606edd2f1SRobert Watson 		}
68706edd2f1SRobert Watson 		if (strcasestr(andor, "and") != NULL)
68806edd2f1SRobert Watson 			*andflg = 1;
68906edd2f1SRobert Watson 		else if (strcasestr(andor, "or") != NULL)
69006edd2f1SRobert Watson 			*andflg = 0;
69106edd2f1SRobert Watson 		else {
69206edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
69306edd2f1SRobert Watson 			pthread_mutex_unlock(&mutex);
69406edd2f1SRobert Watson #endif
69506edd2f1SRobert Watson 			return (-1);
69606edd2f1SRobert Watson 		}
69706edd2f1SRobert Watson 		break;
69806edd2f1SRobert Watson 
69906edd2f1SRobert Watson 	default:
70006edd2f1SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
70106edd2f1SRobert Watson 		pthread_mutex_unlock(&mutex);
70206edd2f1SRobert Watson #endif
70306edd2f1SRobert Watson 		return (-1);
70406edd2f1SRobert Watson 	}
70506edd2f1SRobert Watson 
7067a0a89d2SRobert Watson #ifdef HAVE_PTHREAD_MUTEX_LOCK
707bb97b418SRobert Watson 	pthread_mutex_unlock(&mutex);
7087a0a89d2SRobert Watson #endif
709ca0716f5SRobert Watson 	return (0);
710ca0716f5SRobert Watson }
711