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