1185573Srwatson/*-
2243750Srwatson * Copyright (c) 2004-2009 Apple Inc.
3168777Srwatson * Copyright (c) 2006 Martin Voros
4155131Srwatson * All rights reserved.
5155131Srwatson *
6155131Srwatson * Redistribution and use in source and binary forms, with or without
7155131Srwatson * modification, are permitted provided that the following conditions
8155131Srwatson * are met:
9155131Srwatson * 1.  Redistributions of source code must retain the above copyright
10155131Srwatson *     notice, this list of conditions and the following disclaimer.
11155131Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
12155131Srwatson *     notice, this list of conditions and the following disclaimer in the
13155131Srwatson *     documentation and/or other materials provided with the distribution.
14243750Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
15155131Srwatson *     its contributors may be used to endorse or promote products derived
16155131Srwatson *     from this software without specific prior written permission.
17155131Srwatson *
18155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
19155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
22155131Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26155131Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27155131Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28155131Srwatson * POSSIBILITY OF SUCH DAMAGE.
29155131Srwatson *
30243750Srwatson * $P4: //depot/projects/trustedbsd/openbsm/bin/praudit/praudit.c#16 $
31155131Srwatson */
32155131Srwatson
33155131Srwatson/*
34155131Srwatson * Tool used to parse audit records conforming to the BSM structure.
35155131Srwatson */
36155131Srwatson
37155131Srwatson/*
38243750Srwatson * praudit [-lnpx] [-r | -s] [-d del] [file ...]
39155131Srwatson */
40155131Srwatson
41155131Srwatson#include <bsm/libbsm.h>
42155131Srwatson
43155131Srwatson#include <stdio.h>
44155131Srwatson#include <stdlib.h>
45155131Srwatson#include <unistd.h>
46155131Srwatson
47155131Srwatsonextern char	*optarg;
48155131Srwatsonextern int	 optind, optopt, opterr,optreset;
49155131Srwatson
50155131Srwatsonstatic char	*del = ",";	/* Default delimiter. */
51155131Srwatsonstatic int	 oneline = 0;
52155131Srwatsonstatic int	 partial = 0;
53243750Srwatsonstatic int	 oflags = AU_OFLAG_NONE;
54155131Srwatson
55155131Srwatsonstatic void
56168777Srwatsonusage(void)
57155131Srwatson{
58155131Srwatson
59243750Srwatson	fprintf(stderr, "usage: praudit [-lnpx] [-r | -s] [-d del] "
60168777Srwatson	    "[file ...]\n");
61155131Srwatson	exit(1);
62155131Srwatson}
63155131Srwatson
64155131Srwatson/*
65155131Srwatson * Token printing for each token type .
66155131Srwatson */
67155131Srwatsonstatic int
68155131Srwatsonprint_tokens(FILE *fp)
69155131Srwatson{
70155131Srwatson	u_char *buf;
71155131Srwatson	tokenstr_t tok;
72155131Srwatson	int reclen;
73155131Srwatson	int bytesread;
74155131Srwatson
75155131Srwatson	/* Allow tail -f | praudit to work. */
76155131Srwatson	if (partial) {
77155131Srwatson		u_char type = 0;
78155131Srwatson		/* Record must begin with a header token. */
79155131Srwatson		do {
80155131Srwatson			type = fgetc(fp);
81185573Srwatson		} while(type != AUT_HEADER32);
82155131Srwatson		ungetc(type, fp);
83155131Srwatson	}
84155131Srwatson
85155131Srwatson	while ((reclen = au_read_rec(fp, &buf)) != -1) {
86155131Srwatson		bytesread = 0;
87155131Srwatson		while (bytesread < reclen) {
88155131Srwatson			/* Is this an incomplete record? */
89155131Srwatson			if (-1 == au_fetch_tok(&tok, buf + bytesread,
90155131Srwatson			    reclen - bytesread))
91155131Srwatson				break;
92243750Srwatson			au_print_flags_tok(stdout, &tok, del, oflags);
93155131Srwatson			bytesread += tok.len;
94168777Srwatson			if (oneline) {
95243750Srwatson				if (!(oflags & AU_OFLAG_XML))
96168777Srwatson					printf("%s", del);
97168777Srwatson			} else
98155131Srwatson				printf("\n");
99155131Srwatson		}
100155131Srwatson		free(buf);
101155131Srwatson		if (oneline)
102155131Srwatson			printf("\n");
103173143Srwatson		fflush(stdout);
104155131Srwatson	}
105155131Srwatson	return (0);
106155131Srwatson}
107155131Srwatson
108155131Srwatsonint
109155131Srwatsonmain(int argc, char **argv)
110155131Srwatson{
111155364Srwatson	int ch;
112155131Srwatson	int i;
113155131Srwatson	FILE *fp;
114155131Srwatson
115243750Srwatson	while ((ch = getopt(argc, argv, "d:lnprsx")) != -1) {
116155131Srwatson		switch(ch) {
117168777Srwatson		case 'd':
118168777Srwatson			del = optarg;
119168777Srwatson			break;
120168777Srwatson
121155131Srwatson		case 'l':
122155131Srwatson			oneline = 1;
123155131Srwatson			break;
124155131Srwatson
125243750Srwatson		case 'n':
126243750Srwatson			oflags |= AU_OFLAG_NORESOLVE;
127243750Srwatson			break;
128243750Srwatson
129168777Srwatson		case 'p':
130168777Srwatson			partial = 1;
131168777Srwatson			break;
132168777Srwatson
133155131Srwatson		case 'r':
134243750Srwatson			if (oflags & AU_OFLAG_SHORT)
135155131Srwatson				usage();	/* Exclusive from shortfrm. */
136243750Srwatson			oflags |= AU_OFLAG_RAW;
137155131Srwatson			break;
138155131Srwatson
139155131Srwatson		case 's':
140243750Srwatson			if (oflags & AU_OFLAG_RAW)
141155131Srwatson				usage();	/* Exclusive from raw. */
142243750Srwatson			oflags |= AU_OFLAG_SHORT;
143155131Srwatson			break;
144155131Srwatson
145168777Srwatson		case 'x':
146243750Srwatson			oflags |= AU_OFLAG_XML;
147155131Srwatson			break;
148155131Srwatson
149155131Srwatson		case '?':
150155131Srwatson		default:
151155131Srwatson			usage();
152155131Srwatson		}
153155131Srwatson	}
154155131Srwatson
155243750Srwatson	if (oflags & AU_OFLAG_XML)
156168777Srwatson		au_print_xml_header(stdout);
157168777Srwatson
158155131Srwatson	/* For each of the files passed as arguments dump the contents. */
159155131Srwatson	if (optind == argc) {
160155131Srwatson		print_tokens(stdin);
161155131Srwatson		return (1);
162155131Srwatson	}
163155131Srwatson	for (i = optind; i < argc; i++) {
164155131Srwatson		fp = fopen(argv[i], "r");
165155131Srwatson		if ((fp == NULL) || (print_tokens(fp) == -1))
166155131Srwatson			perror(argv[i]);
167155131Srwatson		if (fp != NULL)
168155131Srwatson			fclose(fp);
169155131Srwatson	}
170168777Srwatson
171243750Srwatson	if (oflags & AU_OFLAG_XML)
172168777Srwatson		au_print_xml_footer(stdout);
173168777Srwatson
174155131Srwatson	return (1);
175155131Srwatson}
176