Home | History | Annotate | Download | only in common
      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
     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
    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
    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