8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libbsm / common / getauditflags.c
blob26a32e8d81fb36d3242ebbb25d344a0a091e08de
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
26 * get audit preselection mask values
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <string.h>
33 #include <sys/errno.h>
34 #include <sys/types.h>
35 #include <bsm/audit.h>
36 #include <bsm/libbsm.h>
38 #include <adt_xlate.h> /* adt_write_syslog */
40 #define SUCCESS 0x1 /* '+' success mask */
41 #define FAILURE 0x2 /* '-' failure mask */
42 #define INVERSE 0x4 /* '^' invert the mask */
44 static int
45 match_class(char *s, char *prefix, uint_t m, int v)
47 au_class_ent_t *p_class;
49 (void) strcat(s, prefix);
50 if (cacheauclass(&p_class, m) == 1) {
51 if (v == 0) {
52 (void) strncat(s, p_class->ac_name, AU_CLASS_NAME_MAX);
53 } else {
54 (void) strncat(s, p_class->ac_desc, AU_CLASS_DESC_MAX);
56 (void) strcat(s, ",");
57 return (0);
59 return (-1);
63 * getauditflagschar() - convert bit flag to character string
65 * input: masks->am_success - audit on success
66 * masks->am_failure - audit on failure
67 * verbose - string format. 0 if short name; 1 if long name;
69 * output: auditstring - resultant audit string
71 * returns: 0 - entry read ok
72 * -1 - error
75 int
76 getauditflagschar(char *auditstring, au_mask_t *masks, int verbose)
78 char *prefix; /* +, -, or null */
79 unsigned int m; /* for masking with masks */
80 au_mask_t all; /* value for the string "all" */
81 int plus_all = 0; /* true if +all */
82 int minus_all = 0; /* true if -all */
83 int l;
85 /* initialize input buffer */
86 *auditstring = '\0';
87 /* no masks, no flags; we're outta here */
88 if ((masks->am_success == 0) && (masks->am_failure == 0)) {
89 if (match_class(auditstring, "", 0, verbose) != 0)
90 return (-1);
91 /* kludge to get rid of trailing comma */
92 l = strlen(auditstring) - 1;
93 if (auditstring[l] == ',')
94 auditstring[l] = '\0';
95 return (0);
97 /* Get the mask value for the string "all" */
98 all.am_success = 0;
99 all.am_failure = 0;
100 if (getauditflagsbin("all", &all) != 0)
101 return (-1);
102 if (all.am_success == masks->am_success) {
103 if (all.am_failure == masks->am_failure) {
104 (void) strcat(auditstring, "all");
105 return (0);
107 (void) strcat(auditstring, "+all,");
108 plus_all = 1;
109 } else if (all.am_failure == masks->am_failure) {
110 (void) strcat(auditstring, "-all,");
111 minus_all = 1;
113 for (m = (unsigned)0x80000000; m != 0; m >>= 1) {
114 if (m & masks->am_success & masks->am_failure)
115 prefix = plus_all ? "-" : (minus_all ? "+" : "");
116 else if (m & masks->am_success)
117 prefix = "+";
118 else if (m & masks->am_failure)
119 prefix = "-";
120 else
121 continue;
122 if (match_class(auditstring, prefix, m, verbose) != 0)
123 return (-1);
125 if (*(prefix = auditstring + strlen(auditstring) - 1) == ',')
126 *prefix = '\0';
127 return (0);
132 * Audit flags:
134 * [+ | - | ^ | ^+ | ^-]<classname>{,[+ | - | ^ | ^+ | ^-]<classname>}*
136 * <classname>, add class mask to success and failure mask.
137 * +<classname>, add class mask only to success mask.
138 * -<classname>, add class mask only to failure mask.
139 * ^<classname>, remove class mask from success and failure mask.
140 * ^+<classname>, remove class mask from success mask.
141 * ^-<classname>, remove class mask from failure mask.
145 * __chkflags - check if the audit flags are valid for this system
147 * Entry flags = audit flags string.
148 * cont = B_TRUE, continue parsing even if error.
149 * B_FALSE, return failure on error.
151 * Exit mask = audit mask as defined by flags.
153 * Return B_TRUE if no errors, or continue == B_TRUE.
154 * B_FALSE and if error != NULL, flags in error.
157 boolean_t
158 __chkflags(char *flags, au_mask_t *mask, boolean_t cont, char **error)
160 uint32_t prefix;
161 au_class_ent_t *class;
162 char name[AU_CLASS_NAME_MAX+1];
163 int i;
165 if (flags == NULL || mask == NULL) {
166 return (B_FALSE);
169 mask->am_success = 0;
170 mask->am_failure = 0;
172 while (*flags != '\0') {
173 prefix = (SUCCESS | FAILURE);
175 /* skip white space */
176 while (isspace(*flags)) {
177 flags++;
180 if (flags == '\0') {
181 break;
183 if (error != NULL) {
184 /* save error pointer */
185 *error = flags;
188 /* get the prefix */
189 if (*flags == '+') {
190 flags++;
191 prefix ^= FAILURE;
192 } else if (*flags == '-') {
193 flags++;
194 prefix ^= SUCCESS;
195 } else if (*flags == '^') {
196 flags++;
197 prefix |= INVERSE;
198 if (*flags == '+') {
199 flags++;
200 prefix ^= FAILURE;
201 } else if (*flags == '-') {
202 flags++;
203 prefix ^= SUCCESS;
207 /* get class name */
209 for (i = 0; (i < sizeof (name) - 1) &&
210 !(*flags == '\0' || *flags == ','); i++) {
211 name[i] = *flags++;
213 name[i++] = '\0';
214 if (*flags == ',') {
215 /* skip comma (',') */
216 flags++;
218 if (cacheauclassnam(&class, name) != 1) {
219 if (!cont) {
220 return (B_FALSE);
221 } else {
222 char msg[512];
224 (void) snprintf(msg, sizeof (msg), "invalid "
225 "audit flag %s", name);
226 adt_write_syslog(msg, EINVAL);
228 } else {
229 /* add class mask */
231 if ((prefix & (INVERSE | SUCCESS)) == SUCCESS) {
232 mask->am_success |= class->ac_class;
233 } else if ((prefix & (INVERSE | SUCCESS)) ==
234 (INVERSE | SUCCESS)) {
235 mask->am_success &= ~(class->ac_class);
237 if ((prefix & (INVERSE | FAILURE)) == FAILURE) {
238 mask->am_failure |= class->ac_class;
239 } else if ((prefix & (INVERSE | FAILURE)) ==
240 (INVERSE | FAILURE)) {
241 mask->am_failure &= ~(class->ac_class);
246 return (B_TRUE);
250 * getauditflagsbin() - converts character string to success and
251 * failure bit masks
253 * input: auditstring - audit string
255 * output: masks->am_success - audit on success
256 * masks->am_failure - audit on failure
258 * returns: 0 - ok
259 * -1 - error - string or mask NULL.
263 getauditflagsbin(char *auditstring, au_mask_t *masks)
265 if (__chkflags(auditstring, masks, B_TRUE, NULL)) {
266 return (0);
268 return (-1);