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