xref: /freebsd/contrib/openbsm/libbsm/bsm_control.c (revision d056fa046c6a91b90cd98165face0e42a33a5173)
1 /*
2  * Copyright (c) 2004 Apple Computer, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_control.c#13 $
30  */
31 
32 #include <bsm/libbsm.h>
33 
34 #include <errno.h>
35 #include <string.h>
36 #include <pthread.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 
40 /*
41  * Parse the contents of the audit_control file to return the audit control
42  * parameters.
43  */
44 static FILE	*fp = NULL;
45 static char	linestr[AU_LINE_MAX];
46 static char	*delim = ":";
47 
48 static char	inacdir = 0;
49 static char	ptrmoved = 0;
50 
51 static pthread_mutex_t	mutex = PTHREAD_MUTEX_INITIALIZER;
52 
53 /*
54  * Returns the string value corresponding to the given label from the
55  * configuration file.
56  *
57  * Must be called with mutex held.
58  */
59 static int
60 getstrfromtype_locked(char *name, char **str)
61 {
62 	char *type, *nl;
63 	char *tokptr;
64 	char *last;
65 
66 	*str = NULL;
67 
68 	if ((fp == NULL) && ((fp = fopen(AUDIT_CONTROL_FILE, "r")) == NULL))
69 		return (-1); /* Error */
70 
71 	while (1) {
72 		if (fgets(linestr, AU_LINE_MAX, fp) == NULL) {
73 			if (ferror(fp))
74 				return (-1);
75 			return (0);	/* EOF */
76 		}
77 
78 		if (linestr[0] == '#')
79 			continue;
80 
81 		/* Remove trailing new line character. */
82 		if ((nl = strrchr(linestr, '\n')) != NULL)
83 			*nl = '\0';
84 
85 		tokptr = linestr;
86 		if ((type = strtok_r(tokptr, delim, &last)) != NULL) {
87 			if (strcmp(name, type) == 0) {
88 				/* Found matching name. */
89 				*str = strtok_r(NULL, delim, &last);
90 				if (*str == NULL) {
91 					errno = EINVAL;
92 					return (-1); /* Parse error in file */
93 				}
94 				return (0); /* Success */
95 			}
96 		}
97 	}
98 }
99 
100 /*
101  * Rewind the file pointer to beginning.
102  */
103 void
104 setac(void)
105 {
106 
107 	pthread_mutex_lock(&mutex);
108 	ptrmoved = 1;
109 	if (fp != NULL)
110 		fseek(fp, 0, SEEK_SET);
111 	pthread_mutex_unlock(&mutex);
112 }
113 
114 /*
115  * Close the audit_control file
116  */
117 void
118 endac(void)
119 {
120 
121 	pthread_mutex_lock(&mutex);
122 	ptrmoved = 1;
123 	if (fp != NULL) {
124 		fclose(fp);
125 		fp = NULL;
126 	}
127 	pthread_mutex_unlock(&mutex);
128 }
129 
130 /*
131  * Return audit directory information from the audit control file.
132  */
133 int
134 getacdir(char *name, int len)
135 {
136 	char *dir;
137 	int ret = 0;
138 
139 	if (name == NULL) {
140 		errno = EINVAL;
141 		return (-2);
142 	}
143 
144 	pthread_mutex_lock(&mutex);
145 
146 	/*
147 	 * Check if another function was called between
148 	 * successive calls to getacdir
149 	 */
150 	if (inacdir && ptrmoved) {
151 		ptrmoved = 0;
152 		if (fp != NULL)
153 			fseek(fp, 0, SEEK_SET);
154 		ret = 2;
155 	}
156 
157 
158 	if (getstrfromtype_locked(DIR_CONTROL_ENTRY, &dir) < 0) {
159 		pthread_mutex_unlock(&mutex);
160 		return (-2);
161 	}
162 
163 	pthread_mutex_unlock(&mutex);
164 
165 	if (dir == NULL)
166 		return (-1);
167 
168 	if (strlen(dir) >= len)
169 		return (-3);
170 
171 	strcpy(name, dir);
172 
173 	return (ret);
174 }
175 
176 /*
177  * Return the minimum free diskspace value from the audit control file
178  */
179 int
180 getacmin(int *min_val)
181 {
182 	char *min;
183 
184 	setac();
185 
186 	if (min_val == NULL) {
187 		errno = EINVAL;
188 		return (-2);
189 	}
190 
191 	pthread_mutex_lock(&mutex);
192 
193 	if (getstrfromtype_locked(MINFREE_CONTROL_ENTRY, &min) < 0) {
194 		pthread_mutex_unlock(&mutex);
195 		return (-2);
196 	}
197 
198 	pthread_mutex_unlock(&mutex);
199 
200 	if (min == NULL)
201 		return (1);
202 
203 	*min_val = atoi(min);
204 
205 	return (0);
206 }
207 
208 /*
209  * Return the system audit value from the audit contol file.
210  */
211 int
212 getacflg(char *auditstr, int len)
213 {
214 	char *str;
215 
216 	setac();
217 
218 	if (auditstr == NULL) {
219 		errno = EINVAL;
220 		return (-2);
221 	}
222 
223 	pthread_mutex_lock(&mutex);
224 
225 	if (getstrfromtype_locked(FLAGS_CONTROL_ENTRY, &str) < 0) {
226 		pthread_mutex_unlock(&mutex);
227 		return (-2);
228 	}
229 
230 	pthread_mutex_unlock(&mutex);
231 
232 	if (str == NULL)
233 		return (1);
234 
235 	if (strlen(str) >= len)
236 		return (-3);
237 
238 	strcpy(auditstr, str);
239 
240 	return (0);
241 }
242 
243 /*
244  * Return the non attributable flags from the audit contol file.
245  */
246 int
247 getacna(char *auditstr, int len)
248 {
249 	char *str;
250 
251 	setac();
252 
253 	if (auditstr == NULL) {
254 		errno = EINVAL;
255 		return (-2);
256 	}
257 
258 	pthread_mutex_lock(&mutex);
259 
260 	if (getstrfromtype_locked(NA_CONTROL_ENTRY, &str) < 0) {
261 		pthread_mutex_unlock(&mutex);
262 		return (-2);
263 	}
264 	pthread_mutex_unlock(&mutex);
265 
266 	if (str == NULL)
267 		return (1);
268 
269 	if (strlen(str) >= len)
270 		return (-3);
271 
272 	strcpy(auditstr, str);
273 
274 	return (0);
275 }
276