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 2003 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  * get audit preselection mask values
     30  */
     31 
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <syslog.h>
     35 #include <sys/types.h>
     36 #include <bsm/audit.h>
     37 #include <bsm/libbsm.h>
     38 
     39 #define	ON 1
     40 #define	OK 0
     41 #define	OFF -1
     42 #define	COMMA  ','
     43 
     44 #define	MAXFLDLEN 25
     45 
     46 int getauditflagsbin();
     47 
     48 static int
     49 match_class(s, prefix, m, v)
     50 char	*s;
     51 char	*prefix;
     52 unsigned int	m;
     53 int	v;
     54 {
     55 	au_class_ent_t *p_class;
     56 
     57 	(void) strcat(s, prefix);
     58 	if (cacheauclass(&p_class, m) == 1) {
     59 		(void) strcat(s, v ? p_class->ac_desc : p_class->ac_name);
     60 		(void) strcat(s, ",");
     61 		return (0);
     62 	}
     63 	return (-1);
     64 }
     65 
     66 
     67 /*
     68  * getauditflagschar() - convert bit flag to character string
     69  *
     70  * input:	masks->am_success - audit on success
     71  *		masks->am_failure - audit on failure
     72  *		verbose - string format. 0 if short name; 1 if long name;
     73  *
     74  * output: auditstring - resultant audit string
     75  *
     76  * returns: 	0 - entry read ok
     77  *		-1 - error
     78  */
     79 
     80 int
     81 getauditflagschar(auditstring, masks, verbose)
     82 char	*auditstring;
     83 au_mask_t *masks;
     84 int	verbose;
     85 {
     86 	char	*prefix;		/* +, -, or null */
     87 	unsigned int	m;		/* for masking with masks */
     88 	au_mask_t all; 		/* value for the string "all" */
     89 	int	plus_all = 0;	/* true if +all */
     90 	int	minus_all = 0;	/* true if -all */
     91 	int	l;
     92 
     93 	/* initialize input buffer */
     94 	*auditstring = '\0';
     95 	/* no masks, no flags; we're outta here */
     96 	if ((masks->am_success == 0) && (masks->am_failure == 0)) {
     97 		if (match_class(auditstring, "", 0, verbose) != 0)
     98 			return (-1);
     99 		/* kludge to get rid of trailing comma */
    100 		l = strlen(auditstring) - 1;
    101 		if (auditstring[l] == COMMA)
    102 			auditstring[l] = '\0';
    103 		return (0);
    104 	}
    105 	/* Get the mask value for the string "all" */
    106 	all.am_success = 0;
    107 	all.am_failure = 0;
    108 	if (getauditflagsbin("all", &all) != 0)
    109 		return (-1);
    110 	if (all.am_success == masks->am_success) {
    111 		if (all.am_failure == masks->am_failure) {
    112 			(void) strcat(auditstring, "all");
    113 			return (0);
    114 		}
    115 		(void) strcat(auditstring, "+all,");
    116 		plus_all = 1;
    117 	} else if (all.am_failure == masks->am_failure) {
    118 		(void) strcat(auditstring, "-all,");
    119 		minus_all = 1;
    120 	}
    121 	for (m = (unsigned)0x80000000; m != 0; m >>= 1) {
    122 		if (m & masks->am_success & masks->am_failure)
    123 			prefix = plus_all ? "-" : (minus_all ? "+" : "");
    124 		else if (m & masks->am_success)
    125 			prefix = "+";
    126 		else if (m & masks->am_failure)
    127 			prefix = "-";
    128 			else
    129 			continue;
    130 		if (match_class(auditstring, prefix, m, verbose) != 0)
    131 			return (-1);
    132 	}
    133 	if (*(prefix = auditstring + strlen(auditstring) - 1) == COMMA)
    134 		*prefix = '\0';
    135 	return (0);
    136 
    137 }
    138 
    139 /*
    140  * getauditflagsbin() -  converts character string to success and
    141  *			 failure bit masks
    142  *
    143  * input:	auditstring - audit string
    144  *		cnt - number of elements in the masks array
    145  *
    146  * output:	masks->am_success - audit on success
    147  *		masks->am_failure - audit on failure
    148  *
    149  * returns: 0 - ok
    150  *	    -1 - error - string contains characters which do
    151  *		not match event flag names or invalid pointers
    152  *              passed in.
    153  */
    154 
    155 int
    156 getauditflagsbin(auditstring, masks)
    157 char	*auditstring;
    158 au_mask_t *masks;
    159 {
    160 	int	gotone, done = 0, invert = 0, tryagain;
    161 	int	retstat = 0, succ_event, fail_event;
    162 	char	*ptr, tmp_buff[MAXFLDLEN];
    163 	au_class_ent_t *p_class;
    164 
    165 	if ((masks == NULL) || (auditstring == NULL))
    166 		return (-1);
    167 
    168 	masks->am_success = masks->am_failure = 0;
    169 
    170 	/* process character string */
    171 	do {
    172 		gotone = 0;
    173 		/* read through string storing chars. until a comma */
    174 		for (ptr = tmp_buff; !gotone; /* */) {
    175 			if (*auditstring != COMMA && *auditstring != '\0' &&
    176 			    *auditstring != '\n' && *auditstring != ' ' &&
    177 			    *auditstring != '\t')
    178 				*ptr++ = *auditstring++;
    179 			else if (*auditstring == ' ' || *auditstring == '\t')
    180 				auditstring++;
    181 			else {
    182 				if (*auditstring == '\0' ||
    183 						*auditstring == '\n') {
    184 					done = 1;
    185 					if (ptr == tmp_buff)
    186 						done = 2;
    187 				}
    188 				gotone = 1;
    189 			}
    190 		}
    191 		/* * process audit state */
    192 		if (gotone && done != 2) {
    193 			if (!done)
    194 				auditstring++;
    195 			*ptr++ = '\0';
    196 			ptr = tmp_buff;
    197 			gotone = 0;
    198 			succ_event = ON;
    199 			fail_event = ON;
    200 			tryagain = 1;
    201 			invert = 0;
    202 
    203 			/* get flags */
    204 			do {
    205 				switch (*ptr++) {
    206 				case '^':
    207 					invert = 1;
    208 					succ_event = OFF;
    209 					fail_event = OFF;
    210 					break;
    211 				case '+':
    212 					if (invert)
    213 						fail_event = OK;
    214 					else {
    215 						succ_event = ON;
    216 						fail_event = OK;
    217 					}
    218 					break;
    219 				case '-':
    220 					if (invert)
    221 						succ_event = OK;
    222 					else {
    223 						fail_event = ON;
    224 						succ_event = OK;
    225 					}
    226 					break;
    227 				default:
    228 					tryagain = 0;
    229 					ptr--;
    230 					break;
    231 				}
    232 			} while (tryagain);
    233 
    234 			/* add audit state to mask */
    235 
    236 
    237 			if (cacheauclassnam(&p_class, ptr) == 1) {
    238 				if (succ_event == ON)
    239 					masks->am_success |= p_class->ac_class;
    240 				else if (succ_event == OFF)
    241 					masks->am_success &=
    242 						~(p_class->ac_class);
    243 				if (fail_event == ON)
    244 					masks->am_failure |= p_class->ac_class;
    245 				else if (fail_event == OFF)
    246 					masks->am_failure &=
    247 						~(p_class->ac_class);
    248 				gotone = 1;
    249 			} else {  /* Bug 4330887 */
    250 				syslog(LOG_CRIT,
    251 					"auditflags have invalid flag %s",
    252 					ptr);
    253 				continue;
    254 			}
    255 			if (!gotone) {
    256 				retstat = -1;
    257 				done = 1;
    258 			}
    259 		}
    260 	} while (!done);
    261 
    262 
    263 	return (retstat);
    264 }
    265