xref: /titanic_41/usr/src/lib/libbc/libc/gen/common/getauditflags.c (revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1992 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/label.h>
33 #include <sys/audit.h>
34 #include <auevents.h>
35 
36 #define ON 1
37 #define OK 0
38 #define OFF -1
39 #define COMMA  ','
40 #define COMMASTR ","
41 
42 #define COMMON 0
43 #define SUCCESS 1
44 #define FAILURE 2
45 
46 #define MAXFLDLEN 25
47 #define MAXSTRLEN 360
48 #define MAXEVENT 11
49 
50 /* GLOBALS */
51 
52 static int length;
53 static int pos = 0;
54 
55 struct list {
56 	short count;
57 	short on[MAXEVENT+1];
58 	short off;
59 };
60 typedef struct list list_t;
61 
62 struct exception {
63 	short type;
64 	short exception;
65 };
66 typedef struct exception except_t;
67 
68 static int	stringcopy(char *, char *, int);
69 
70 /*
71  * getauditflagschar() - convert bit flag to character string
72  *
73  * input: masks->as_success - audit on success
74  *	  masks->as_failure - audit on failure
75  *  	  verbose     - string format. 0 if short name; 1 if long name;
76  *
77  * output: auditstring - resultant audit string
78  *
79  * returns:  	0 - entry read ok
80  *    		-1 - error
81  */
82 
83 int
getauditflagschar(char * auditstring,audit_state_t * masks,int verbose)84 getauditflagschar(char *auditstring, audit_state_t *masks, int verbose)
85 {
86 	int i, j, k, mask_num;
87 	int list = -1, retstat = 0;
88 	int except_list[3];
89 	char *prefix = "  ";
90 	except_t except[2];
91 	list_t lists[3];
92 
93 	/*
94 	 * initialize input buffer
95 	 */
96 	strcpy(auditstring, "");
97 	/*
98 	 * initialize lists struct
99 	 */
100 	for (mask_num = COMMON; mask_num <= FAILURE; mask_num++) {
101 		lists[mask_num].count = 0;
102 		lists[mask_num].off = -1;
103 		for (i=0;i<MAXEVENT+1;i++)
104 			lists[mask_num].on[i] = -1;
105 	}
106 	/*
107 	 * initialize exception lists
108 	 */
109 	for (i = 0; i < 2; i++) {
110 		except[i].type = -1;
111 		except[i].exception = -1;
112 	}
113 
114 	for (i = 0; i < 3; i++)
115 		except_list[i] = 0;
116 
117 	/*
118 	 * set length global
119 	 */
120 	length = verbose;
121 	pos = 0;
122 
123 	/*
124 	 * find turned-on events - if on, store index of event
125 	 * in one of the three event lists, common, success, failure.
126 	 */
127 	for ( i = 0; i < MAXEVENT; i++) {
128 		if (((event_class[i].event_mask & masks->as_success) > 0) ||
129 		  ((event_class[i].event_mask & masks->as_failure) > 0)) {
130 
131 			/*
132 			 * check for events in common
133 			 */
134 			if (((event_class[i].event_mask & masks->as_success) >
135 			  0) &&
136 			  ((event_class[i].event_mask & masks->as_failure) > 0))
137 				lists[COMMON].on[lists[COMMON].count++] = i;
138 
139 			/*
140 			 * check for success events
141 			 */
142 			if ((event_class[i].event_mask & masks->as_success) > 0)
143 				lists[SUCCESS].on[lists[SUCCESS].count++] = i;
144 			else {
145 				except_list[SUCCESS]++;
146 			if (lists[SUCCESS].off == -1)
147 				lists[SUCCESS].off = i;
148 			}
149 			/*
150 			 * check for failure events
151 			 */
152 			if ((event_class[i].event_mask & masks->as_failure) > 0)
153 				lists[FAILURE].on[lists[FAILURE].count++] = i;
154 			else {
155 				except_list[FAILURE]++;
156 				if (lists[FAILURE].off == -1)
157 				lists[FAILURE].off = i;
158 			}
159 		} else {
160 			except_list[COMMON]++;
161 			if (lists[COMMON].off == -1)
162 			lists[COMMON].off = i;
163 		}
164 	}
165 	/*
166 	* check for all set or all-1 set - output all and common exceptions.
167 	*   the all or common state is exclusive; only one of the
168 	*   three, (+-)all, allowed
169 	*/
170 	/*
171 	 * no exceptions
172 	 */
173 	if (lists[COMMON].count >= MAXEVENT-2) {
174 		if (lists[COMMON].count == MAXEVENT)
175 			list = COMMON;
176 
177 		/*
178 		 * one exception
179 		 */
180 		else if (lists[COMMON].count == MAXEVENT-1) {
181 			for (i=COMMON;i<=FAILURE && (list == -1);i++) {
182 				if (except_list[i] == 1) {
183 					list = COMMON;
184 					except[0].type = i;
185 					except[0].exception = lists[i].off;
186 				}
187 			}
188 		}
189 		/*
190 		 * two exceptions
191 		 */
192 		else if (lists[COMMON].count == MAXEVENT-2) {
193 			if (except_list[COMMON] == 1) {
194 				list = COMMON;
195 				except[0].type = COMMON;
196 				except[0].exception = lists[COMMON].off;
197 				for (i=SUCCESS;i<=FAILURE;i++) {
198 					if (except_list[i] == 1) {
199 						except[1].type = i;
200 						except[1].exception = lists[i].off;
201 					}
202 				}
203 
204 			 } else if (except_list[COMMON] == 0) {
205 				for (i=SUCCESS,j=0;i<=FAILURE;i++) {
206 					if (except_list[i] == 1) {
207 						list = COMMON;
208 						except[j].type = i;
209 						except[j++].exception = lists[i].off;
210 					}
211 				}
212 			}
213 		}
214 	} else {
215 		/*
216 		 * check for +all or -all
217 		 */
218 		for (i=SUCCESS,j=0;i<=FAILURE;i++) {
219 			if (lists[i].count >= MAXEVENT-1) {
220 				list = i;
221 				except[j].type = i;
222 				if (lists[i].count != MAXEVENT) {
223 					if (lists[i].off != -1)
224 						except[j++].exception =
225 						  lists[i].off;
226 					else
227 						except[j++].exception =
228 						  lists[COMMON].off;
229 				}
230 			}
231 		}
232 	}
233 	/*
234 	 * output all and exceptions
235 	 */
236 	if (list != -1) {
237 		if(list==SUCCESS) {
238 			if ((stringcopy(auditstring, "+", 0)) == -1)
239 				retstat = -1;
240 		}
241 		if(list==FAILURE) {
242 			if ((stringcopy(auditstring, "-", 0)) == -1)
243 				retstat = -1;
244 		}
245 
246 		if (retstat == 0) {
247 			if (length) {
248 				if
249 				  ((stringcopy(auditstring,event_class[11].event_lname,1)) == -1)
250 					retstat = -1;
251 			} else
252 				if ((stringcopy(auditstring, event_class[11].event_sname,1)) == -1)
253 					retstat = -1;
254 		}
255 
256 		if (retstat == 0) {
257 			/*
258 			 * output exceptions
259 			 */
260 			for (i=0;i<2 && except[i].exception != -1; i++) {
261 				if ((stringcopy(auditstring, "^", 0)) == -1)
262 					retstat = -1;
263 				if(except[i].type==SUCCESS) {
264 					if ((stringcopy(auditstring, "+", 0)) == -1)
265 						retstat = -1;
266 				}
267 				if (except[i].type==FAILURE) {
268 					if ((stringcopy(auditstring, "-", 0)) == -1)
269 						retstat = -1;
270 				}
271 				if (length == 1 && retstat == 0) {
272 					if ((stringcopy(auditstring,
273 					 event_class[except[i].exception].event_lname, 1))==-1)
274 						retstat = -1;
275 				} else if (retstat == 0) {
276 					if ((stringcopy(auditstring,
277 					event_class[except[i].exception].event_sname, 1))==-1)
278 						retstat = -1;
279 				}
280 			}
281 		}
282 	} /* end of " all " processing */
283 
284 	/*
285 	 * process common events if no "all" was output
286 	 */
287 	if (list == -1 && (lists[COMMON].count > 0) && retstat == 0) {
288 		/*
289 		 * output common events first
290 		 */
291 		for (j=0;j<lists[COMMON].count;j++) {
292 			if (length == 1) {
293 				if ((stringcopy(auditstring,
294 				 event_class[lists[COMMON].on[j]].event_lname, 1)) == -1)
295 					retstat = -1;
296 			} else if ((stringcopy(auditstring,
297 			 event_class[lists[COMMON].on[j]].event_sname, 1)) == -1)
298 				retstat = -1;
299 		}
300 		/*
301 		 * remove common events from individual lists
302 		 */
303 		if (retstat == 0) {
304 			for (i=SUCCESS;i<=FAILURE;i++) {
305 				for(j=0;j<lists[COMMON].count;j++) {
306 					for(k=0;k < lists[i].count;k++) {
307 						if (lists[COMMON].on[j] ==
308 						  lists[i].on[k])
309 							lists[i].on[k] = -1;
310 					}
311 				}
312 			}
313 		}
314 	}
315 
316 	/*
317 	 * start processing individual event flags in success
318 	 * and failure lists
319 	 */
320 	if (list != COMMON && retstat == 0) {
321 		for (i=SUCCESS;i<=FAILURE;i++) {
322 			if(list != i) {
323 				if (i==SUCCESS) strcpy(prefix, "+");
324 				if (i==FAILURE) strcpy(prefix, "-");
325 				for (j=0;j<MAXEVENT && j<lists[i].count;j++) {
326 					if (lists[i].on[j] != -1) {
327 						if ((stringcopy(auditstring, prefix, 0)) == -1)
328 							retstat = -1;
329 						if (length == 1 &&
330 						  retstat == 0) {
331 							if ((stringcopy(auditstring,
332 							  event_class[lists[i].on[j]].event_lname, 1))==-1)
333 							retstat = -1;
334 						} else if (retstat == 0) {
335 							if ((stringcopy(auditstring,
336 							 event_class[lists[i].on[j]].event_sname, 1))==-1)
337 								retstat = -1;
338 						}
339 					}
340 				}
341 			}
342 		}
343 	}
344 	if ((stringcopy(auditstring, "\0", 2)) == -1)
345 		retstat = -1;
346 
347 	return (retstat);
348 }
349 
350 static int
stringcopy(char * auditstring,char * event,int flag)351 stringcopy(char *auditstring, char *event,
352     int flag)	/* if set, output comma after event */
353 {
354 	int retstat = 0;
355 
356 	/*
357 	 * check size
358 	 */
359 	if (pos >= MAXSTRLEN) {
360 		fprintf(stderr,"getauditflagschar: Inputted buffer too small.\n");
361 		retstat = -1;
362 	} else if (flag != 2) {
363 		strcpy(auditstring+pos, event);
364 		pos += strlen(event);
365 		if(flag) {
366 			strcpy(auditstring+pos, COMMASTR);
367 			pos += strlen(COMMASTR);
368 		}
369 	} else {
370 		/*
371 		 * add null terminator only
372 		 */
373 		if (pos)
374 			strcpy(auditstring+(pos-1), event);
375 
376 	}
377 	return (retstat);
378 }
379 
380 /*
381  * getauditflagsbin() -  converts character string to success and
382  *			 failure bit masks
383  *
384  * input: auditstring - audit string
385  *  	  cnt - number of elements in the masks array
386  *
387  * output: masks->as_success - audit on success
388  *         masks->as_failure - audit on failure
389  *
390  * returns: 0 - ok
391  *    	    -1 - error - string contains characters which do
392  *        		not match event flag names
393  */
394 
395 int
getauditflagsbin(char * auditstring,audit_state_t * masks)396 getauditflagsbin(char *auditstring, audit_state_t *masks)
397 {
398 	int i, gotone, done = 0, invert = 0, tryagain;
399 	int retstat = 0, succ_event, fail_event;
400 	char *ptr, tmp_buff[MAXFLDLEN];
401 
402 	/*
403 	 * process character string
404 	 */
405 	do {
406 		gotone = 0;
407 		/*
408 		 * read through string storing chars. until a comma
409 		 */
410 		for (ptr=tmp_buff; !gotone;) {
411 			if(*auditstring!=COMMA && *auditstring!='\0' &&
412 			  *auditstring!='\n' && *auditstring!=' ')
413 				*ptr++ = *auditstring++;
414 			else if (*auditstring == ' ')
415 				*auditstring++;
416 			else {
417 				if (*auditstring == '\0' ||
418 				  *auditstring == '\n') {
419 					done = 1;
420 					if (ptr == tmp_buff)
421 						done = 2;
422 				}
423 				gotone = 1;
424 			}
425 		}
426 		/*
427 		 * process audit state
428 		 */
429 		if(gotone && done != 2) {
430 			if(!done) auditstring++;
431 			*ptr++ = '\0';
432 			ptr = tmp_buff;
433 			gotone = 0;
434 			succ_event = ON;
435 			fail_event = ON;
436 			tryagain = 1;
437 			invert = 0;
438 
439 			/*
440 			 * get flags
441 			 */
442 			do {
443 				switch (*ptr++) {
444 				case '^':
445 					invert = 1;
446 					succ_event = OFF;
447 					fail_event = OFF;
448 					break;
449 				case '+':
450 					if (invert)
451 						fail_event = OK;
452 					else {
453 						succ_event = ON;
454 						fail_event = OK;
455 					}
456 					break;
457 				case '-':
458 					if (invert)
459 						succ_event = OK;
460 					else {
461 						fail_event = ON;
462 						succ_event = OK;
463 					}
464 					break;
465 				default:
466 					tryagain = 0;
467 					ptr--;
468 					break;
469 				}
470 			} while(tryagain);
471 
472 			/* add audit state to mask */
473 			for (i=0;i<MAXEVENT+1 && !gotone;i++) {
474 				if ((!(strcmp(ptr, event_class[i].event_sname))) ||
475 				 (!(strcmp(ptr, event_class[i].event_lname)))) {
476 					if (succ_event == ON)
477 						masks->as_success |= event_class[i].event_mask;
478 					else if (succ_event == OFF)
479 						masks->as_success &= ~(event_class[i].event_mask);
480 					if (fail_event == ON)
481 						masks->as_failure |= event_class[i].event_mask;
482 					else if (fail_event == OFF)
483 						masks->as_failure &= ~(event_class[i].event_mask);
484 					gotone = 1;
485 				}
486 			}
487 			if(!gotone) {
488 				retstat = -1;
489 				done = 1;
490 			}
491 		}
492 	} while (!done);
493 
494 	return (retstat);
495 }
496