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