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 * Copyright (c) 2019 Peter Tribble. 23 */ 24 /* 25 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. 26 */ 27 28 #include <dirent.h> 29 #include <errno.h> 30 #include <locale.h> 31 #include <libintl.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 #include <stdio.h> 35 #include <unistd.h> 36 37 #include <sys/types.h> 38 #include <sys/file.h> 39 40 #include <bsm/audit.h> 41 #include <bsm/audit_record.h> 42 #include <bsm/libbsm.h> 43 44 #include "praudit.h" 45 #include "toktable.h" 46 47 static int process_options(int *argc, char *argv[], char *names[]); 48 49 static int input_mode; /* audit file source */ 50 static int format = PRF_DEFAULTM; /* output mode */ 51 52 static char SEPARATOR[SEP_SIZE] = ","; /* field separator */ 53 54 static FILE *gf = NULL; 55 static FILE *pf = NULL; 56 57 /* 58 * ---------------------------------------------------------------------- 59 * praudit - display contents of audit trail file 60 * 61 * main() - main control 62 * input: - command line input: 63 * praudit -r|s -l -x -ddelim. -p pwfile -g grpfile -c filename(s) 64 * ---------------------------------------------------------------------- 65 */ 66 67 int 68 main(int argc, char **argv) 69 { 70 int i = 0, retstat; 71 char *names[MAXFILENAMES]; 72 73 /* Internationalization */ 74 (void) setlocale(LC_ALL, ""); 75 (void) textdomain(TEXT_DOMAIN); 76 /* 77 * get audit file names 78 */ 79 if ((retstat = process_options(&argc, argv, names)) == 0) { 80 if (pf != NULL) { 81 errno = 0; 82 loadnames(pf); 83 (void) fclose(pf); 84 if (errno != 0) { 85 (void) fprintf(stderr, 86 gettext("praudit: Problem reading passwd " 87 "file.\n")); 88 exit(1); 89 } 90 } 91 if (gf != NULL) { 92 errno = 0; 93 loadgroups(gf); 94 (void) fclose(gf); 95 if (errno != 0) { 96 (void) fprintf(stderr, 97 gettext("praudit: Problem reading group " 98 "file.\n")); 99 exit(1); 100 } 101 } 102 if (format & PRF_XMLM) 103 print_audit_xml_prolog(); 104 do { 105 retstat = 0; 106 /* 107 * process each audit file 108 */ 109 if (input_mode == FILEMODE) { 110 if (freopen(names[i], "r", stdin) == NULL) { 111 (void) fprintf(stderr, 112 gettext("praudit: Cannot associate " 113 "stdin with %s: %s\n"), 114 names[i], strerror(errno)); 115 exit(1); 116 } 117 } 118 119 /* 120 * Call the library routine to format the 121 * audit data from stdin and print to stdout 122 */ 123 retstat = print_audit(format, SEPARATOR); 124 125 } while ((++i < argc) && retstat >= 0); 126 } 127 if ((retstat == 0) && (format & PRF_XMLM)) 128 print_audit_xml_ending(); 129 130 if (retstat == -2) { 131 (void) printf(gettext("\nusage: praudit [-r/-s] [-l] [-x] " 132 "[-ddel] [-p file] [-g file] [-c] filename...\n")); 133 exit(1); 134 } else if (retstat < 0) { 135 exit(1); 136 } 137 return (0); 138 } 139 140 141 /* 142 * ------------------------------------------------------------------- 143 * process_options() - get command line flags and file names 144 * input: - praudit [-r]/[-s] [-l] [-x] [-ddel] [-c] 145 * -p pwfile -g grpfile -c {audit file names} 146 * output: - {audit file names} 147 * globals set: format: RAWM / SHORTM / XML / ONELINE or DEFAULTM 148 * SEPARATOR: default, ",", set here if 149 * user specified 150 * NOTE: no changes required here for new audit record format 151 * ------------------------------------------------------------------- 152 */ 153 int 154 process_options(int *argc, char **argv, char **names) 155 { 156 int c, returnstat = 0; 157 158 /* 159 * check for flags 160 */ 161 162 while ((c = getopt(*argc, argv, "crslxd:g:p:")) != -1) { 163 switch (c) { 164 case 'c': 165 format |= PRF_NOCACHE; /* turn off cache */ 166 break; 167 case 'r': 168 if (format & PRF_SHORTM) 169 returnstat = -2; 170 else 171 format |= PRF_RAWM; 172 break; 173 case 's': 174 if (format & PRF_RAWM) 175 returnstat = -2; 176 else 177 format |= PRF_SHORTM; 178 break; 179 case 'l': 180 format |= PRF_ONELINE; 181 break; 182 case 'x': 183 format |= PRF_XMLM; 184 break; 185 case 'd': 186 if (strlen(optarg) < sizeof (SEPARATOR)) 187 (void) strlcpy(SEPARATOR, optarg, 188 sizeof (SEPARATOR)); 189 else { 190 (void) fprintf(stderr, 191 gettext("praudit: Delimiter too " 192 "long. Using default.\n")); 193 } 194 break; 195 case 'g': 196 if ((gf = fopen(optarg, "r")) == NULL) { 197 (void) fprintf(stderr, gettext("praudit: Cannot" 198 " open specified group file.\n")); 199 return (-1); 200 } 201 break; 202 case 'p': 203 if ((pf = fopen(optarg, "r")) == NULL) { 204 (void) fprintf(stderr, gettext("praudit: Cannot" 205 " open specified passwd file.\n")); 206 return (-1); 207 } 208 break; 209 default: 210 returnstat = -2; 211 break; 212 } 213 } 214 215 argv = &argv[optind - 1]; 216 *argc -= optind; 217 218 if (*argc > MAXFILENAMES) { 219 (void) fprintf(stderr, gettext("praudit: Too many file " 220 "names.\n")); 221 return (-1); 222 } 223 if (*argc > 0) { 224 int count = *argc; 225 226 input_mode = FILEMODE; 227 /* 228 * copy file names from command line 229 */ 230 do { 231 *names++ = *++argv; 232 } while (--count > 0); 233 } else 234 input_mode = PIPEMODE; 235 236 return (returnstat); 237 } 238