xref: /freebsd-src/contrib/openbsm/bin/auditreduce/auditreduce.c (revision 71f8f48356585b1777d5d6a940c86f810bd20c6a)
152267f74SRobert Watson /*-
252267f74SRobert Watson  * Copyright (c) 2004-2008 Apple Inc.
35e386598SRobert Watson  * Copyright (c) 2016 Robert N. M. Watson
4ca0716f5SRobert Watson  * All rights reserved.
5ca0716f5SRobert Watson  *
65e386598SRobert Watson  * Portions of this software were developed by BAE Systems, the University of
75e386598SRobert Watson  * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
85e386598SRobert Watson  * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
95e386598SRobert Watson  * Computing (TC) research program.
105e386598SRobert Watson  *
11ca0716f5SRobert Watson  * Redistribution and use in source and binary forms, with or without
12ca0716f5SRobert Watson  * modification, are permitted provided that the following conditions
13ca0716f5SRobert Watson  * are met:
14ca0716f5SRobert Watson  * 1.  Redistributions of source code must retain the above copyright
15ca0716f5SRobert Watson  *     notice, this list of conditions and the following disclaimer.
16ca0716f5SRobert Watson  * 2.  Redistributions in binary form must reproduce the above copyright
17ca0716f5SRobert Watson  *     notice, this list of conditions and the following disclaimer in the
18ca0716f5SRobert Watson  *     documentation and/or other materials provided with the distribution.
1952267f74SRobert Watson  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
20ca0716f5SRobert Watson  *     its contributors may be used to endorse or promote products derived
21ca0716f5SRobert Watson  *     from this software without specific prior written permission.
22ca0716f5SRobert Watson  *
23ca0716f5SRobert Watson  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
24ca0716f5SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ca0716f5SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ca0716f5SRobert Watson  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
27ca0716f5SRobert Watson  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ca0716f5SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ca0716f5SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ca0716f5SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31ca0716f5SRobert Watson  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32ca0716f5SRobert Watson  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33ca0716f5SRobert Watson  * POSSIBILITY OF SUCH DAMAGE.
34ca0716f5SRobert Watson  */
35ca0716f5SRobert Watson 
36ca0716f5SRobert Watson /*
37ca0716f5SRobert Watson  * Tool used to merge and select audit records from audit trail files
38ca0716f5SRobert Watson  */
39ca0716f5SRobert Watson 
40ca0716f5SRobert Watson /*
41ca0716f5SRobert Watson  * XXX Currently we do not support merging of records from multiple
42ca0716f5SRobert Watson  * XXX audit trail files
43ca0716f5SRobert Watson  * XXX We assume that records are sorted chronologically - both wrt to
44ca0716f5SRobert Watson  * XXX the records present within the file and between the files themselves
45ca0716f5SRobert Watson  */
46ca0716f5SRobert Watson 
474bd0c025SRobert Watson #include <config/config.h>
48c74c7b73SRobert Watson 
49c74c7b73SRobert Watson #define	_GNU_SOURCE		/* Required for strptime() on glibc2. */
50c74c7b73SRobert Watson 
514bd0c025SRobert Watson #ifdef HAVE_FULL_QUEUE_H
524bd0c025SRobert Watson #include <sys/queue.h>
534bd0c025SRobert Watson #else
544bd0c025SRobert Watson #include <compat/queue.h>
554bd0c025SRobert Watson #endif
564bd0c025SRobert Watson 
575e386598SRobert Watson #ifdef HAVE_CAP_ENTER
585e386598SRobert Watson #include <sys/capsicum.h>
595e386598SRobert Watson #include <sys/wait.h>
605e386598SRobert Watson #endif
615e386598SRobert Watson 
62ca0716f5SRobert Watson #include <bsm/libbsm.h>
63ca0716f5SRobert Watson 
64506764c6SRobert Watson #include <err.h>
65*71f8f483SKyle Evans #include <fnmatch.h>
66506764c6SRobert Watson #include <grp.h>
67506764c6SRobert Watson #include <pwd.h>
68ca0716f5SRobert Watson #include <stdio.h>
69ca0716f5SRobert Watson #include <stdlib.h>
70ca0716f5SRobert Watson #include <sysexits.h>
71ca0716f5SRobert Watson #include <string.h>
72ca0716f5SRobert Watson #include <time.h>
73ca0716f5SRobert Watson #include <unistd.h>
744bd0c025SRobert Watson #include <regex.h>
754bd0c025SRobert Watson #include <errno.h>
76ca0716f5SRobert Watson 
7752267f74SRobert Watson #ifndef HAVE_STRLCPY
7852267f74SRobert Watson #include <compat/strlcpy.h>
7952267f74SRobert Watson #endif
8052267f74SRobert Watson 
81ca0716f5SRobert Watson #include "auditreduce.h"
82ca0716f5SRobert Watson 
834bd0c025SRobert Watson static TAILQ_HEAD(tailhead, re_entry) re_head =
844bd0c025SRobert Watson     TAILQ_HEAD_INITIALIZER(re_head);
854bd0c025SRobert Watson 
86ca0716f5SRobert Watson extern char		*optarg;
87ca0716f5SRobert Watson extern int		 optind, optopt, opterr,optreset;
88ca0716f5SRobert Watson 
89ca0716f5SRobert Watson static au_mask_t	 maskp;		/* Class. */
90ca0716f5SRobert Watson static time_t		 p_atime;	/* Created after this time. */
91ca0716f5SRobert Watson static time_t		 p_btime;	/* Created before this time. */
92ca0716f5SRobert Watson static int		 p_auid;	/* Audit id. */
93ca0716f5SRobert Watson static int		 p_euid;	/* Effective user id. */
94ca0716f5SRobert Watson static int		 p_egid;	/* Effective group id. */
95ca0716f5SRobert Watson static int		 p_rgid;	/* Real group id. */
96ca0716f5SRobert Watson static int		 p_ruid;	/* Real user id. */
97ca0716f5SRobert Watson static int		 p_subid;	/* Subject id. */
98*71f8f483SKyle Evans static const char	*p_zone;	/* Zone. */
99ca0716f5SRobert Watson 
100ca0716f5SRobert Watson /*
10152267f74SRobert Watson  * Maintain a dynamically sized array of events for -m
10252267f74SRobert Watson  */
10352267f74SRobert Watson static uint16_t		*p_evec;	/* Event type list */
10452267f74SRobert Watson static int		 p_evec_used;	/* Number of events used */
10552267f74SRobert Watson static int		 p_evec_alloc;	/* Number of events allocated */
10652267f74SRobert Watson 
10752267f74SRobert Watson /*
108ca0716f5SRobert Watson  * Following are the objects (-o option) that we can select upon.
109ca0716f5SRobert Watson  */
110ca0716f5SRobert Watson static char	*p_fileobj = NULL;
111ca0716f5SRobert Watson static char	*p_msgqobj = NULL;
112ca0716f5SRobert Watson static char	*p_pidobj = NULL;
113ca0716f5SRobert Watson static char	*p_semobj = NULL;
114ca0716f5SRobert Watson static char	*p_shmobj = NULL;
115ca0716f5SRobert Watson static char	*p_sockobj = NULL;
116ca0716f5SRobert Watson 
117ca0716f5SRobert Watson static uint32_t opttochk = 0;
118ca0716f5SRobert Watson 
119*71f8f483SKyle Evans static int	select_zone(const char *zone, uint32_t *optchkd);
120*71f8f483SKyle Evans 
121ca0716f5SRobert Watson static void
parse_regexp(char * re_string)1224bd0c025SRobert Watson parse_regexp(char *re_string)
1234bd0c025SRobert Watson {
1244bd0c025SRobert Watson 	char *orig, *copy, re_error[64];
1254bd0c025SRobert Watson 	struct re_entry *rep;
1264bd0c025SRobert Watson 	int error, nstrs, i, len;
1274bd0c025SRobert Watson 
1284bd0c025SRobert Watson 	copy = strdup(re_string);
1294bd0c025SRobert Watson 	orig = copy;
1304bd0c025SRobert Watson 	len = strlen(copy);
1314bd0c025SRobert Watson 	for (nstrs = 0, i = 0; i < len; i++) {
1324bd0c025SRobert Watson 		if (copy[i] == ',' && i > 0) {
1334bd0c025SRobert Watson 			if (copy[i - 1] == '\\')
13452267f74SRobert Watson 				strlcpy(&copy[i - 1], &copy[i], len);
1354bd0c025SRobert Watson 			else {
1364bd0c025SRobert Watson 				nstrs++;
1374bd0c025SRobert Watson 				copy[i] = '\0';
1384bd0c025SRobert Watson 			}
1394bd0c025SRobert Watson 		}
1404bd0c025SRobert Watson 	}
1414bd0c025SRobert Watson 	TAILQ_INIT(&re_head);
1424bd0c025SRobert Watson 	for (i = 0; i < nstrs + 1; i++) {
1434bd0c025SRobert Watson 		rep = calloc(1, sizeof(*rep));
1444bd0c025SRobert Watson 		if (rep == NULL) {
1454bd0c025SRobert Watson 			(void) fprintf(stderr, "calloc: %s\n",
1464bd0c025SRobert Watson 			    strerror(errno));
1474bd0c025SRobert Watson 			exit(1);
1484bd0c025SRobert Watson 		}
1494bd0c025SRobert Watson 		if (*copy == '~') {
1504bd0c025SRobert Watson 			copy++;
1514bd0c025SRobert Watson 			rep->re_negate = 1;
1524bd0c025SRobert Watson 		}
1534bd0c025SRobert Watson 		rep->re_pattern = strdup(copy);
1544bd0c025SRobert Watson 		error = regcomp(&rep->re_regexp, rep->re_pattern,
1554bd0c025SRobert Watson 		    REG_EXTENDED | REG_NOSUB);
1564bd0c025SRobert Watson 		if (error != 0) {
1574bd0c025SRobert Watson 			regerror(error, &rep->re_regexp, re_error, 64);
1584bd0c025SRobert Watson 			(void) fprintf(stderr, "regcomp: %s\n", re_error);
1594bd0c025SRobert Watson 			exit(1);
1604bd0c025SRobert Watson 		}
1614bd0c025SRobert Watson 		TAILQ_INSERT_TAIL(&re_head, rep, re_glue);
1624bd0c025SRobert Watson 		len = strlen(copy);
1634bd0c025SRobert Watson 		copy += len + 1;
1644bd0c025SRobert Watson 	}
1654bd0c025SRobert Watson 	free(orig);
1664bd0c025SRobert Watson }
1674bd0c025SRobert Watson 
1684bd0c025SRobert Watson static void
usage(const char * msg)169ca0716f5SRobert Watson usage(const char *msg)
170ca0716f5SRobert Watson {
171ca0716f5SRobert Watson 	fprintf(stderr, "%s\n", msg);
1724bd0c025SRobert Watson 	fprintf(stderr, "Usage: auditreduce [options] [file ...]\n");
173ca0716f5SRobert Watson 	fprintf(stderr, "\tOptions are : \n");
174ca0716f5SRobert Watson 	fprintf(stderr, "\t-A : all records\n");
175ca0716f5SRobert Watson 	fprintf(stderr, "\t-a YYYYMMDD[HH[[MM[SS]]] : after date\n");
176ca0716f5SRobert Watson 	fprintf(stderr, "\t-b YYYYMMDD[HH[[MM[SS]]] : before date\n");
177ca0716f5SRobert Watson 	fprintf(stderr, "\t-c <flags> : matching class\n");
178ca0716f5SRobert Watson 	fprintf(stderr, "\t-d YYYYMMDD : on date\n");
179ca0716f5SRobert Watson 	fprintf(stderr, "\t-e <uid|name>  : effective user\n");
180ca0716f5SRobert Watson 	fprintf(stderr, "\t-f <gid|group> : effective group\n");
181ca0716f5SRobert Watson 	fprintf(stderr, "\t-g <gid|group> : real group\n");
182ca0716f5SRobert Watson 	fprintf(stderr, "\t-j <pid> : subject id \n");
183ca0716f5SRobert Watson 	fprintf(stderr, "\t-m <evno|evname> : matching event\n");
184ca0716f5SRobert Watson 	fprintf(stderr, "\t-o objecttype=objectvalue\n");
185ca0716f5SRobert Watson 	fprintf(stderr, "\t\t file=<pathname>\n");
186ca0716f5SRobert Watson 	fprintf(stderr, "\t\t msgqid=<ID>\n");
187ca0716f5SRobert Watson 	fprintf(stderr, "\t\t pid=<ID>\n");
188ca0716f5SRobert Watson 	fprintf(stderr, "\t\t semid=<ID>\n");
189ca0716f5SRobert Watson 	fprintf(stderr, "\t\t shmid=<ID>\n");
190ca0716f5SRobert Watson 	fprintf(stderr, "\t-r <uid|name> : real user\n");
191ca0716f5SRobert Watson 	fprintf(stderr, "\t-u <uid|name> : audit user\n");
19252267f74SRobert Watson 	fprintf(stderr, "\t-v : select non-matching records\n");
193*71f8f483SKyle Evans 	fprintf(stderr, "\t-z <zone> : zone name\n");
194ca0716f5SRobert Watson 	exit(EX_USAGE);
195ca0716f5SRobert Watson }
196ca0716f5SRobert Watson 
197ca0716f5SRobert Watson /*
198ca0716f5SRobert Watson  * Check if the given auid matches the selection criteria.
199ca0716f5SRobert Watson  */
200ca0716f5SRobert Watson static int
select_auid(int au)201ca0716f5SRobert Watson select_auid(int au)
202ca0716f5SRobert Watson {
203ca0716f5SRobert Watson 
204ca0716f5SRobert Watson 	/* Check if we want to select on auid. */
205ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_u)) {
206ca0716f5SRobert Watson 		if (au != p_auid)
207ca0716f5SRobert Watson 			return (0);
208ca0716f5SRobert Watson 	}
209ca0716f5SRobert Watson 	return (1);
210ca0716f5SRobert Watson }
211ca0716f5SRobert Watson 
212ca0716f5SRobert Watson /*
213ca0716f5SRobert Watson  * Check if the given euid matches the selection criteria.
214ca0716f5SRobert Watson  */
215ca0716f5SRobert Watson static int
select_euid(int euser)216ca0716f5SRobert Watson select_euid(int euser)
217ca0716f5SRobert Watson {
218ca0716f5SRobert Watson 
219ca0716f5SRobert Watson 	/* Check if we want to select on euid. */
220ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_e)) {
221ca0716f5SRobert Watson 		if (euser != p_euid)
222ca0716f5SRobert Watson 			return (0);
223ca0716f5SRobert Watson 	}
224ca0716f5SRobert Watson 	return (1);
225ca0716f5SRobert Watson }
226ca0716f5SRobert Watson 
227ca0716f5SRobert Watson /*
228ca0716f5SRobert Watson  * Check if the given egid matches the selection criteria.
229ca0716f5SRobert Watson  */
230ca0716f5SRobert Watson static int
select_egid(int egrp)231ca0716f5SRobert Watson select_egid(int egrp)
232ca0716f5SRobert Watson {
233ca0716f5SRobert Watson 
234ca0716f5SRobert Watson 	/* Check if we want to select on egid. */
235ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_f)) {
236ca0716f5SRobert Watson 		if (egrp != p_egid)
237ca0716f5SRobert Watson 			return (0);
238ca0716f5SRobert Watson 	}
239ca0716f5SRobert Watson 	return (1);
240ca0716f5SRobert Watson }
241ca0716f5SRobert Watson 
242ca0716f5SRobert Watson /*
243ca0716f5SRobert Watson  * Check if the given rgid matches the selection criteria.
244ca0716f5SRobert Watson  */
245ca0716f5SRobert Watson static int
select_rgid(int grp)246ca0716f5SRobert Watson select_rgid(int grp)
247ca0716f5SRobert Watson {
248ca0716f5SRobert Watson 
249ca0716f5SRobert Watson 	/* Check if we want to select on rgid. */
250ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_g)) {
251ca0716f5SRobert Watson 		if (grp != p_rgid)
252ca0716f5SRobert Watson 			return (0);
253ca0716f5SRobert Watson 	}
254ca0716f5SRobert Watson 	return (1);
255ca0716f5SRobert Watson }
256ca0716f5SRobert Watson 
257ca0716f5SRobert Watson /*
258ca0716f5SRobert Watson  * Check if the given ruid matches the selection criteria.
259ca0716f5SRobert Watson  */
260ca0716f5SRobert Watson static int
select_ruid(int user)261ca0716f5SRobert Watson select_ruid(int user)
262ca0716f5SRobert Watson {
263ca0716f5SRobert Watson 
264ca0716f5SRobert Watson 	/* Check if we want to select on rgid. */
265ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_r)) {
266ca0716f5SRobert Watson 		if (user != p_ruid)
267ca0716f5SRobert Watson 			return (0);
268ca0716f5SRobert Watson 	}
269ca0716f5SRobert Watson 	return (1);
270ca0716f5SRobert Watson }
271ca0716f5SRobert Watson 
272ca0716f5SRobert Watson /*
273ca0716f5SRobert Watson  * Check if the given subject id (pid) matches the selection criteria.
274ca0716f5SRobert Watson  */
275ca0716f5SRobert Watson static int
select_subid(int subid)276ca0716f5SRobert Watson select_subid(int subid)
277ca0716f5SRobert Watson {
278ca0716f5SRobert Watson 
279ca0716f5SRobert Watson 	/* Check if we want to select on subject uid. */
280ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_j)) {
281ca0716f5SRobert Watson 		if (subid != p_subid)
282ca0716f5SRobert Watson 			return (0);
283ca0716f5SRobert Watson 	}
284ca0716f5SRobert Watson 	return (1);
285ca0716f5SRobert Watson }
286ca0716f5SRobert Watson 
287ca0716f5SRobert Watson 
288ca0716f5SRobert Watson /*
289ca0716f5SRobert Watson  * Check if object's pid maches the given pid.
290ca0716f5SRobert Watson  */
291ca0716f5SRobert Watson static int
select_pidobj(uint32_t pid)292ca0716f5SRobert Watson select_pidobj(uint32_t pid)
293ca0716f5SRobert Watson {
294ca0716f5SRobert Watson 
295ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_op)) {
29652267f74SRobert Watson 		if (pid != (uint32_t)strtol(p_pidobj, (char **)NULL, 10))
297ca0716f5SRobert Watson 			return (0);
298ca0716f5SRobert Watson 	}
299ca0716f5SRobert Watson 	return (1);
300ca0716f5SRobert Watson }
301ca0716f5SRobert Watson 
302ca0716f5SRobert Watson /*
303ca0716f5SRobert Watson  * Check if the given ipc object with the given type matches the selection
304ca0716f5SRobert Watson  * criteria.
305ca0716f5SRobert Watson  */
306ca0716f5SRobert Watson static int
select_ipcobj(u_char type,uint32_t id,uint32_t * optchkd)307ca0716f5SRobert Watson select_ipcobj(u_char type, uint32_t id, uint32_t *optchkd)
308ca0716f5SRobert Watson {
309ca0716f5SRobert Watson 
310ca0716f5SRobert Watson 	if (type == AT_IPC_MSG) {
311ca0716f5SRobert Watson 		SETOPT((*optchkd), OPT_om);
312ca0716f5SRobert Watson 		if (ISOPTSET(opttochk, OPT_om)) {
31352267f74SRobert Watson 			if (id != (uint32_t)strtol(p_msgqobj, (char **)NULL,
31452267f74SRobert Watson 			    10))
315ca0716f5SRobert Watson 				return (0);
316ca0716f5SRobert Watson 		}
317ca0716f5SRobert Watson 		return (1);
318ca0716f5SRobert Watson 	} else if (type == AT_IPC_SEM) {
319ca0716f5SRobert Watson 		SETOPT((*optchkd), OPT_ose);
320ca0716f5SRobert Watson 		if (ISOPTSET(opttochk, OPT_ose)) {
32152267f74SRobert Watson 			if (id != (uint32_t)strtol(p_semobj, (char **)NULL, 10))
322ca0716f5SRobert Watson 				return (0);
323ca0716f5SRobert Watson 		}
324ca0716f5SRobert Watson 		return (1);
325ca0716f5SRobert Watson 	} else if (type == AT_IPC_SHM) {
326ca0716f5SRobert Watson 		SETOPT((*optchkd), OPT_osh);
327ca0716f5SRobert Watson 		if (ISOPTSET(opttochk, OPT_osh)) {
32852267f74SRobert Watson 			if (id != (uint32_t)strtol(p_shmobj, (char **)NULL, 10))
329ca0716f5SRobert Watson 				return (0);
330ca0716f5SRobert Watson 		}
331ca0716f5SRobert Watson 		return (1);
332ca0716f5SRobert Watson 	}
333ca0716f5SRobert Watson 
334ca0716f5SRobert Watson 	/* Unknown type -- filter if *any* ipc filtering is required. */
335ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_om) || ISOPTSET(opttochk, OPT_ose)
336ca0716f5SRobert Watson 	    || ISOPTSET(opttochk, OPT_osh))
337ca0716f5SRobert Watson 		return (0);
338ca0716f5SRobert Watson 
339ca0716f5SRobert Watson 	return (1);
340ca0716f5SRobert Watson }
341ca0716f5SRobert Watson 
342ca0716f5SRobert Watson 
343ca0716f5SRobert Watson /*
344ca0716f5SRobert Watson  * Check if the file name matches selection criteria.
345ca0716f5SRobert Watson  */
346ca0716f5SRobert Watson static int
select_filepath(char * path,uint32_t * optchkd)347ca0716f5SRobert Watson select_filepath(char *path, uint32_t *optchkd)
348ca0716f5SRobert Watson {
3494bd0c025SRobert Watson 	struct re_entry *rep;
3504bd0c025SRobert Watson 	int match;
351ca0716f5SRobert Watson 
352ca0716f5SRobert Watson 	SETOPT((*optchkd), OPT_of);
3534bd0c025SRobert Watson 	match = 1;
354ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_of)) {
3554bd0c025SRobert Watson 		match = 0;
3564bd0c025SRobert Watson 		TAILQ_FOREACH(rep, &re_head, re_glue) {
3574bd0c025SRobert Watson 			if (regexec(&rep->re_regexp, path, 0, NULL,
3584bd0c025SRobert Watson 			    0) != REG_NOMATCH)
3594bd0c025SRobert Watson 				return (!rep->re_negate);
360ca0716f5SRobert Watson 		}
361ca0716f5SRobert Watson 	}
3624bd0c025SRobert Watson 	return (match);
363ca0716f5SRobert Watson }
364ca0716f5SRobert Watson 
365ca0716f5SRobert Watson /*
366ca0716f5SRobert Watson  * Returns 1 if the following pass the selection rules:
367ca0716f5SRobert Watson  *
368ca0716f5SRobert Watson  * before-time,
369ca0716f5SRobert Watson  * after time,
370ca0716f5SRobert Watson  * date,
371ca0716f5SRobert Watson  * class,
372ca0716f5SRobert Watson  * event
373ca0716f5SRobert Watson  */
374ca0716f5SRobert Watson static int
select_hdr32(tokenstr_t tok,uint32_t * optchkd)375ca0716f5SRobert Watson select_hdr32(tokenstr_t tok, uint32_t *optchkd)
376ca0716f5SRobert Watson {
37752267f74SRobert Watson 	uint16_t *ev;
37852267f74SRobert Watson 	int match;
379ca0716f5SRobert Watson 
38052267f74SRobert Watson 	SETOPT((*optchkd), (OPT_A | OPT_a | OPT_b | OPT_c | OPT_m | OPT_v));
381ca0716f5SRobert Watson 
382ca0716f5SRobert Watson 	/* The A option overrides a, b and d. */
383ca0716f5SRobert Watson 	if (!ISOPTSET(opttochk, OPT_A)) {
384ca0716f5SRobert Watson 		if (ISOPTSET(opttochk, OPT_a)) {
385ca0716f5SRobert Watson 			if (difftime((time_t)tok.tt.hdr32.s, p_atime) < 0) {
386ca0716f5SRobert Watson 				/* Record was created before p_atime. */
387ca0716f5SRobert Watson 				return (0);
388ca0716f5SRobert Watson 			}
389ca0716f5SRobert Watson 		}
390ca0716f5SRobert Watson 
391ca0716f5SRobert Watson 		if (ISOPTSET(opttochk, OPT_b)) {
392ca0716f5SRobert Watson 			if (difftime(p_btime, (time_t)tok.tt.hdr32.s) < 0) {
393ca0716f5SRobert Watson 				/* Record was created after p_btime. */
394ca0716f5SRobert Watson 				return (0);
395ca0716f5SRobert Watson 			}
396ca0716f5SRobert Watson 		}
397ca0716f5SRobert Watson 	}
398ca0716f5SRobert Watson 
399ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_c)) {
400ca0716f5SRobert Watson 		/*
401ca0716f5SRobert Watson 		 * Check if the classes represented by the event matches
402ca0716f5SRobert Watson 		 * given class.
403ca0716f5SRobert Watson 		 */
404ca0716f5SRobert Watson 		if (au_preselect(tok.tt.hdr32.e_type, &maskp, AU_PRS_BOTH,
405ca0716f5SRobert Watson 		    AU_PRS_USECACHE) != 1)
406ca0716f5SRobert Watson 			return (0);
407ca0716f5SRobert Watson 	}
408ca0716f5SRobert Watson 
409ca0716f5SRobert Watson 	/* Check if event matches. */
410ca0716f5SRobert Watson 	if (ISOPTSET(opttochk, OPT_m)) {
41152267f74SRobert Watson 		match = 0;
41252267f74SRobert Watson 		for (ev = p_evec; ev < &p_evec[p_evec_used]; ev++)
41352267f74SRobert Watson 			if (tok.tt.hdr32.e_type == *ev)
41452267f74SRobert Watson 				match = 1;
41552267f74SRobert Watson 		if (match == 0)
416ca0716f5SRobert Watson 			return (0);
417ca0716f5SRobert Watson 	}
418ca0716f5SRobert Watson 
419ca0716f5SRobert Watson 	return (1);
420ca0716f5SRobert Watson }
421ca0716f5SRobert Watson 
4224bd0c025SRobert Watson static int
select_return32(tokenstr_t tok_ret32,tokenstr_t tok_hdr32,uint32_t * optchkd)4234bd0c025SRobert Watson select_return32(tokenstr_t tok_ret32, tokenstr_t tok_hdr32, uint32_t *optchkd)
4244bd0c025SRobert Watson {
4254bd0c025SRobert Watson 	int sorf;
4264bd0c025SRobert Watson 
4274bd0c025SRobert Watson 	SETOPT((*optchkd), (OPT_c));
4284bd0c025SRobert Watson 	if (tok_ret32.tt.ret32.status == 0)
4294bd0c025SRobert Watson 		sorf = AU_PRS_SUCCESS;
4304bd0c025SRobert Watson 	else
4314bd0c025SRobert Watson 		sorf = AU_PRS_FAILURE;
4324bd0c025SRobert Watson 	if (ISOPTSET(opttochk, OPT_c)) {
4334bd0c025SRobert Watson 		if (au_preselect(tok_hdr32.tt.hdr32.e_type, &maskp, sorf,
4344bd0c025SRobert Watson 		    AU_PRS_USECACHE) != 1)
4354bd0c025SRobert Watson 			return (0);
4364bd0c025SRobert Watson 	}
4374bd0c025SRobert Watson 	return (1);
4384bd0c025SRobert Watson }
4394bd0c025SRobert Watson 
440ca0716f5SRobert Watson /*
441ca0716f5SRobert Watson  * Return 1 if checks for the the following succeed
442ca0716f5SRobert Watson  * auid,
443ca0716f5SRobert Watson  * euid,
444ca0716f5SRobert Watson  * egid,
445ca0716f5SRobert Watson  * rgid,
446ca0716f5SRobert Watson  * ruid,
447ca0716f5SRobert Watson  * process id
448ca0716f5SRobert Watson  */
449ca0716f5SRobert Watson static int
select_proc32(tokenstr_t tok,uint32_t * optchkd)450ca0716f5SRobert Watson select_proc32(tokenstr_t tok, uint32_t *optchkd)
451ca0716f5SRobert Watson {
452ca0716f5SRobert Watson 
453ca0716f5SRobert Watson 	SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_op));
454ca0716f5SRobert Watson 
455ca0716f5SRobert Watson 	if (!select_auid(tok.tt.proc32.auid))
456ca0716f5SRobert Watson 		return (0);
457ca0716f5SRobert Watson 	if (!select_euid(tok.tt.proc32.euid))
458ca0716f5SRobert Watson 		return (0);
459ca0716f5SRobert Watson 	if (!select_egid(tok.tt.proc32.egid))
460ca0716f5SRobert Watson 		return (0);
461ca0716f5SRobert Watson 	if (!select_rgid(tok.tt.proc32.rgid))
462ca0716f5SRobert Watson 		return (0);
463ca0716f5SRobert Watson 	if (!select_ruid(tok.tt.proc32.ruid))
464ca0716f5SRobert Watson 		return (0);
465ca0716f5SRobert Watson 	if (!select_pidobj(tok.tt.proc32.pid))
466ca0716f5SRobert Watson 		return (0);
467ca0716f5SRobert Watson 	return (1);
468ca0716f5SRobert Watson }
469ca0716f5SRobert Watson 
470ca0716f5SRobert Watson /*
471ca0716f5SRobert Watson  * Return 1 if checks for the the following succeed
472ca0716f5SRobert Watson  * auid,
473ca0716f5SRobert Watson  * euid,
474ca0716f5SRobert Watson  * egid,
475ca0716f5SRobert Watson  * rgid,
476ca0716f5SRobert Watson  * ruid,
477ca0716f5SRobert Watson  * subject id
478ca0716f5SRobert Watson  */
479ca0716f5SRobert Watson static int
select_subj32(tokenstr_t tok,uint32_t * optchkd)480ca0716f5SRobert Watson select_subj32(tokenstr_t tok, uint32_t *optchkd)
481ca0716f5SRobert Watson {
482ca0716f5SRobert Watson 
483ca0716f5SRobert Watson 	SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_j));
484ca0716f5SRobert Watson 
485ca0716f5SRobert Watson 	if (!select_auid(tok.tt.subj32.auid))
486ca0716f5SRobert Watson 		return (0);
487ca0716f5SRobert Watson 	if (!select_euid(tok.tt.subj32.euid))
488ca0716f5SRobert Watson 		return (0);
489ca0716f5SRobert Watson 	if (!select_egid(tok.tt.subj32.egid))
490ca0716f5SRobert Watson 		return (0);
491ca0716f5SRobert Watson 	if (!select_rgid(tok.tt.subj32.rgid))
492ca0716f5SRobert Watson 		return (0);
493ca0716f5SRobert Watson 	if (!select_ruid(tok.tt.subj32.ruid))
494ca0716f5SRobert Watson 		return (0);
495ca0716f5SRobert Watson 	if (!select_subid(tok.tt.subj32.pid))
496ca0716f5SRobert Watson 		return (0);
497ca0716f5SRobert Watson 	return (1);
498ca0716f5SRobert Watson }
499ca0716f5SRobert Watson 
500ca0716f5SRobert Watson /*
501*71f8f483SKyle Evans  * Check if the given zone matches the selection criteria.
502*71f8f483SKyle Evans   */
503*71f8f483SKyle Evans static int
select_zone(const char * zone,uint32_t * optchkd)504*71f8f483SKyle Evans select_zone(const char *zone, uint32_t *optchkd)
505*71f8f483SKyle Evans {
506*71f8f483SKyle Evans 
507*71f8f483SKyle Evans 	SETOPT((*optchkd), OPT_z);
508*71f8f483SKyle Evans 	if (ISOPTSET(opttochk, OPT_z) && p_zone != NULL) {
509*71f8f483SKyle Evans 		if (fnmatch(p_zone, zone, FNM_PATHNAME) != 0)
510*71f8f483SKyle Evans 			return (0);
511*71f8f483SKyle Evans 	}
512*71f8f483SKyle Evans 	return (1);
513*71f8f483SKyle Evans }
514*71f8f483SKyle Evans 
515*71f8f483SKyle Evans /*
516ca0716f5SRobert Watson  * Read each record from the audit trail.  Check if it is selected after
517ca0716f5SRobert Watson  * passing through each of the options
518ca0716f5SRobert Watson  */
519ca0716f5SRobert Watson static int
select_records(FILE * fp)520ca0716f5SRobert Watson select_records(FILE *fp)
521ca0716f5SRobert Watson {
5224bd0c025SRobert Watson 	tokenstr_t tok_hdr32_copy;
523ca0716f5SRobert Watson 	u_char *buf;
524ca0716f5SRobert Watson 	tokenstr_t tok;
525ca0716f5SRobert Watson 	int reclen;
526ca0716f5SRobert Watson 	int bytesread;
527ca0716f5SRobert Watson 	int selected;
528ca0716f5SRobert Watson 	uint32_t optchkd;
52952267f74SRobert Watson 	int print;
530ca0716f5SRobert Watson 
531ca0716f5SRobert Watson 	int err = 0;
532ca0716f5SRobert Watson 	while ((reclen = au_read_rec(fp, &buf)) != -1) {
533ca0716f5SRobert Watson 		optchkd = 0;
534ca0716f5SRobert Watson 		bytesread = 0;
535ca0716f5SRobert Watson 		selected = 1;
536ca0716f5SRobert Watson 		while ((selected == 1) && (bytesread < reclen)) {
537ca0716f5SRobert Watson 			if (-1 == au_fetch_tok(&tok, buf + bytesread,
538ca0716f5SRobert Watson 			    reclen - bytesread)) {
539ca0716f5SRobert Watson 				/* Is this an incomplete record? */
540ca0716f5SRobert Watson 				err = 1;
541ca0716f5SRobert Watson 				break;
542ca0716f5SRobert Watson 			}
543ca0716f5SRobert Watson 
544ca0716f5SRobert Watson 			/*
545ca0716f5SRobert Watson 			 * For each token type we have have different
546ca0716f5SRobert Watson 			 * selection criteria.
547ca0716f5SRobert Watson 			 */
548ca0716f5SRobert Watson 			switch(tok.id) {
54952267f74SRobert Watson 			case AUT_HEADER32:
550ca0716f5SRobert Watson 					selected = select_hdr32(tok,
551ca0716f5SRobert Watson 					    &optchkd);
5524bd0c025SRobert Watson 					bcopy(&tok, &tok_hdr32_copy,
5534bd0c025SRobert Watson 					    sizeof(tok));
554ca0716f5SRobert Watson 					break;
555ca0716f5SRobert Watson 
55652267f74SRobert Watson 			case AUT_PROCESS32:
557ca0716f5SRobert Watson 					selected = select_proc32(tok,
558ca0716f5SRobert Watson 					    &optchkd);
559ca0716f5SRobert Watson 					break;
560ca0716f5SRobert Watson 
56152267f74SRobert Watson 			case AUT_SUBJECT32:
562ca0716f5SRobert Watson 					selected = select_subj32(tok,
563ca0716f5SRobert Watson 					    &optchkd);
564ca0716f5SRobert Watson 					break;
565ca0716f5SRobert Watson 
56652267f74SRobert Watson 			case AUT_IPC:
567ca0716f5SRobert Watson 					selected = select_ipcobj(
568ca0716f5SRobert Watson 					    tok.tt.ipc.type, tok.tt.ipc.id,
569ca0716f5SRobert Watson 					    &optchkd);
570ca0716f5SRobert Watson 					break;
571ca0716f5SRobert Watson 
57252267f74SRobert Watson 			case AUT_PATH:
573ca0716f5SRobert Watson 					selected = select_filepath(
574ca0716f5SRobert Watson 					    tok.tt.path.path, &optchkd);
575ca0716f5SRobert Watson 					break;
576ca0716f5SRobert Watson 
57752267f74SRobert Watson 			case AUT_RETURN32:
5784bd0c025SRobert Watson 				selected = select_return32(tok,
5794bd0c025SRobert Watson 				    tok_hdr32_copy, &optchkd);
5804bd0c025SRobert Watson 				break;
5814bd0c025SRobert Watson 
582*71f8f483SKyle Evans 			case AUT_ZONENAME:
583*71f8f483SKyle Evans 				selected = select_zone(tok.tt.zonename.zonename, &optchkd);
584*71f8f483SKyle Evans 				break;
585*71f8f483SKyle Evans 
586ca0716f5SRobert Watson 			default:
587ca0716f5SRobert Watson 				break;
588ca0716f5SRobert Watson 			}
589ca0716f5SRobert Watson 			bytesread += tok.len;
590ca0716f5SRobert Watson 		}
591ca0716f5SRobert Watson 		/* Check if all the options were matched. */
59252267f74SRobert Watson 		print = ((selected == 1) && (!err) && (!(opttochk & ~optchkd)));
59352267f74SRobert Watson 		if (ISOPTSET(opttochk, OPT_v))
59452267f74SRobert Watson 			print = !print;
59552267f74SRobert Watson 		if (print)
59652267f74SRobert Watson 			(void) fwrite(buf, 1, reclen, stdout);
597ca0716f5SRobert Watson 		free(buf);
598ca0716f5SRobert Watson 	}
599ca0716f5SRobert Watson 	return (0);
600ca0716f5SRobert Watson }
601ca0716f5SRobert Watson 
602ca0716f5SRobert Watson /*
603ca0716f5SRobert Watson  * The -o option has the form object_type=object_value.  Identify the object
604ca0716f5SRobert Watson  * components.
605ca0716f5SRobert Watson  */
6067a0a89d2SRobert Watson static void
parse_object_type(char * name,char * val)607ca0716f5SRobert Watson parse_object_type(char *name, char *val)
608ca0716f5SRobert Watson {
609ca0716f5SRobert Watson 	if (val == NULL)
610ca0716f5SRobert Watson 		return;
611ca0716f5SRobert Watson 
612ca0716f5SRobert Watson 	if (!strcmp(name, FILEOBJ)) {
613ca0716f5SRobert Watson 		p_fileobj = val;
6144bd0c025SRobert Watson 		parse_regexp(val);
615ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_of);
616ca0716f5SRobert Watson 	} else if (!strcmp(name, MSGQIDOBJ)) {
617ca0716f5SRobert Watson 		p_msgqobj = val;
618ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_om);
619ca0716f5SRobert Watson 	} else if (!strcmp(name, PIDOBJ)) {
620ca0716f5SRobert Watson 		p_pidobj = val;
621ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_op);
622ca0716f5SRobert Watson 	} else if (!strcmp(name, SEMIDOBJ)) {
623ca0716f5SRobert Watson 		p_semobj = val;
624ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_ose);
625ca0716f5SRobert Watson 	} else if (!strcmp(name, SHMIDOBJ)) {
626ca0716f5SRobert Watson 		p_shmobj = val;
627ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_osh);
628ca0716f5SRobert Watson 	} else if (!strcmp(name, SOCKOBJ)) {
629ca0716f5SRobert Watson 		p_sockobj = val;
630ca0716f5SRobert Watson 		SETOPT(opttochk, OPT_oso);
631ca0716f5SRobert Watson 	} else
632ca0716f5SRobert Watson 		usage("unknown value for -o");
633ca0716f5SRobert Watson }
634ca0716f5SRobert Watson 
635ca0716f5SRobert Watson int
main(int argc,char ** argv)636ca0716f5SRobert Watson main(int argc, char **argv)
637ca0716f5SRobert Watson {
638ca0716f5SRobert Watson 	struct group *grp;
639ca0716f5SRobert Watson 	struct passwd *pw;
640ca0716f5SRobert Watson 	struct tm tm;
641ca0716f5SRobert Watson 	au_event_t *n;
642ca0716f5SRobert Watson 	FILE *fp;
643ca0716f5SRobert Watson 	int i;
644ca0716f5SRobert Watson 	char *objval, *converr;
64523bf6e20SRobert Watson 	int ch;
646ca0716f5SRobert Watson 	char timestr[128];
647ca0716f5SRobert Watson 	char *fname;
64852267f74SRobert Watson 	uint16_t *etp;
6495e386598SRobert Watson #ifdef HAVE_CAP_ENTER
6505e386598SRobert Watson 	int retval, status;
6515e386598SRobert Watson 	pid_t childpid, pid;
6525e386598SRobert Watson #endif
653ca0716f5SRobert Watson 
654ca0716f5SRobert Watson 	converr = NULL;
655ca0716f5SRobert Watson 
656*71f8f483SKyle Evans 	while ((ch = getopt(argc, argv, "Aa:b:c:d:e:f:g:j:m:o:r:u:vz:")) != -1) {
657ca0716f5SRobert Watson 		switch(ch) {
658ca0716f5SRobert Watson 		case 'A':
659ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_A);
660ca0716f5SRobert Watson 			break;
661ca0716f5SRobert Watson 
662ca0716f5SRobert Watson 		case 'a':
663ca0716f5SRobert Watson 			if (ISOPTSET(opttochk, OPT_a)) {
664ca0716f5SRobert Watson 				usage("d is exclusive with a and b");
665ca0716f5SRobert Watson 			}
666ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_a);
6670814440eSRobert Watson 			bzero(&tm, sizeof(tm));
668ca0716f5SRobert Watson 			strptime(optarg, "%Y%m%d%H%M%S", &tm);
669ca0716f5SRobert Watson 			strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S",
670ca0716f5SRobert Watson 			    &tm);
671ca0716f5SRobert Watson 			/* fprintf(stderr, "Time converted = %s\n", timestr); */
672ca0716f5SRobert Watson 			p_atime = mktime(&tm);
673ca0716f5SRobert Watson 			break;
674ca0716f5SRobert Watson 
675ca0716f5SRobert Watson 		case 'b':
676ca0716f5SRobert Watson 			if (ISOPTSET(opttochk, OPT_b)) {
677ca0716f5SRobert Watson 				usage("d is exclusive with a and b");
678ca0716f5SRobert Watson 			}
679ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_b);
6800814440eSRobert Watson 			bzero(&tm, sizeof(tm));
681ca0716f5SRobert Watson 			strptime(optarg, "%Y%m%d%H%M%S", &tm);
682ca0716f5SRobert Watson 			strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S",
683ca0716f5SRobert Watson 			    &tm);
684ca0716f5SRobert Watson 			/* fprintf(stderr, "Time converted = %s\n", timestr); */
685ca0716f5SRobert Watson 			p_btime = mktime(&tm);
686ca0716f5SRobert Watson 			break;
687ca0716f5SRobert Watson 
688ca0716f5SRobert Watson 		case 'c':
689ca0716f5SRobert Watson 			if (0 != getauditflagsbin(optarg, &maskp)) {
690ca0716f5SRobert Watson 				/* Incorrect class */
691ca0716f5SRobert Watson 				usage("Incorrect class");
692ca0716f5SRobert Watson 			}
693ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_c);
694ca0716f5SRobert Watson 			break;
695ca0716f5SRobert Watson 
696ca0716f5SRobert Watson 		case 'd':
697ca0716f5SRobert Watson 			if (ISOPTSET(opttochk, OPT_b) || ISOPTSET(opttochk,
698ca0716f5SRobert Watson 			    OPT_a))
699ca0716f5SRobert Watson 				usage("'d' is exclusive with 'a' and 'b'");
700ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_d);
7010814440eSRobert Watson 			bzero(&tm, sizeof(tm));
702ca0716f5SRobert Watson 			strptime(optarg, "%Y%m%d", &tm);
703ca0716f5SRobert Watson 			strftime(timestr, sizeof(timestr), "%Y%m%d", &tm);
704ca0716f5SRobert Watson 			/* fprintf(stderr, "Time converted = %s\n", timestr); */
705ca0716f5SRobert Watson 			p_atime = mktime(&tm);
706ca0716f5SRobert Watson 			tm.tm_hour = 23;
707ca0716f5SRobert Watson 			tm.tm_min = 59;
708ca0716f5SRobert Watson 			tm.tm_sec = 59;
709ca0716f5SRobert Watson 			strftime(timestr, sizeof(timestr), "%Y%m%d", &tm);
710ca0716f5SRobert Watson 			/* fprintf(stderr, "Time converted = %s\n", timestr); */
711ca0716f5SRobert Watson 			p_btime = mktime(&tm);
712ca0716f5SRobert Watson 			break;
713ca0716f5SRobert Watson 
714ca0716f5SRobert Watson 		case 'e':
715ca0716f5SRobert Watson 			p_euid = strtol(optarg, &converr, 10);
716ca0716f5SRobert Watson 			if (*converr != '\0') {
717ca0716f5SRobert Watson 				/* Try the actual name */
718ca0716f5SRobert Watson 				if ((pw = getpwnam(optarg)) == NULL)
719ca0716f5SRobert Watson 					break;
720ca0716f5SRobert Watson 				p_euid = pw->pw_uid;
721ca0716f5SRobert Watson 			}
722ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_e);
723ca0716f5SRobert Watson 			break;
724ca0716f5SRobert Watson 
725ca0716f5SRobert Watson 		case 'f':
726ca0716f5SRobert Watson 			p_egid = strtol(optarg, &converr, 10);
727ca0716f5SRobert Watson 			if (*converr != '\0') {
728ca0716f5SRobert Watson 				/* Try actual group name. */
729ca0716f5SRobert Watson 				if ((grp = getgrnam(optarg)) == NULL)
730ca0716f5SRobert Watson 					break;
731ca0716f5SRobert Watson 				p_egid = grp->gr_gid;
732ca0716f5SRobert Watson 			}
733ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_f);
734ca0716f5SRobert Watson 			break;
735ca0716f5SRobert Watson 
736ca0716f5SRobert Watson 		case 'g':
737ca0716f5SRobert Watson 			p_rgid = strtol(optarg, &converr, 10);
738ca0716f5SRobert Watson 			if (*converr != '\0') {
739ca0716f5SRobert Watson 				/* Try actual group name. */
740ca0716f5SRobert Watson 				if ((grp = getgrnam(optarg)) == NULL)
741ca0716f5SRobert Watson 					break;
742ca0716f5SRobert Watson 				p_rgid = grp->gr_gid;
743ca0716f5SRobert Watson 			}
744ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_g);
745ca0716f5SRobert Watson 			break;
746ca0716f5SRobert Watson 
747ca0716f5SRobert Watson 		case 'j':
748ca0716f5SRobert Watson 			p_subid = strtol(optarg, (char **)NULL, 10);
749ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_j);
750ca0716f5SRobert Watson 			break;
751ca0716f5SRobert Watson 
752ca0716f5SRobert Watson 		case 'm':
75352267f74SRobert Watson 			if (p_evec == NULL) {
75452267f74SRobert Watson 				p_evec_alloc = 32;
75552267f74SRobert Watson 				p_evec = malloc(sizeof(*etp) * p_evec_alloc);
75652267f74SRobert Watson 				if (p_evec == NULL)
75752267f74SRobert Watson 					err(1, "malloc");
75852267f74SRobert Watson 			} else if (p_evec_alloc == p_evec_used) {
75952267f74SRobert Watson 				p_evec_alloc <<= 1;
76052267f74SRobert Watson 				p_evec = realloc(p_evec,
76152267f74SRobert Watson 				    sizeof(*p_evec) * p_evec_alloc);
76252267f74SRobert Watson 				if (p_evec == NULL)
76352267f74SRobert Watson 					err(1, "realloc");
76452267f74SRobert Watson 			}
76552267f74SRobert Watson 			etp = &p_evec[p_evec_used++];
76652267f74SRobert Watson 			*etp = strtol(optarg, (char **)NULL, 10);
76752267f74SRobert Watson 			if (*etp == 0) {
768ca0716f5SRobert Watson 				/* Could be the string representation. */
769ca0716f5SRobert Watson 				n = getauevnonam(optarg);
770ca0716f5SRobert Watson 				if (n == NULL)
771ca0716f5SRobert Watson 					usage("Incorrect event name");
77252267f74SRobert Watson 				*etp = *n;
773ca0716f5SRobert Watson 			}
774ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_m);
775ca0716f5SRobert Watson 			break;
776ca0716f5SRobert Watson 
777ca0716f5SRobert Watson 		case 'o':
778ca0716f5SRobert Watson 			objval = strchr(optarg, '=');
779ca0716f5SRobert Watson 			if (objval != NULL) {
780ca0716f5SRobert Watson 				*objval = '\0';
781ca0716f5SRobert Watson 				objval += 1;
782ca0716f5SRobert Watson 				parse_object_type(optarg, objval);
783ca0716f5SRobert Watson 			}
784ca0716f5SRobert Watson 			break;
785ca0716f5SRobert Watson 
786ca0716f5SRobert Watson 		case 'r':
787ca0716f5SRobert Watson 			p_ruid = strtol(optarg, &converr, 10);
788ca0716f5SRobert Watson 			if (*converr != '\0') {
789ca0716f5SRobert Watson 				if ((pw = getpwnam(optarg)) == NULL)
790ca0716f5SRobert Watson 					break;
791ca0716f5SRobert Watson 				p_ruid = pw->pw_uid;
792ca0716f5SRobert Watson 			}
793ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_r);
794ca0716f5SRobert Watson 			break;
795ca0716f5SRobert Watson 
796ca0716f5SRobert Watson 		case 'u':
797ca0716f5SRobert Watson 			p_auid = strtol(optarg, &converr, 10);
798ca0716f5SRobert Watson 			if (*converr != '\0') {
799ca0716f5SRobert Watson 				if ((pw = getpwnam(optarg)) == NULL)
800ca0716f5SRobert Watson 					break;
801ca0716f5SRobert Watson 				p_auid = pw->pw_uid;
802ca0716f5SRobert Watson 			}
803ca0716f5SRobert Watson 			SETOPT(opttochk, OPT_u);
804ca0716f5SRobert Watson 			break;
805ca0716f5SRobert Watson 
80652267f74SRobert Watson 		case 'v':
80752267f74SRobert Watson 			SETOPT(opttochk, OPT_v);
80852267f74SRobert Watson 			break;
80952267f74SRobert Watson 
810*71f8f483SKyle Evans 		case 'z':
811*71f8f483SKyle Evans 			p_zone = optarg;
812*71f8f483SKyle Evans 			SETOPT(opttochk, OPT_z);
813*71f8f483SKyle Evans 			break;
814*71f8f483SKyle Evans 
815ca0716f5SRobert Watson 		case '?':
816ca0716f5SRobert Watson 		default:
817ca0716f5SRobert Watson 			usage("Unknown option");
818ca0716f5SRobert Watson 		}
819ca0716f5SRobert Watson 	}
820ca0716f5SRobert Watson 	argv += optind;
821ca0716f5SRobert Watson 	argc -= optind;
822ca0716f5SRobert Watson 
8234bd0c025SRobert Watson 	if (argc == 0) {
8245e386598SRobert Watson #ifdef HAVE_CAP_ENTER
8255e386598SRobert Watson 		retval = cap_enter();
8265e386598SRobert Watson 		if (retval != 0 && errno != ENOSYS)
8275e386598SRobert Watson 			err(EXIT_FAILURE, "cap_enter");
8285e386598SRobert Watson #endif
8294bd0c025SRobert Watson 		if (select_records(stdin) == -1)
8304bd0c025SRobert Watson 			errx(EXIT_FAILURE,
8314bd0c025SRobert Watson 			    "Couldn't select records from stdin");
8324bd0c025SRobert Watson 		exit(EXIT_SUCCESS);
8334bd0c025SRobert Watson 	}
834ca0716f5SRobert Watson 
835ca0716f5SRobert Watson 	/*
836ca0716f5SRobert Watson 	 * XXX: We should actually be merging records here.
837ca0716f5SRobert Watson 	 */
838ca0716f5SRobert Watson 	for (i = 0; i < argc; i++) {
839ca0716f5SRobert Watson 		fname = argv[i];
840ca0716f5SRobert Watson 		fp = fopen(fname, "r");
841ca0716f5SRobert Watson 		if (fp == NULL)
842ca0716f5SRobert Watson 			errx(EXIT_FAILURE, "Couldn't open %s", fname);
8435e386598SRobert Watson 
8445e386598SRobert Watson 		/*
8455e386598SRobert Watson 		 * If operating with sandboxing, create a sandbox process for
8465e386598SRobert Watson 		 * each trail file we operate on.  This avoids the need to do
8475e386598SRobert Watson 		 * fancy things with file descriptors, etc, when iterating on
8485e386598SRobert Watson 		 * a list of arguments.
8495e386598SRobert Watson 		 *
8505e386598SRobert Watson 		 * NB: Unlike praudit(1), auditreduce(1) terminates if it hits
8515e386598SRobert Watson 		 * any errors.  Propagate the error from the child to the
8525e386598SRobert Watson 		 * parent if any problems arise.
8535e386598SRobert Watson 		 */
8545e386598SRobert Watson #ifdef HAVE_CAP_ENTER
8555e386598SRobert Watson 		childpid = fork();
8565e386598SRobert Watson 		if (childpid == 0) {
8575e386598SRobert Watson 			/* Child. */
8585e386598SRobert Watson 			retval = cap_enter();
8595e386598SRobert Watson 			if (retval != 0 && errno != ENOSYS)
8605e386598SRobert Watson 				errx(EXIT_FAILURE, "cap_enter");
8615e386598SRobert Watson 			if (select_records(fp) == -1)
8625e386598SRobert Watson 				errx(EXIT_FAILURE,
8635e386598SRobert Watson 				    "Couldn't select records %s", fname);
8645e386598SRobert Watson 			exit(0);
8655e386598SRobert Watson 		}
8665e386598SRobert Watson 
8675e386598SRobert Watson 		/* Parent.  Await child termination, check exit value. */
8685e386598SRobert Watson 		while ((pid = waitpid(childpid, &status, 0)) != childpid);
8695e386598SRobert Watson 		if (WEXITSTATUS(status) != 0)
8705e386598SRobert Watson 			exit(EXIT_FAILURE);
8715e386598SRobert Watson #else
8725e386598SRobert Watson 		if (select_records(fp) == -1)
873ca0716f5SRobert Watson 			errx(EXIT_FAILURE, "Couldn't select records %s",
874ca0716f5SRobert Watson 			    fname);
8755e386598SRobert Watson #endif
876ca0716f5SRobert Watson 		fclose(fp);
877ca0716f5SRobert Watson 	}
878ca0716f5SRobert Watson 	exit(EXIT_SUCCESS);
879ca0716f5SRobert Watson }
880