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 1992 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" /* c2 secure */ 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <sys/types.h> 32 #include <sys/label.h> 33 #include <sys/audit.h> 34 #include <auevents.h> 35 36 #define ON 1 37 #define OK 0 38 #define OFF -1 39 #define COMMA ',' 40 #define COMMASTR "," 41 42 #define COMMON 0 43 #define SUCCESS 1 44 #define FAILURE 2 45 46 #define MAXFLDLEN 25 47 #define MAXSTRLEN 360 48 #define MAXEVENT 11 49 50 /* GLOBALS */ 51 52 static int length; 53 static int pos = 0; 54 55 struct list { 56 short count; 57 short on[MAXEVENT+1]; 58 short off; 59 }; 60 typedef struct list list_t; 61 62 struct exception { 63 short type; 64 short exception; 65 }; 66 typedef struct exception except_t; 67 68 /* 69 * getauditflagschar() - convert bit flag to character string 70 * 71 * input: masks->as_success - audit on success 72 * masks->as_failure - audit on failure 73 * verbose - string format. 0 if short name; 1 if long name; 74 * 75 * output: auditstring - resultant audit string 76 * 77 * returns: 0 - entry read ok 78 * -1 - error 79 */ 80 81 getauditflagschar(auditstring, masks, verbose) 82 char *auditstring; 83 audit_state_t *masks; 84 int verbose; 85 { 86 int i, j, k, mask_num; 87 int list = -1, retstat = 0; 88 int except_list[3]; 89 char *prefix = " "; 90 except_t except[2]; 91 list_t lists[3]; 92 93 /* 94 * initialize input buffer 95 */ 96 strcpy(auditstring, ""); 97 /* 98 * initialize lists struct 99 */ 100 for (mask_num = COMMON; mask_num <= FAILURE; mask_num++) { 101 lists[mask_num].count = 0; 102 lists[mask_num].off = -1; 103 for (i=0;i<MAXEVENT+1;i++) 104 lists[mask_num].on[i] = -1; 105 } 106 /* 107 * initialize exception lists 108 */ 109 for (i = 0; i < 2; i++) { 110 except[i].type = -1; 111 except[i].exception = -1; 112 } 113 114 for (i = 0; i < 3; i++) 115 except_list[i] = 0; 116 117 /* 118 * set length global 119 */ 120 length = verbose; 121 pos = 0; 122 123 /* 124 * find turned-on events - if on, store index of event 125 * in one of the three event lists, common, success, failure. 126 */ 127 for ( i = 0; i < MAXEVENT; i++) { 128 if (((event_class[i].event_mask & masks->as_success) > 0) || 129 ((event_class[i].event_mask & masks->as_failure) > 0)) { 130 131 /* 132 * check for events in common 133 */ 134 if (((event_class[i].event_mask & masks->as_success) > 135 0) && 136 ((event_class[i].event_mask & masks->as_failure) > 0)) 137 lists[COMMON].on[lists[COMMON].count++] = i; 138 139 /* 140 * check for success events 141 */ 142 if ((event_class[i].event_mask & masks->as_success) > 0) 143 lists[SUCCESS].on[lists[SUCCESS].count++] = i; 144 else { 145 except_list[SUCCESS]++; 146 if (lists[SUCCESS].off == -1) 147 lists[SUCCESS].off = i; 148 } 149 /* 150 * check for failure events 151 */ 152 if ((event_class[i].event_mask & masks->as_failure) > 0) 153 lists[FAILURE].on[lists[FAILURE].count++] = i; 154 else { 155 except_list[FAILURE]++; 156 if (lists[FAILURE].off == -1) 157 lists[FAILURE].off = i; 158 } 159 } else { 160 except_list[COMMON]++; 161 if (lists[COMMON].off == -1) 162 lists[COMMON].off = i; 163 } 164 } 165 /* 166 * check for all set or all-1 set - output all and common exceptions. 167 * the all or common state is exclusive; only one of the 168 * three, (+-)all, allowed 169 */ 170 /* 171 * no exceptions 172 */ 173 if (lists[COMMON].count >= MAXEVENT-2) { 174 if (lists[COMMON].count == MAXEVENT) 175 list = COMMON; 176 177 /* 178 * one exception 179 */ 180 else if (lists[COMMON].count == MAXEVENT-1) { 181 for (i=COMMON;i<=FAILURE && (list == -1);i++) { 182 if (except_list[i] == 1) { 183 list = COMMON; 184 except[0].type = i; 185 except[0].exception = lists[i].off; 186 } 187 } 188 } 189 /* 190 * two exceptions 191 */ 192 else if (lists[COMMON].count == MAXEVENT-2) { 193 if (except_list[COMMON] == 1) { 194 list = COMMON; 195 except[0].type = COMMON; 196 except[0].exception = lists[COMMON].off; 197 for (i=SUCCESS;i<=FAILURE;i++) { 198 if (except_list[i] == 1) { 199 except[1].type = i; 200 except[1].exception = lists[i].off; 201 } 202 } 203 204 } else if (except_list[COMMON] == 0) { 205 for (i=SUCCESS,j=0;i<=FAILURE;i++) { 206 if (except_list[i] == 1) { 207 list = COMMON; 208 except[j].type = i; 209 except[j++].exception = lists[i].off; 210 } 211 } 212 } 213 } 214 } else { 215 /* 216 * check for +all or -all 217 */ 218 for (i=SUCCESS,j=0;i<=FAILURE;i++) { 219 if (lists[i].count >= MAXEVENT-1) { 220 list = i; 221 except[j].type = i; 222 if (lists[i].count != MAXEVENT) { 223 if (lists[i].off != -1) 224 except[j++].exception = 225 lists[i].off; 226 else 227 except[j++].exception = 228 lists[COMMON].off; 229 } 230 } 231 } 232 } 233 /* 234 * output all and exceptions 235 */ 236 if (list != -1) { 237 if(list==SUCCESS) { 238 if ((stringcopy(auditstring, "+", 0)) == -1) 239 retstat = -1; 240 } 241 if(list==FAILURE) { 242 if ((stringcopy(auditstring, "-", 0)) == -1) 243 retstat = -1; 244 } 245 246 if (retstat == 0) { 247 if (length) { 248 if 249 ((stringcopy(auditstring,event_class[11].event_lname,1)) == -1) 250 retstat = -1; 251 } else 252 if ((stringcopy(auditstring, event_class[11].event_sname,1)) == -1) 253 retstat = -1; 254 } 255 256 if (retstat == 0) { 257 /* 258 * output exceptions 259 */ 260 for (i=0;i<2 && except[i].exception != -1; i++) { 261 if ((stringcopy(auditstring, "^", 0)) == -1) 262 retstat = -1; 263 if(except[i].type==SUCCESS) { 264 if ((stringcopy(auditstring, "+", 0)) == -1) 265 retstat = -1; 266 } 267 if (except[i].type==FAILURE) { 268 if ((stringcopy(auditstring, "-", 0)) == -1) 269 retstat = -1; 270 } 271 if (length == 1 && retstat == 0) { 272 if ((stringcopy(auditstring, 273 event_class[except[i].exception].event_lname, 1))==-1) 274 retstat = -1; 275 } else if (retstat == 0) { 276 if ((stringcopy(auditstring, 277 event_class[except[i].exception].event_sname, 1))==-1) 278 retstat = -1; 279 } 280 } 281 } 282 } /* end of " all " processing */ 283 284 /* 285 * process common events if no "all" was output 286 */ 287 if (list == -1 && (lists[COMMON].count > 0) && retstat == 0) { 288 /* 289 * output common events first 290 */ 291 for (j=0;j<lists[COMMON].count;j++) { 292 if (length == 1) { 293 if ((stringcopy(auditstring, 294 event_class[lists[COMMON].on[j]].event_lname, 1)) == -1) 295 retstat = -1; 296 } else if ((stringcopy(auditstring, 297 event_class[lists[COMMON].on[j]].event_sname, 1)) == -1) 298 retstat = -1; 299 } 300 /* 301 * remove common events from individual lists 302 */ 303 if (retstat == 0) { 304 for (i=SUCCESS;i<=FAILURE;i++) { 305 for(j=0;j<lists[COMMON].count;j++) { 306 for(k=0;k < lists[i].count;k++) { 307 if (lists[COMMON].on[j] == 308 lists[i].on[k]) 309 lists[i].on[k] = -1; 310 } 311 } 312 } 313 } 314 } 315 316 /* 317 * start processing individual event flags in success 318 * and failure lists 319 */ 320 if (list != COMMON && retstat == 0) { 321 for (i=SUCCESS;i<=FAILURE;i++) { 322 if(list != i) { 323 if (i==SUCCESS) strcpy(prefix, "+"); 324 if (i==FAILURE) strcpy(prefix, "-"); 325 for (j=0;j<MAXEVENT && j<lists[i].count;j++) { 326 if (lists[i].on[j] != -1) { 327 if ((stringcopy(auditstring, prefix, 0)) == -1) 328 retstat = -1; 329 if (length == 1 && 330 retstat == 0) { 331 if ((stringcopy(auditstring, 332 event_class[lists[i].on[j]].event_lname, 1))==-1) 333 retstat = -1; 334 } else if (retstat == 0) { 335 if ((stringcopy(auditstring, 336 event_class[lists[i].on[j]].event_sname, 1))==-1) 337 retstat = -1; 338 } 339 } 340 } 341 } 342 } 343 } 344 if ((stringcopy(auditstring, "\0", 2)) == -1) 345 retstat = -1; 346 347 return (retstat); 348 } 349 350 static stringcopy(auditstring, event, flag) 351 char *auditstring; 352 char *event; 353 int flag; /* if set, output comma after event */ 354 { 355 int retstat = 0; 356 357 /* 358 * check size 359 */ 360 if (pos >= MAXSTRLEN) { 361 fprintf(stderr,"getauditflagschar: Inputted buffer too small.\n"); 362 retstat = -1; 363 } else if (flag != 2) { 364 strcpy(auditstring+pos, event); 365 pos += strlen(event); 366 if(flag) { 367 strcpy(auditstring+pos, COMMASTR); 368 pos += strlen(COMMASTR); 369 } 370 } else { 371 /* 372 * add null terminator only 373 */ 374 if (pos) 375 strcpy(auditstring+(pos-1), event); 376 377 } 378 return (retstat); 379 } 380 381 /* 382 * getauditflagsbin() - converts character string to success and 383 * failure bit masks 384 * 385 * input: auditstring - audit string 386 * cnt - number of elements in the masks array 387 * 388 * output: masks->as_success - audit on success 389 * masks->as_failure - audit on failure 390 * 391 * returns: 0 - ok 392 * -1 - error - string contains characters which do 393 * not match event flag names 394 */ 395 396 getauditflagsbin(auditstring, masks) 397 char *auditstring; 398 audit_state_t *masks; 399 { 400 int i, gotone, done = 0, invert = 0, tryagain; 401 int retstat = 0, succ_event, fail_event; 402 char *ptr, tmp_buff[MAXFLDLEN]; 403 404 /* 405 * process character string 406 */ 407 do { 408 gotone = 0; 409 /* 410 * read through string storing chars. until a comma 411 */ 412 for (ptr=tmp_buff; !gotone;) { 413 if(*auditstring!=COMMA && *auditstring!='\0' && 414 *auditstring!='\n' && *auditstring!=' ') 415 *ptr++ = *auditstring++; 416 else if (*auditstring == ' ') 417 *auditstring++; 418 else { 419 if (*auditstring == '\0' || 420 *auditstring == '\n') { 421 done = 1; 422 if (ptr == tmp_buff) 423 done = 2; 424 } 425 gotone = 1; 426 } 427 } 428 /* 429 * process audit state 430 */ 431 if(gotone && done != 2) { 432 if(!done) auditstring++; 433 *ptr++ = '\0'; 434 ptr = tmp_buff; 435 gotone = 0; 436 succ_event = ON; 437 fail_event = ON; 438 tryagain = 1; 439 invert = 0; 440 441 /* 442 * get flags 443 */ 444 do { 445 switch (*ptr++) { 446 case '^': 447 invert = 1; 448 succ_event = OFF; 449 fail_event = OFF; 450 break; 451 case '+': 452 if (invert) 453 fail_event = OK; 454 else { 455 succ_event = ON; 456 fail_event = OK; 457 } 458 break; 459 case '-': 460 if (invert) 461 succ_event = OK; 462 else { 463 fail_event = ON; 464 succ_event = OK; 465 } 466 break; 467 default: 468 tryagain = 0; 469 ptr--; 470 break; 471 } 472 } while(tryagain); 473 474 /* add audit state to mask */ 475 for (i=0;i<MAXEVENT+1 && !gotone;i++) { 476 if ((!(strcmp(ptr, event_class[i].event_sname))) || 477 (!(strcmp(ptr, event_class[i].event_lname)))) { 478 if (succ_event == ON) 479 masks->as_success |= event_class[i].event_mask; 480 else if (succ_event == OFF) 481 masks->as_success &= ~(event_class[i].event_mask); 482 if (fail_event == ON) 483 masks->as_failure |= event_class[i].event_mask; 484 else if (fail_event == OFF) 485 masks->as_failure &= ~(event_class[i].event_mask); 486 gotone = 1; 487 } 488 } 489 if(!gotone) { 490 retstat = -1; 491 done = 1; 492 } 493 } 494 } while (!done); 495 496 return (retstat); 497 } 498