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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* getacinfo.c - get audit control info */ 28 29 #include <stdio.h> 30 #include <string.h> 31 #include <sys/types.h> 32 #include <bsm/audit.h> 33 #include <bsm/libbsm.h> 34 #include <synch.h> 35 36 #define DIROP 0 37 #define OTHEROP 1 38 39 #define LEN 360 /* maximum audit control entry length */ 40 41 #define SUCCESS 0 42 #define EOF_WARN 1 43 #define REW_WARN 2 44 #define EOF_ERR -1 45 #define ERROR -2 46 #define FORMAT_ERR -3 47 48 static char *AUDIT_CTRL = AUDITCONTROLFILE; 49 static char *MINLABEL = "minfree:"; 50 static char *DIRLABEL = "dir:"; 51 static char *DEFFLGLABEL = "flags:"; 52 static char *NAFLGLABEL = "naflags:"; 53 static int LASTOP; 54 static int DIRINIT; 55 static FILE *acf; /* pointer into audit control file */ 56 static mutex_t mutex_acf = DEFAULTMUTEX; 57 58 /* 59 * getacinfo.c - get audit control info 60 * 61 * getacdir() - get audit control directories, one at a time 62 * getacflg() - get audit control default audit flags 63 * getacmin() - get audit control directory min. fill value 64 * getacna() - get audit control non-attrib audit flags 65 * setac() - rewind the audit control file 66 * endac() - close the audit control file 67 * testac() - check if audit control file open 68 */ 69 70 71 /* 72 * getacdir() - get audit control directories, one at a time 73 * 74 * input: len - size of dir buffer 75 * 76 * output: dir - directory string 77 * 78 * returns: 0 - entry read ok 79 * -1 - end of file 80 * -2 - error - can't open audit control file for read 81 * -3 - error - directory entry format error 82 * 2 - directory search started from beginning again 83 * 84 * notes: It is the responsibility of the calling function to 85 * check the status of the directory entry. 86 */ 87 88 int 89 getacdir(char *dir, int len) 90 { 91 int retstat = SUCCESS, gotone = 0, dirlen, dirst; 92 char entry[LEN]; 93 /* void setac(); */ 94 95 /* open file if it is not already opened */ 96 (void) mutex_lock(&mutex_acf); 97 if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) 98 retstat = ERROR; 99 else if (LASTOP != DIROP && DIRINIT == 1) { 100 retstat = REW_WARN; 101 (void) mutex_unlock(&mutex_acf); 102 setac(); 103 } else { 104 DIRINIT = 1; 105 LASTOP = DIROP; 106 } 107 if (retstat >= SUCCESS) do { 108 if (fgets(entry, LEN, acf) != NULL) { 109 switch (*entry) { 110 111 case '#': 112 113 break; 114 115 case 'd': 116 117 /* return directory entry */ 118 if (strncmp(entry, DIRLABEL, strlen(DIRLABEL)) == 0) { 119 if ((strlen(entry) + 1) > (size_t)len) { 120 retstat = FORMAT_ERR; 121 } else { 122 /* 123 * allow zero or one blank 124 * between colon and directory 125 */ 126 if (entry[strlen(DIRLABEL)] == ' ') { 127 dirst = strlen(DIRLABEL) + 1; 128 dirlen = strlen(entry) - 129 (strlen(DIRLABEL) + 2); 130 } else { 131 dirst = strlen(DIRLABEL); 132 dirlen = strlen(entry) - 133 (strlen(DIRLABEL) + 1); 134 } 135 (void) strcpy(dir, entry + dirst); 136 (void) strcpy(dir + dirlen, "\0"); 137 gotone = 1; 138 } 139 } else 140 retstat = FORMAT_ERR; 141 142 break; 143 144 case 'm': 145 146 break; 147 148 case 'f': 149 150 break; 151 152 default: 153 154 break; 155 156 } /* end of switch */ 157 } else if ((feof(acf)) == 0) { 158 retstat = ERROR; 159 } else { 160 retstat = EOF_ERR; 161 } 162 } while (gotone == 0 && retstat >= SUCCESS); 163 164 (void) mutex_unlock(&mutex_acf); 165 return (retstat); 166 } 167 168 169 /* 170 * getacmin() - get audit control directory min. fill value 171 * 172 * output: min_val - percentage of directory fill allowed 173 * 174 * returns: 0 - entry read ok 175 * 1 - end of file 176 * -2 - error; errno contains error number 177 * -3 - error - directory entry format error 178 */ 179 180 int 181 getacmin(int *min_val) 182 { 183 int retstat = SUCCESS, gotone = 0; 184 char entry[LEN]; 185 186 /* open file if it is not already opened */ 187 (void) mutex_lock(&mutex_acf); 188 if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) 189 retstat = ERROR; 190 else 191 rewind(acf); 192 193 if (retstat == SUCCESS) { 194 do { 195 if (fgets(entry, LEN, acf) != NULL) { 196 switch (*entry) { 197 case '#': 198 break; 199 case 'd': 200 break; 201 case 'm': 202 if (strncmp(entry, MINLABEL, 203 strlen(MINLABEL)) == 0) { 204 (void) sscanf(entry + 205 strlen(MINLABEL), 206 "%d", min_val); 207 gotone = 1; 208 } else 209 retstat = FORMAT_ERR; 210 break; 211 case 'f': 212 break; 213 default: 214 break; 215 } 216 } else if ((feof(acf)) == 0) 217 retstat = ERROR; 218 else 219 retstat = EOF_WARN; 220 221 } while (gotone == 0 && retstat == SUCCESS); 222 } 223 224 if (LASTOP == DIROP) 225 LASTOP = OTHEROP; 226 else { 227 if (acf != NULL) { 228 (void) fclose(acf); 229 acf = NULL; 230 } 231 LASTOP = DIROP; 232 DIRINIT = 0; 233 } 234 235 (void) mutex_unlock(&mutex_acf); 236 return (retstat); 237 } 238 239 240 /* 241 * getacflg() - get audit control flags 242 * 243 * output: auditstring - character representation of system audit flags 244 * 245 * returns: 0 - entry read ok 246 * 1 - end of file 247 * -2 - error - errno contains error number 248 * -3 - error - directory entry format error 249 */ 250 251 int 252 getacflg(char *auditstring, int len) 253 { 254 int retstat = SUCCESS, gotone = 0, minst, minlen; 255 char entry[LEN]; 256 257 /* open file if it is not already opened */ 258 (void) mutex_lock(&mutex_acf); 259 if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) 260 retstat = ERROR; 261 else 262 rewind(acf); 263 264 if (retstat == SUCCESS) do { 265 if (fgets(entry, LEN, acf) != NULL) { 266 switch (*entry) { 267 case '#': 268 break; 269 case 'd': 270 break; 271 case 'm': 272 break; 273 case 'f': 274 275 if ((strncmp(entry, DEFFLGLABEL, 276 strlen(DEFFLGLABEL))) == 0) { 277 if (entry[strlen(DEFFLGLABEL)] == ' ') { 278 minst = strlen(DEFFLGLABEL) + 1; 279 minlen = strlen(entry) - 280 (strlen(DEFFLGLABEL) + 2); 281 } else { 282 minst = strlen(DEFFLGLABEL); 283 minlen = strlen(entry) - 284 (strlen(DEFFLGLABEL) + 1); 285 } 286 if (minlen > len) 287 retstat = FORMAT_ERR; 288 else { 289 (void) strcpy(auditstring, 290 entry + minst); 291 (void) strcpy(auditstring + minlen, 292 "\0"); 293 gotone = 1; 294 } 295 } else 296 retstat = FORMAT_ERR; 297 298 break; /* end of case f */ 299 300 default: 301 break; 302 } 303 } else if ((feof(acf)) == 0) { 304 retstat = ERROR; 305 } else { 306 retstat = EOF_WARN; 307 } 308 } while (gotone == 0 && retstat == SUCCESS); 309 310 if (LASTOP == DIROP) 311 LASTOP = OTHEROP; 312 else { 313 if (acf != NULL) { 314 (void) fclose(acf); 315 acf = NULL; 316 } 317 LASTOP = DIROP; 318 DIRINIT = 0; 319 } 320 321 (void) mutex_unlock(&mutex_acf); 322 return (retstat); 323 } 324 325 326 /* 327 * getacna() - get audit flags for non-attributable (server) events 328 * 329 * output: auditstring - character representation of system audit flags 330 * 331 * returns: 0 - entry read ok 332 * 1 - end of file 333 * -2 - error - errno contains error number 334 * -3 - error - directory entry format error 335 */ 336 337 int 338 getacna(char *auditstring, int len) 339 { 340 int retstat = SUCCESS, gotone = 0, minst, minlen; 341 char entry[LEN]; 342 343 /* open file if it is not already opened */ 344 (void) mutex_lock(&mutex_acf); 345 if (acf == NULL && (acf = fopen(AUDIT_CTRL, "rF")) == NULL) { 346 retstat = ERROR; 347 } else { 348 rewind(acf); 349 } 350 351 if (retstat == SUCCESS) do { 352 if (fgets(entry, LEN, acf) != NULL) 353 switch (*entry) { 354 case '#': 355 break; 356 case 'd': 357 break; 358 case 'm': 359 break; 360 case 'f': 361 break; 362 case 'n': 363 364 if ((strncmp(entry, NAFLGLABEL, 365 strlen(NAFLGLABEL))) == 0) { 366 if (entry[strlen(NAFLGLABEL)] == ' ') { 367 minst = strlen(NAFLGLABEL) + 1; 368 minlen = strlen(entry) - 369 (strlen(NAFLGLABEL) + 2); 370 } else { 371 minst = strlen(NAFLGLABEL); 372 minlen = strlen(entry) - 373 (strlen(NAFLGLABEL) + 1); 374 } 375 if (minlen > len) 376 retstat = FORMAT_ERR; 377 else { 378 (void) strcpy(auditstring, 379 entry + minst); 380 (void) strcpy(auditstring + minlen, 381 "\0"); 382 gotone = 1; 383 } 384 } else 385 retstat = FORMAT_ERR; 386 387 break; /* end of case n */ 388 389 default: 390 break; 391 392 /* end of if-switch */ 393 } else if ((feof(acf)) == 0) { 394 retstat = ERROR; 395 } else { 396 retstat = EOF_WARN; 397 } 398 399 /* end of if-do */ 400 } while (gotone == 0 && retstat == SUCCESS); 401 402 if (LASTOP == DIROP) 403 LASTOP = OTHEROP; 404 else { 405 if (acf != NULL) { 406 (void) fclose(acf); 407 acf = NULL; 408 } 409 LASTOP = DIROP; 410 DIRINIT = 0; 411 } 412 413 (void) mutex_unlock(&mutex_acf); 414 return (retstat); 415 } 416 417 418 /* rewind the audit control file */ 419 void 420 setac() 421 { 422 (void) mutex_lock(&mutex_acf); 423 if (acf == NULL) 424 acf = fopen(AUDIT_CTRL, "rF"); 425 else 426 rewind(acf); 427 LASTOP = DIROP; 428 DIRINIT = 0; 429 (void) mutex_unlock(&mutex_acf); 430 } 431 432 433 /* close the audit control file */ 434 void 435 endac() 436 { 437 (void) mutex_lock(&mutex_acf); 438 if (acf != NULL) { 439 (void) fclose(acf); 440 acf = NULL; 441 } 442 LASTOP = DIROP; 443 DIRINIT = 0; 444 (void) mutex_unlock(&mutex_acf); 445 } 446