1ca0716f5SRobert Watson /*-
2ca0716f5SRobert Watson * Copyright (c) 2004-2008 Apple Inc.
3ca0716f5SRobert Watson * Copyright (c) 2016 Robert N. M. Watson
4ca0716f5SRobert Watson * All rights reserved.
5ca0716f5SRobert Watson *
6ca0716f5SRobert Watson * Portions of this software were developed by BAE Systems, the University of
7ca0716f5SRobert Watson * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
8ca0716f5SRobert Watson * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
9ca0716f5SRobert Watson * Computing (TC) research program.
10ca0716f5SRobert 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.
19ca0716f5SRobert 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
29eb336521SRobert 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
434bd0c025SRobert Watson * XXX We assume that records are sorted chronologically - both wrt to
444bd0c025SRobert Watson * XXX the records present within the file and between the files themselves
454bd0c025SRobert Watson */
464bd0c025SRobert Watson
474bd0c025SRobert Watson #include <config/config.h>
484bd0c025SRobert Watson
494bd0c025SRobert Watson #define _GNU_SOURCE /* Required for strptime() on glibc2. */
50ca0716f5SRobert Watson
51ca0716f5SRobert Watson #ifdef HAVE_FULL_QUEUE_H
52506764c6SRobert Watson #include <sys/queue.h>
53506764c6SRobert Watson #else
54506764c6SRobert Watson #include <compat/queue.h>
55ca0716f5SRobert Watson #endif
56ca0716f5SRobert Watson
57ca0716f5SRobert Watson #ifdef HAVE_CAP_ENTER
58ca0716f5SRobert Watson #include <sys/capsicum.h>
59ca0716f5SRobert Watson #include <sys/wait.h>
60ca0716f5SRobert Watson #endif
614bd0c025SRobert Watson
624bd0c025SRobert Watson #include <bsm/libbsm.h>
63ca0716f5SRobert Watson
64ca0716f5SRobert Watson #include <err.h>
65ca0716f5SRobert Watson #include <fnmatch.h>
664bd0c025SRobert Watson #include <grp.h>
674bd0c025SRobert Watson #include <pwd.h>
684bd0c025SRobert 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>
74ca0716f5SRobert Watson #include <regex.h>
75ca0716f5SRobert Watson #include <errno.h>
76ca0716f5SRobert Watson
77ca0716f5SRobert Watson #ifndef HAVE_STRLCPY
78ca0716f5SRobert Watson #include <compat/strlcpy.h>
79ca0716f5SRobert Watson #endif
80ca0716f5SRobert Watson
81ca0716f5SRobert Watson #include "auditreduce.h"
82ca0716f5SRobert Watson
83ca0716f5SRobert Watson static TAILQ_HEAD(tailhead, re_entry) re_head =
84ca0716f5SRobert Watson TAILQ_HEAD_INITIALIZER(re_head);
85ca0716f5SRobert 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. */
964bd0c025SRobert Watson static int p_ruid; /* Real user id. */
974bd0c025SRobert Watson static int p_subid; /* Subject id. */
984bd0c025SRobert Watson static const char *p_zone; /* Zone. */
994bd0c025SRobert Watson
1004bd0c025SRobert Watson /*
1014bd0c025SRobert Watson * Maintain a dynamically sized array of events for -m
1024bd0c025SRobert Watson */
1034bd0c025SRobert Watson static uint16_t *p_evec; /* Event type list */
1044bd0c025SRobert Watson static int p_evec_used; /* Number of events used */
1054bd0c025SRobert Watson static int p_evec_alloc; /* Number of events allocated */
1064bd0c025SRobert Watson
1074bd0c025SRobert Watson /*
1084bd0c025SRobert Watson * Following are the objects (-o option) that we can select upon.
1094bd0c025SRobert Watson */
1104bd0c025SRobert Watson static char *p_fileobj = NULL;
1114bd0c025SRobert Watson static char *p_msgqobj = NULL;
1124bd0c025SRobert Watson static char *p_pidobj = NULL;
1134bd0c025SRobert Watson static char *p_semobj = NULL;
1144bd0c025SRobert Watson static char *p_shmobj = NULL;
1154bd0c025SRobert Watson static char *p_sockobj = NULL;
1164bd0c025SRobert Watson
1174bd0c025SRobert Watson static uint32_t opttochk = 0;
1184bd0c025SRobert Watson
1194bd0c025SRobert Watson static int select_zone(const char *zone, uint32_t *optchkd);
1204bd0c025SRobert Watson
1214bd0c025SRobert 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] == '\\')
1344bd0c025SRobert Watson strlcpy(©[i - 1], ©[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++) {
143ca0716f5SRobert Watson rep = calloc(1, sizeof(*rep));
144ca0716f5SRobert Watson if (rep == NULL) {
145ca0716f5SRobert Watson (void) fprintf(stderr, "calloc: %s\n",
1464bd0c025SRobert Watson strerror(errno));
147ca0716f5SRobert Watson exit(1);
148ca0716f5SRobert Watson }
149ca0716f5SRobert Watson if (*copy == '~') {
150ca0716f5SRobert Watson copy++;
151ca0716f5SRobert Watson rep->re_negate = 1;
152ca0716f5SRobert Watson }
153ca0716f5SRobert Watson rep->re_pattern = strdup(copy);
154ca0716f5SRobert Watson error = regcomp(&rep->re_regexp, rep->re_pattern,
155ca0716f5SRobert Watson REG_EXTENDED | REG_NOSUB);
156ca0716f5SRobert Watson if (error != 0) {
157ca0716f5SRobert Watson regerror(error, &rep->re_regexp, re_error, 64);
158ca0716f5SRobert Watson (void) fprintf(stderr, "regcomp: %s\n", re_error);
159ca0716f5SRobert Watson exit(1);
160ca0716f5SRobert Watson }
161ca0716f5SRobert Watson TAILQ_INSERT_TAIL(&re_head, rep, re_glue);
162ca0716f5SRobert Watson len = strlen(copy);
163ca0716f5SRobert Watson copy += len + 1;
164ca0716f5SRobert Watson }
165ca0716f5SRobert Watson free(orig);
166ca0716f5SRobert Watson }
167ca0716f5SRobert Watson
168ca0716f5SRobert Watson static void
usage(const char * msg)169ca0716f5SRobert Watson usage(const char *msg)
170ca0716f5SRobert Watson {
171ca0716f5SRobert Watson fprintf(stderr, "%s\n", msg);
172ca0716f5SRobert 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");
192ca0716f5SRobert Watson fprintf(stderr, "\t-v : select non-matching records\n");
193ca0716f5SRobert Watson 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)) {
296ca0716f5SRobert 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)) {
313ca0716f5SRobert Watson if (id != (uint32_t)strtol(p_msgqobj, (char **)NULL,
314ca0716f5SRobert 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);
3204bd0c025SRobert Watson if (ISOPTSET(opttochk, OPT_ose)) {
3214bd0c025SRobert Watson if (id != (uint32_t)strtol(p_semobj, (char **)NULL, 10))
322ca0716f5SRobert Watson return (0);
323ca0716f5SRobert Watson }
3244bd0c025SRobert Watson return (1);
325ca0716f5SRobert Watson } else if (type == AT_IPC_SHM) {
3264bd0c025SRobert Watson SETOPT((*optchkd), OPT_osh);
3274bd0c025SRobert Watson if (ISOPTSET(opttochk, OPT_osh)) {
3284bd0c025SRobert Watson if (id != (uint32_t)strtol(p_shmobj, (char **)NULL, 10))
3294bd0c025SRobert Watson return (0);
3304bd0c025SRobert Watson }
331ca0716f5SRobert Watson return (1);
332ca0716f5SRobert Watson }
3334bd0c025SRobert 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 {
349ca0716f5SRobert Watson struct re_entry *rep;
350ca0716f5SRobert Watson int match;
351ca0716f5SRobert Watson
352ca0716f5SRobert Watson SETOPT((*optchkd), OPT_of);
353ca0716f5SRobert Watson match = 1;
354ca0716f5SRobert Watson if (ISOPTSET(opttochk, OPT_of)) {
355ca0716f5SRobert Watson match = 0;
356ca0716f5SRobert Watson TAILQ_FOREACH(rep, &re_head, re_glue) {
357ca0716f5SRobert Watson if (regexec(&rep->re_regexp, path, 0, NULL,
358ca0716f5SRobert Watson 0) != REG_NOMATCH)
359ca0716f5SRobert Watson return (!rep->re_negate);
360ca0716f5SRobert Watson }
361ca0716f5SRobert Watson }
362ca0716f5SRobert 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 {
377ca0716f5SRobert Watson uint16_t *ev;
378ca0716f5SRobert Watson int match;
379ca0716f5SRobert Watson
380ca0716f5SRobert 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. */
3874bd0c025SRobert Watson return (0);
3884bd0c025SRobert Watson }
3894bd0c025SRobert Watson }
3904bd0c025SRobert Watson
3914bd0c025SRobert Watson if (ISOPTSET(opttochk, OPT_b)) {
3924bd0c025SRobert Watson if (difftime(p_btime, (time_t)tok.tt.hdr32.s) < 0) {
3934bd0c025SRobert Watson /* Record was created after p_btime. */
3944bd0c025SRobert Watson return (0);
3954bd0c025SRobert Watson }
3964bd0c025SRobert Watson }
3974bd0c025SRobert Watson }
3984bd0c025SRobert Watson
3994bd0c025SRobert Watson if (ISOPTSET(opttochk, OPT_c)) {
4004bd0c025SRobert Watson /*
4014bd0c025SRobert Watson * Check if the classes represented by the event matches
4024bd0c025SRobert Watson * given class.
4034bd0c025SRobert Watson */
4044bd0c025SRobert 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)) {
411ca0716f5SRobert Watson match = 0;
412ca0716f5SRobert Watson for (ev = p_evec; ev < &p_evec[p_evec_used]; ev++)
413ca0716f5SRobert Watson if (tok.tt.hdr32.e_type == *ev)
414ca0716f5SRobert Watson match = 1;
415ca0716f5SRobert Watson if (match == 0)
416ca0716f5SRobert Watson return (0);
417ca0716f5SRobert Watson }
418ca0716f5SRobert Watson
419ca0716f5SRobert Watson return (1);
420ca0716f5SRobert Watson }
421ca0716f5SRobert Watson
422ca0716f5SRobert Watson static int
select_return32(tokenstr_t tok_ret32,tokenstr_t tok_hdr32,uint32_t * optchkd)423ca0716f5SRobert Watson select_return32(tokenstr_t tok_ret32, tokenstr_t tok_hdr32, uint32_t *optchkd)
424ca0716f5SRobert Watson {
425ca0716f5SRobert Watson int sorf;
426ca0716f5SRobert Watson
427ca0716f5SRobert Watson SETOPT((*optchkd), (OPT_c));
428ca0716f5SRobert Watson if (tok_ret32.tt.ret32.status == 0)
429ca0716f5SRobert Watson sorf = AU_PRS_SUCCESS;
430ca0716f5SRobert Watson else
431ca0716f5SRobert Watson sorf = AU_PRS_FAILURE;
432ca0716f5SRobert Watson if (ISOPTSET(opttochk, OPT_c)) {
433ca0716f5SRobert Watson if (au_preselect(tok_hdr32.tt.hdr32.e_type, &maskp, sorf,
434ca0716f5SRobert Watson AU_PRS_USECACHE) != 1)
435ca0716f5SRobert Watson return (0);
436ca0716f5SRobert Watson }
437ca0716f5SRobert Watson return (1);
438ca0716f5SRobert Watson }
439ca0716f5SRobert 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
4724bd0c025SRobert 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 /*
5014bd0c025SRobert Watson * Check if the given zone matches the selection criteria.
5024bd0c025SRobert Watson */
503ca0716f5SRobert Watson static int
select_zone(const char * zone,uint32_t * optchkd)504ca0716f5SRobert Watson select_zone(const char *zone, uint32_t *optchkd)
505ca0716f5SRobert Watson {
506ca0716f5SRobert Watson
507ca0716f5SRobert Watson SETOPT((*optchkd), OPT_z);
508ca0716f5SRobert Watson if (ISOPTSET(opttochk, OPT_z) && p_zone != NULL) {
509ca0716f5SRobert Watson if (fnmatch(p_zone, zone, FNM_PATHNAME) != 0)
510ca0716f5SRobert Watson return (0);
511ca0716f5SRobert Watson }
512ca0716f5SRobert Watson return (1);
513ca0716f5SRobert Watson }
514ca0716f5SRobert Watson
515ca0716f5SRobert Watson /*
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 {
522ca0716f5SRobert 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;
529ca0716f5SRobert Watson int print;
530ca0716f5SRobert Watson
5314bd0c025SRobert Watson int err = 0;
5324bd0c025SRobert Watson while ((reclen = au_read_rec(fp, &buf)) != -1) {
5334bd0c025SRobert Watson optchkd = 0;
5344bd0c025SRobert Watson bytesread = 0;
5354bd0c025SRobert 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) {
549ca0716f5SRobert Watson case AUT_HEADER32:
550ca0716f5SRobert Watson selected = select_hdr32(tok,
551ca0716f5SRobert Watson &optchkd);
552ca0716f5SRobert Watson bcopy(&tok, &tok_hdr32_copy,
553ca0716f5SRobert Watson sizeof(tok));
554ca0716f5SRobert Watson break;
555ca0716f5SRobert Watson
556ca0716f5SRobert Watson case AUT_PROCESS32:
557ca0716f5SRobert Watson selected = select_proc32(tok,
558ca0716f5SRobert Watson &optchkd);
559ca0716f5SRobert Watson break;
560ca0716f5SRobert Watson
561ca0716f5SRobert Watson case AUT_SUBJECT32:
562ca0716f5SRobert Watson selected = select_subj32(tok,
563ca0716f5SRobert Watson &optchkd);
564ca0716f5SRobert Watson break;
565ca0716f5SRobert Watson
566ca0716f5SRobert 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
572ca0716f5SRobert Watson case AUT_PATH:
573ca0716f5SRobert Watson selected = select_filepath(
574ca0716f5SRobert Watson tok.tt.path.path, &optchkd);
575ca0716f5SRobert Watson break;
576ca0716f5SRobert Watson
577ca0716f5SRobert Watson case AUT_RETURN32:
578ca0716f5SRobert Watson selected = select_return32(tok,
579ca0716f5SRobert Watson tok_hdr32_copy, &optchkd);
580ca0716f5SRobert Watson break;
581ca0716f5SRobert Watson
582ca0716f5SRobert Watson case AUT_ZONENAME:
583ca0716f5SRobert Watson selected = select_zone(tok.tt.zonename.zonename, &optchkd);
5844bd0c025SRobert Watson break;
585ca0716f5SRobert Watson
586ca0716f5SRobert Watson default:
587ca0716f5SRobert Watson break;
588ca0716f5SRobert Watson }
589ca0716f5SRobert Watson bytesread += tok.len;
590ca0716f5SRobert Watson }
591ca0716f5SRobert Watson /* Check if all the options were matched. */
592ca0716f5SRobert Watson print = ((selected == 1) && (!err) && (!(opttochk & ~optchkd)));
593ca0716f5SRobert Watson if (ISOPTSET(opttochk, OPT_v))
594ca0716f5SRobert Watson print = !print;
595ca0716f5SRobert Watson if (print)
596ca0716f5SRobert 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 */
606ca0716f5SRobert 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;
614ca0716f5SRobert Watson parse_regexp(val);
61523bf6e20SRobert 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
6320814440eSRobert 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;
6450814440eSRobert Watson int ch;
646ca0716f5SRobert Watson char timestr[128];
647ca0716f5SRobert Watson char *fname;
648ca0716f5SRobert Watson uint16_t *etp;
649ca0716f5SRobert Watson #ifdef HAVE_CAP_ENTER
650ca0716f5SRobert Watson int retval, status;
651ca0716f5SRobert Watson pid_t childpid, pid;
652ca0716f5SRobert Watson #endif
653ca0716f5SRobert Watson
654ca0716f5SRobert Watson converr = NULL;
655ca0716f5SRobert Watson
656ca0716f5SRobert Watson 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 }
6660814440eSRobert Watson SETOPT(opttochk, OPT_a);
667ca0716f5SRobert 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);
680ca0716f5SRobert 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);
701ca0716f5SRobert 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':
753ca0716f5SRobert Watson if (p_evec == NULL) {
754ca0716f5SRobert Watson p_evec_alloc = 32;
755ca0716f5SRobert Watson p_evec = malloc(sizeof(*etp) * p_evec_alloc);
756ca0716f5SRobert Watson if (p_evec == NULL)
757ca0716f5SRobert Watson err(1, "malloc");
758ca0716f5SRobert Watson } else if (p_evec_alloc == p_evec_used) {
759ca0716f5SRobert Watson p_evec_alloc <<= 1;
760ca0716f5SRobert Watson p_evec = realloc(p_evec,
761ca0716f5SRobert Watson sizeof(*p_evec) * p_evec_alloc);
762ca0716f5SRobert Watson if (p_evec == NULL)
763ca0716f5SRobert Watson err(1, "realloc");
764ca0716f5SRobert Watson }
765ca0716f5SRobert Watson etp = &p_evec[p_evec_used++];
7664bd0c025SRobert Watson *etp = strtol(optarg, (char **)NULL, 10);
7674bd0c025SRobert Watson if (*etp == 0) {
7684bd0c025SRobert Watson /* Could be the string representation. */
7694bd0c025SRobert Watson n = getauevnonam(optarg);
7704bd0c025SRobert Watson if (n == NULL)
7714bd0c025SRobert Watson usage("Incorrect event name");
772ca0716f5SRobert 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') {
789 if ((pw = getpwnam(optarg)) == NULL)
790 break;
791 p_ruid = pw->pw_uid;
792 }
793 SETOPT(opttochk, OPT_r);
794 break;
795
796 case 'u':
797 p_auid = strtol(optarg, &converr, 10);
798 if (*converr != '\0') {
799 if ((pw = getpwnam(optarg)) == NULL)
800 break;
801 p_auid = pw->pw_uid;
802 }
803 SETOPT(opttochk, OPT_u);
804 break;
805
806 case 'v':
807 SETOPT(opttochk, OPT_v);
808 break;
809
810 case 'z':
811 p_zone = optarg;
812 SETOPT(opttochk, OPT_z);
813 break;
814
815 case '?':
816 default:
817 usage("Unknown option");
818 }
819 }
820 argv += optind;
821 argc -= optind;
822
823 if (argc == 0) {
824 #ifdef HAVE_CAP_ENTER
825 retval = cap_enter();
826 if (retval != 0 && errno != ENOSYS)
827 err(EXIT_FAILURE, "cap_enter");
828 #endif
829 if (select_records(stdin) == -1)
830 errx(EXIT_FAILURE,
831 "Couldn't select records from stdin");
832 exit(EXIT_SUCCESS);
833 }
834
835 /*
836 * XXX: We should actually be merging records here.
837 */
838 for (i = 0; i < argc; i++) {
839 fname = argv[i];
840 fp = fopen(fname, "r");
841 if (fp == NULL)
842 errx(EXIT_FAILURE, "Couldn't open %s", fname);
843
844 /*
845 * If operating with sandboxing, create a sandbox process for
846 * each trail file we operate on. This avoids the need to do
847 * fancy things with file descriptors, etc, when iterating on
848 * a list of arguments.
849 *
850 * NB: Unlike praudit(1), auditreduce(1) terminates if it hits
851 * any errors. Propagate the error from the child to the
852 * parent if any problems arise.
853 */
854 #ifdef HAVE_CAP_ENTER
855 childpid = fork();
856 if (childpid == 0) {
857 /* Child. */
858 retval = cap_enter();
859 if (retval != 0 && errno != ENOSYS)
860 errx(EXIT_FAILURE, "cap_enter");
861 if (select_records(fp) == -1)
862 errx(EXIT_FAILURE,
863 "Couldn't select records %s", fname);
864 exit(0);
865 }
866
867 /* Parent. Await child termination, check exit value. */
868 while ((pid = waitpid(childpid, &status, 0)) != childpid);
869 if (WEXITSTATUS(status) != 0)
870 exit(EXIT_FAILURE);
871 #else
872 if (select_records(fp) == -1)
873 errx(EXIT_FAILURE, "Couldn't select records %s",
874 fname);
875 #endif
876 fclose(fp);
877 }
878 exit(EXIT_SUCCESS);
879 }
880