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 (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 /* getacinfo.c  -  get audit control info */
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <sys/types.h>
     32 #include <bsm/audit.h>
     33 #include <bsm/libbsm.h>
     34 #include <synch.h>
     35 
     36 #define	DIROP 0
     37 #define	OTHEROP 1
     38 
     39 #define	LEN 360		/* maximum audit control entry length */
     40 
     41 #define	SUCCESS 0
     42 #define	EOF_WARN 1
     43 #define	REW_WARN 2
     44 #define	EOF_ERR -1
     45 #define	ERROR   -2
     46 #define	FORMAT_ERR -3
     47 
     48 static char	*AUDIT_CTRL  = AUDITCONTROLFILE;
     49 static char	*MINLABEL    = "minfree:";
     50 static char	*DIRLABEL    = "dir:";
     51 static char	*DEFFLGLABEL = "flags:";
     52 static char	*NAFLGLABEL  = "naflags:";
     53 static int	LASTOP;
     54 static int	DIRINIT;
     55 static FILE *acf;    /* pointer into audit control file */
     56 static mutex_t mutex_acf = DEFAULTMUTEX;
     57 
     58 /*
     59  * getacinfo.c  -  get audit control info
     60  *
     61  *	getacdir() - get audit control directories, one at a time
     62  *	getacflg() - get audit control default audit flags
     63  *	getacmin() - get audit control directory min. fill value
     64  *	getacna() -  get audit control non-attrib audit flags
     65  *	setac()    -  rewind the audit control file
     66  *	endac()    -  close the audit control file
     67  *	testac()   -  check if audit control file open
     68  */
     69 
     70 
     71 /*
     72  * getacdir() - get audit control directories, one at a time
     73  *
     74  * input: len  - size of dir buffer
     75  *
     76  * output: dir - directory string
     77  *
     78  * returns:	0 - entry read ok
     79  *		-1 - end of file
     80  *		-2 - error - can't open audit control file for read
     81  *		-3 - error - directory entry format error
     82  *		2 - directory search started from beginning again
     83  *
     84  * notes: It is the responsibility of the calling function to
     85  * 		check the status of the directory entry.
     86  */
     87 
     88 int
     89 getacdir(char *dir, int len)
     90 {
     91 	int	retstat = SUCCESS, gotone = 0, dirlen, dirst;
     92 	char	entry[LEN];
     93 	/* void	setac(); */
     94 
     95 	/* open file if it is not already opened */
     96 	(void) mutex_lock(&mutex_acf);
     97 	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
     98 		retstat = ERROR;
     99 	else if (LASTOP != DIROP && DIRINIT == 1) {
    100 		retstat = REW_WARN;
    101 		(void) mutex_unlock(&mutex_acf);
    102 		setac();
    103 	} else {
    104 		DIRINIT = 1;
    105 		LASTOP = DIROP;
    106 	}
    107 	if (retstat >= SUCCESS) do {
    108 		if (fgets(entry, LEN, acf) != NULL) {
    109 			switch (*entry) {
    110 
    111 			case '#':
    112 
    113 			break;
    114 
    115 			case 'd':
    116 
    117 			/* return directory entry */
    118 			if (strncmp(entry, DIRLABEL, strlen(DIRLABEL)) == 0) {
    119 				if ((strlen(entry) + 1) > (size_t)len) {
    120 					retstat = FORMAT_ERR;
    121 				} else {
    122 					/*
    123 					 * allow zero or one blank
    124 					 * between colon and directory
    125 					 */
    126 					if (entry[strlen(DIRLABEL)] == ' ') {
    127 						dirst = strlen(DIRLABEL) + 1;
    128 						dirlen = strlen(entry) -
    129 						    (strlen(DIRLABEL) + 2);
    130 					} else {
    131 						dirst = strlen(DIRLABEL);
    132 						dirlen = strlen(entry) -
    133 						    (strlen(DIRLABEL) + 1);
    134 					}
    135 					(void) strcpy(dir, entry + dirst);
    136 					(void) strcpy(dir + dirlen, "\0");
    137 					gotone = 1;
    138 				}
    139 			} else
    140 				retstat = FORMAT_ERR;
    141 
    142 			break;
    143 
    144 			case 'm':
    145 
    146 			break;
    147 
    148 			case 'f':
    149 
    150 			break;
    151 
    152 			default:
    153 
    154 			break;
    155 
    156 			} /* end of switch */
    157 		} else if ((feof(acf)) == 0) {
    158 			retstat = ERROR;
    159 		} else {
    160 			retstat = EOF_ERR;
    161 		}
    162 	} while (gotone == 0 && retstat >= SUCCESS);
    163 
    164 	(void) mutex_unlock(&mutex_acf);
    165 	return (retstat);
    166 }
    167 
    168 
    169 /*
    170  * getacmin() - get audit control directory min. fill value
    171  *
    172  * output: min_val - percentage of directory fill allowed
    173  *
    174  * returns:	0 - entry read ok
    175  *		1 - end of file
    176  *		-2 - error; errno contains error number
    177  *		-3 - error - directory entry format error
    178  */
    179 
    180 int
    181 getacmin(int *min_val)
    182 {
    183 	int	retstat = SUCCESS, gotone = 0;
    184 	char	entry[LEN];
    185 
    186 	/* open file if it is not already opened */
    187 	(void) mutex_lock(&mutex_acf);
    188 	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
    189 		retstat = ERROR;
    190 	else
    191 		rewind(acf);
    192 
    193 	if (retstat == SUCCESS) {
    194 		do {
    195 			if (fgets(entry, LEN, acf) != NULL) {
    196 				switch (*entry) {
    197 				case '#':
    198 					break;
    199 				case 'd':
    200 					break;
    201 				case 'm':
    202 					if (strncmp(entry, MINLABEL,
    203 					    strlen(MINLABEL)) == 0) {
    204 						(void) sscanf(entry +
    205 						    strlen(MINLABEL),
    206 						    "%d", min_val);
    207 						gotone = 1;
    208 					} else
    209 						retstat = FORMAT_ERR;
    210 					break;
    211 				case 'f':
    212 					break;
    213 				default:
    214 					break;
    215 				}
    216 			} else if ((feof(acf)) == 0)
    217 				retstat = ERROR;
    218 				else
    219 				retstat = EOF_WARN;
    220 
    221 		} while (gotone == 0 && retstat == SUCCESS);
    222 	}
    223 
    224 	if (LASTOP == DIROP)
    225 		LASTOP = OTHEROP;
    226 	else {
    227 		if (acf != NULL) {
    228 			(void) fclose(acf);
    229 			acf = NULL;
    230 		}
    231 		LASTOP = DIROP;
    232 		DIRINIT = 0;
    233 	}
    234 
    235 	(void) mutex_unlock(&mutex_acf);
    236 	return (retstat);
    237 }
    238 
    239 
    240 /*
    241  * getacflg() - get audit control flags
    242  *
    243  * output: auditstring - character representation of system audit flags
    244  *
    245  * returns:	0 - entry read ok
    246  *		1 - end of file
    247  *		-2 - error - errno contains error number
    248  *		-3 - error - directory entry format error
    249  */
    250 
    251 int
    252 getacflg(char *auditstring, int len)
    253 {
    254 	int	retstat = SUCCESS, gotone = 0, minst, minlen;
    255 	char	entry[LEN];
    256 
    257 	/* open file if it is not already opened */
    258 	(void) mutex_lock(&mutex_acf);
    259 	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL)
    260 		retstat = ERROR;
    261 	else
    262 		rewind(acf);
    263 
    264 	if (retstat == SUCCESS) do {
    265 		if (fgets(entry, LEN, acf) != NULL) {
    266 			switch (*entry) {
    267 			case '#':
    268 				break;
    269 			case 'd':
    270 				break;
    271 			case 'm':
    272 				break;
    273 			case 'f':
    274 
    275 			if ((strncmp(entry, DEFFLGLABEL,
    276 			    strlen(DEFFLGLABEL))) == 0) {
    277 				if (entry[strlen(DEFFLGLABEL)] == ' ') {
    278 					minst = strlen(DEFFLGLABEL) + 1;
    279 					minlen = strlen(entry) -
    280 					    (strlen(DEFFLGLABEL) + 2);
    281 				} else {
    282 					minst = strlen(DEFFLGLABEL);
    283 					minlen = strlen(entry) -
    284 					    (strlen(DEFFLGLABEL) + 1);
    285 				}
    286 				if (minlen > len)
    287 					retstat = FORMAT_ERR;
    288 				else {
    289 					(void) strcpy(auditstring,
    290 					    entry + minst);
    291 					(void) strcpy(auditstring + minlen,
    292 					    "\0");
    293 					gotone = 1;
    294 				}
    295 			} else
    296 				retstat = FORMAT_ERR;
    297 
    298 			break; /* end of case f */
    299 
    300 			default:
    301 				break;
    302 			}
    303 		} else if ((feof(acf)) == 0) {
    304 			retstat = ERROR;
    305 		} else {
    306 			retstat = EOF_WARN;
    307 		}
    308 	} while (gotone == 0 && retstat == SUCCESS);
    309 
    310 	if (LASTOP == DIROP)
    311 		LASTOP = OTHEROP;
    312 	else {
    313 		if (acf != NULL) {
    314 			(void) fclose(acf);
    315 			acf = NULL;
    316 		}
    317 		LASTOP = DIROP;
    318 		DIRINIT = 0;
    319 	}
    320 
    321 	(void) mutex_unlock(&mutex_acf);
    322 	return (retstat);
    323 }
    324 
    325 
    326 /*
    327  * getacna() - get audit flags for non-attributable (server) events
    328  *
    329  * output: auditstring - character representation of system audit flags
    330  *
    331  * returns:	0 - entry read ok
    332  *		1 - end of file
    333  *		-2 - error - errno contains error number
    334  *		-3 - error - directory entry format error
    335  */
    336 
    337 int
    338 getacna(char *auditstring, int len)
    339 {
    340 	int	retstat = SUCCESS, gotone = 0, minst, minlen;
    341 	char	entry[LEN];
    342 
    343 	/* open file if it is not already opened */
    344 	(void) mutex_lock(&mutex_acf);
    345 	if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) {
    346 		retstat = ERROR;
    347 	} else {
    348 		rewind(acf);
    349 	}
    350 
    351 	if (retstat == SUCCESS) do {
    352 		if (fgets(entry, LEN, acf) != NULL)
    353 			switch (*entry) {
    354 			case '#':
    355 				break;
    356 			case 'd':
    357 				break;
    358 			case 'm':
    359 				break;
    360 			case 'f':
    361 				break;
    362 			case 'n':
    363 
    364 			if ((strncmp(entry, NAFLGLABEL,
    365 			    strlen(NAFLGLABEL))) == 0) {
    366 				if (entry[strlen(NAFLGLABEL)] == ' ') {
    367 					minst = strlen(NAFLGLABEL) + 1;
    368 					minlen = strlen(entry) -
    369 					    (strlen(NAFLGLABEL) + 2);
    370 				} else {
    371 					minst = strlen(NAFLGLABEL);
    372 					minlen = strlen(entry) -
    373 					    (strlen(NAFLGLABEL) + 1);
    374 				}
    375 				if (minlen > len)
    376 					retstat = FORMAT_ERR;
    377 				else {
    378 					(void) strcpy(auditstring,
    379 					    entry + minst);
    380 					(void) strcpy(auditstring + minlen,
    381 					    "\0");
    382 					gotone = 1;
    383 				}
    384 			} else
    385 				retstat = FORMAT_ERR;
    386 
    387 			break; /* end of case n */
    388 
    389 			default:
    390 				break;
    391 
    392 		/* end of if-switch */
    393 		} else if ((feof(acf)) == 0) {
    394 			retstat = ERROR;
    395 		} else {
    396 			retstat = EOF_WARN;
    397 		}
    398 
    399 	/* end of if-do */
    400 	} while (gotone == 0 && retstat == SUCCESS);
    401 
    402 	if (LASTOP == DIROP)
    403 		LASTOP = OTHEROP;
    404 	else {
    405 		if (acf != NULL) {
    406 			(void) fclose(acf);
    407 			acf = NULL;
    408 		}
    409 		LASTOP = DIROP;
    410 		DIRINIT = 0;
    411 	}
    412 
    413 	(void) mutex_unlock(&mutex_acf);
    414 	return (retstat);
    415 }
    416 
    417 
    418 /* rewind the audit control file */
    419 void
    420 setac()
    421 {
    422 	(void) mutex_lock(&mutex_acf);
    423 	if (acf == NULL)
    424 		acf = fopen(AUDIT_CTRL, "rF");
    425 	else
    426 		rewind(acf);
    427 	LASTOP = DIROP;
    428 	DIRINIT = 0;
    429 	(void) mutex_unlock(&mutex_acf);
    430 }
    431 
    432 
    433 /* close the audit control file */
    434 void
    435 endac()
    436 {
    437 	(void) mutex_lock(&mutex_acf);
    438 	if (acf != NULL) {
    439 		(void) fclose(acf);
    440 		acf = NULL;
    441 	}
    442 	LASTOP = DIROP;
    443 	DIRINIT = 0;
    444 	(void) mutex_unlock(&mutex_acf);
    445 }
    446