1 /*- 2 * Copyright (c) 2004-2009 Apple Inc. 3 * Copyright (c) 2006 Martin Voros 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * Tool used to parse audit records conforming to the BSM structure. 33 */ 34 35 /* 36 * praudit [-lnpx] [-r | -s] [-d del] [file ...] 37 */ 38 39 #include <bsm/libbsm.h> 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <unistd.h> 44 45 extern char *optarg; 46 extern int optind, optopt, opterr,optreset; 47 48 static char *del = ","; /* Default delimiter. */ 49 static int oneline = 0; 50 static int partial = 0; 51 static int oflags = AU_OFLAG_NONE; 52 53 static void 54 usage(void) 55 { 56 57 fprintf(stderr, "usage: praudit [-lnpx] [-r | -s] [-d del] " 58 "[file ...]\n"); 59 exit(1); 60 } 61 62 /* 63 * Token printing for each token type . 64 */ 65 static int 66 print_tokens(FILE *fp) 67 { 68 u_char *buf; 69 tokenstr_t tok; 70 int reclen; 71 int bytesread; 72 73 /* Allow tail -f | praudit to work. */ 74 if (partial) { 75 u_char type = 0; 76 /* Record must begin with a header token. */ 77 do { 78 type = fgetc(fp); 79 } while(type != AUT_HEADER32); 80 ungetc(type, fp); 81 } 82 83 while ((reclen = au_read_rec(fp, &buf)) != -1) { 84 bytesread = 0; 85 while (bytesread < reclen) { 86 /* Is this an incomplete record? */ 87 if (-1 == au_fetch_tok(&tok, buf + bytesread, 88 reclen - bytesread)) 89 break; 90 au_print_flags_tok(stdout, &tok, del, oflags); 91 bytesread += tok.len; 92 if (oneline) { 93 if (!(oflags & AU_OFLAG_XML)) 94 printf("%s", del); 95 } else 96 printf("\n"); 97 } 98 free(buf); 99 if (oneline) 100 printf("\n"); 101 fflush(stdout); 102 } 103 return (0); 104 } 105 106 int 107 main(int argc, char **argv) 108 { 109 int ch; 110 int i; 111 FILE *fp; 112 113 while ((ch = getopt(argc, argv, "d:lnprsx")) != -1) { 114 switch(ch) { 115 case 'd': 116 del = optarg; 117 break; 118 119 case 'l': 120 oneline = 1; 121 break; 122 123 case 'n': 124 oflags |= AU_OFLAG_NORESOLVE; 125 break; 126 127 case 'p': 128 partial = 1; 129 break; 130 131 case 'r': 132 if (oflags & AU_OFLAG_SHORT) 133 usage(); /* Exclusive from shortfrm. */ 134 oflags |= AU_OFLAG_RAW; 135 break; 136 137 case 's': 138 if (oflags & AU_OFLAG_RAW) 139 usage(); /* Exclusive from raw. */ 140 oflags |= AU_OFLAG_SHORT; 141 break; 142 143 case 'x': 144 oflags |= AU_OFLAG_XML; 145 break; 146 147 case '?': 148 default: 149 usage(); 150 } 151 } 152 153 if (oflags & AU_OFLAG_XML) 154 au_print_xml_header(stdout); 155 156 /* For each of the files passed as arguments dump the contents. */ 157 if (optind == argc) { 158 print_tokens(stdin); 159 return (1); 160 } 161 for (i = optind; i < argc; i++) { 162 fp = fopen(argv[i], "r"); 163 if ((fp == NULL) || (print_tokens(fp) == -1)) 164 perror(argv[i]); 165 if (fp != NULL) 166 fclose(fp); 167 } 168 169 if (oflags & AU_OFLAG_XML) 170 au_print_xml_footer(stdout); 171 172 return (1); 173 } 174