1185573Srwatson/*- 2185573Srwatson * Copyright (c) 2004-2008 Apple Inc. 3155131Srwatson * All rights reserved. 4155131Srwatson * 5155131Srwatson * Redistribution and use in source and binary forms, with or without 6155131Srwatson * modification, are permitted provided that the following conditions 7155131Srwatson * are met: 8155131Srwatson * 1. Redistributions of source code must retain the above copyright 9155131Srwatson * notice, this list of conditions and the following disclaimer. 10155131Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11155131Srwatson * notice, this list of conditions and the following disclaimer in the 12155131Srwatson * documentation and/or other materials provided with the distribution. 13185573Srwatson * 3. Neither the name of Apple Inc. ("Apple") nor the names of 14155131Srwatson * its contributors may be used to endorse or promote products derived 15155131Srwatson * from this software without specific prior written permission. 16155131Srwatson * 17155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 18155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 21155131Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25155131Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 26155131Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27155131Srwatson * POSSIBILITY OF SUCH DAMAGE. 28155131Srwatson * 29187214Srwatson * $P4: //depot/projects/trustedbsd/openbsm/bin/auditreduce/auditreduce.c#31 $ 30155131Srwatson */ 31155131Srwatson 32155131Srwatson/* 33155131Srwatson * Tool used to merge and select audit records from audit trail files 34155131Srwatson */ 35155131Srwatson 36155131Srwatson/* 37155131Srwatson * XXX Currently we do not support merging of records from multiple 38155131Srwatson * XXX audit trail files 39155131Srwatson * XXX We assume that records are sorted chronologically - both wrt to 40155131Srwatson * XXX the records present within the file and between the files themselves 41155131Srwatson */ 42155131Srwatson 43162621Srwatson#include <config/config.h> 44187214Srwatson 45187214Srwatson#define _GNU_SOURCE /* Required for strptime() on glibc2. */ 46187214Srwatson 47162621Srwatson#ifdef HAVE_FULL_QUEUE_H 48162621Srwatson#include <sys/queue.h> 49162621Srwatson#else 50162621Srwatson#include <compat/queue.h> 51162621Srwatson#endif 52162621Srwatson 53155131Srwatson#include <bsm/libbsm.h> 54155131Srwatson 55159248Srwatson#include <err.h> 56159248Srwatson#include <grp.h> 57159248Srwatson#include <pwd.h> 58155131Srwatson#include <stdio.h> 59155131Srwatson#include <stdlib.h> 60155131Srwatson#include <sysexits.h> 61155131Srwatson#include <string.h> 62155131Srwatson#include <time.h> 63155131Srwatson#include <unistd.h> 64162621Srwatson#include <regex.h> 65162621Srwatson#include <errno.h> 66155131Srwatson 67185573Srwatson#ifndef HAVE_STRLCPY 68185573Srwatson#include <compat/strlcpy.h> 69185573Srwatson#endif 70185573Srwatson 71155131Srwatson#include "auditreduce.h" 72155131Srwatson 73162621Srwatsonstatic TAILQ_HEAD(tailhead, re_entry) re_head = 74162621Srwatson TAILQ_HEAD_INITIALIZER(re_head); 75162621Srwatson 76155131Srwatsonextern char *optarg; 77155131Srwatsonextern int optind, optopt, opterr,optreset; 78155131Srwatson 79155131Srwatsonstatic au_mask_t maskp; /* Class. */ 80155131Srwatsonstatic time_t p_atime; /* Created after this time. */ 81155131Srwatsonstatic time_t p_btime; /* Created before this time. */ 82155131Srwatsonstatic int p_auid; /* Audit id. */ 83155131Srwatsonstatic int p_euid; /* Effective user id. */ 84155131Srwatsonstatic int p_egid; /* Effective group id. */ 85155131Srwatsonstatic int p_rgid; /* Real group id. */ 86155131Srwatsonstatic int p_ruid; /* Real user id. */ 87155131Srwatsonstatic int p_subid; /* Subject id. */ 88155131Srwatson 89155131Srwatson/* 90185573Srwatson * Maintain a dynamically sized array of events for -m 91185573Srwatson */ 92185573Srwatsonstatic uint16_t *p_evec; /* Event type list */ 93185573Srwatsonstatic int p_evec_used; /* Number of events used */ 94185573Srwatsonstatic int p_evec_alloc; /* Number of events allocated */ 95185573Srwatson 96185573Srwatson/* 97155131Srwatson * Following are the objects (-o option) that we can select upon. 98155131Srwatson */ 99155131Srwatsonstatic char *p_fileobj = NULL; 100155131Srwatsonstatic char *p_msgqobj = NULL; 101155131Srwatsonstatic char *p_pidobj = NULL; 102155131Srwatsonstatic char *p_semobj = NULL; 103155131Srwatsonstatic char *p_shmobj = NULL; 104155131Srwatsonstatic char *p_sockobj = NULL; 105155131Srwatson 106155131Srwatsonstatic uint32_t opttochk = 0; 107155131Srwatson 108155131Srwatsonstatic void 109162621Srwatsonparse_regexp(char *re_string) 110162621Srwatson{ 111162621Srwatson char *orig, *copy, re_error[64]; 112162621Srwatson struct re_entry *rep; 113162621Srwatson int error, nstrs, i, len; 114162621Srwatson 115162621Srwatson copy = strdup(re_string); 116162621Srwatson orig = copy; 117162621Srwatson len = strlen(copy); 118162621Srwatson for (nstrs = 0, i = 0; i < len; i++) { 119162621Srwatson if (copy[i] == ',' && i > 0) { 120162621Srwatson if (copy[i - 1] == '\\') 121185573Srwatson strlcpy(©[i - 1], ©[i], len); 122162621Srwatson else { 123162621Srwatson nstrs++; 124162621Srwatson copy[i] = '\0'; 125162621Srwatson } 126162621Srwatson } 127162621Srwatson } 128162621Srwatson TAILQ_INIT(&re_head); 129162621Srwatson for (i = 0; i < nstrs + 1; i++) { 130162621Srwatson rep = calloc(1, sizeof(*rep)); 131162621Srwatson if (rep == NULL) { 132162621Srwatson (void) fprintf(stderr, "calloc: %s\n", 133162621Srwatson strerror(errno)); 134162621Srwatson exit(1); 135162621Srwatson } 136162621Srwatson if (*copy == '~') { 137162621Srwatson copy++; 138162621Srwatson rep->re_negate = 1; 139162621Srwatson } 140162621Srwatson rep->re_pattern = strdup(copy); 141162621Srwatson error = regcomp(&rep->re_regexp, rep->re_pattern, 142162621Srwatson REG_EXTENDED | REG_NOSUB); 143162621Srwatson if (error != 0) { 144162621Srwatson regerror(error, &rep->re_regexp, re_error, 64); 145162621Srwatson (void) fprintf(stderr, "regcomp: %s\n", re_error); 146162621Srwatson exit(1); 147162621Srwatson } 148162621Srwatson TAILQ_INSERT_TAIL(&re_head, rep, re_glue); 149162621Srwatson len = strlen(copy); 150162621Srwatson copy += len + 1; 151162621Srwatson } 152162621Srwatson free(orig); 153162621Srwatson} 154162621Srwatson 155162621Srwatsonstatic void 156155131Srwatsonusage(const char *msg) 157155131Srwatson{ 158155131Srwatson fprintf(stderr, "%s\n", msg); 159162621Srwatson fprintf(stderr, "Usage: auditreduce [options] [file ...]\n"); 160155131Srwatson fprintf(stderr, "\tOptions are : \n"); 161155131Srwatson fprintf(stderr, "\t-A : all records\n"); 162155131Srwatson fprintf(stderr, "\t-a YYYYMMDD[HH[[MM[SS]]] : after date\n"); 163155131Srwatson fprintf(stderr, "\t-b YYYYMMDD[HH[[MM[SS]]] : before date\n"); 164155131Srwatson fprintf(stderr, "\t-c <flags> : matching class\n"); 165155131Srwatson fprintf(stderr, "\t-d YYYYMMDD : on date\n"); 166155131Srwatson fprintf(stderr, "\t-e <uid|name> : effective user\n"); 167155131Srwatson fprintf(stderr, "\t-f <gid|group> : effective group\n"); 168155131Srwatson fprintf(stderr, "\t-g <gid|group> : real group\n"); 169155131Srwatson fprintf(stderr, "\t-j <pid> : subject id \n"); 170155131Srwatson fprintf(stderr, "\t-m <evno|evname> : matching event\n"); 171155131Srwatson fprintf(stderr, "\t-o objecttype=objectvalue\n"); 172155131Srwatson fprintf(stderr, "\t\t file=<pathname>\n"); 173155131Srwatson fprintf(stderr, "\t\t msgqid=<ID>\n"); 174155131Srwatson fprintf(stderr, "\t\t pid=<ID>\n"); 175155131Srwatson fprintf(stderr, "\t\t semid=<ID>\n"); 176155131Srwatson fprintf(stderr, "\t\t shmid=<ID>\n"); 177155131Srwatson fprintf(stderr, "\t-r <uid|name> : real user\n"); 178155131Srwatson fprintf(stderr, "\t-u <uid|name> : audit user\n"); 179185573Srwatson fprintf(stderr, "\t-v : select non-matching records\n"); 180155131Srwatson exit(EX_USAGE); 181155131Srwatson} 182155131Srwatson 183155131Srwatson/* 184155131Srwatson * Check if the given auid matches the selection criteria. 185155131Srwatson */ 186155131Srwatsonstatic int 187155131Srwatsonselect_auid(int au) 188155131Srwatson{ 189155131Srwatson 190155131Srwatson /* Check if we want to select on auid. */ 191155131Srwatson if (ISOPTSET(opttochk, OPT_u)) { 192155131Srwatson if (au != p_auid) 193155131Srwatson return (0); 194155131Srwatson } 195155131Srwatson return (1); 196155131Srwatson} 197155131Srwatson 198155131Srwatson/* 199155131Srwatson * Check if the given euid matches the selection criteria. 200155131Srwatson */ 201155131Srwatsonstatic int 202155131Srwatsonselect_euid(int euser) 203155131Srwatson{ 204155131Srwatson 205155131Srwatson /* Check if we want to select on euid. */ 206155131Srwatson if (ISOPTSET(opttochk, OPT_e)) { 207155131Srwatson if (euser != p_euid) 208155131Srwatson return (0); 209155131Srwatson } 210155131Srwatson return (1); 211155131Srwatson} 212155131Srwatson 213155131Srwatson/* 214155131Srwatson * Check if the given egid matches the selection criteria. 215155131Srwatson */ 216155131Srwatsonstatic int 217155131Srwatsonselect_egid(int egrp) 218155131Srwatson{ 219155131Srwatson 220155131Srwatson /* Check if we want to select on egid. */ 221155131Srwatson if (ISOPTSET(opttochk, OPT_f)) { 222155131Srwatson if (egrp != p_egid) 223155131Srwatson return (0); 224155131Srwatson } 225155131Srwatson return (1); 226155131Srwatson} 227155131Srwatson 228155131Srwatson/* 229155131Srwatson * Check if the given rgid matches the selection criteria. 230155131Srwatson */ 231155131Srwatsonstatic int 232155131Srwatsonselect_rgid(int grp) 233155131Srwatson{ 234155131Srwatson 235155131Srwatson /* Check if we want to select on rgid. */ 236155131Srwatson if (ISOPTSET(opttochk, OPT_g)) { 237155131Srwatson if (grp != p_rgid) 238155131Srwatson return (0); 239155131Srwatson } 240155131Srwatson return (1); 241155131Srwatson} 242155131Srwatson 243155131Srwatson/* 244155131Srwatson * Check if the given ruid matches the selection criteria. 245155131Srwatson */ 246155131Srwatsonstatic int 247155131Srwatsonselect_ruid(int user) 248155131Srwatson{ 249155131Srwatson 250155131Srwatson /* Check if we want to select on rgid. */ 251155131Srwatson if (ISOPTSET(opttochk, OPT_r)) { 252155131Srwatson if (user != p_ruid) 253155131Srwatson return (0); 254155131Srwatson } 255155131Srwatson return (1); 256155131Srwatson} 257155131Srwatson 258155131Srwatson/* 259155131Srwatson * Check if the given subject id (pid) matches the selection criteria. 260155131Srwatson */ 261155131Srwatsonstatic int 262155131Srwatsonselect_subid(int subid) 263155131Srwatson{ 264155131Srwatson 265155131Srwatson /* Check if we want to select on subject uid. */ 266155131Srwatson if (ISOPTSET(opttochk, OPT_j)) { 267155131Srwatson if (subid != p_subid) 268155131Srwatson return (0); 269155131Srwatson } 270155131Srwatson return (1); 271155131Srwatson} 272155131Srwatson 273155131Srwatson 274155131Srwatson/* 275155131Srwatson * Check if object's pid maches the given pid. 276155131Srwatson */ 277155131Srwatsonstatic int 278155131Srwatsonselect_pidobj(uint32_t pid) 279155131Srwatson{ 280155131Srwatson 281155131Srwatson if (ISOPTSET(opttochk, OPT_op)) { 282185573Srwatson if (pid != (uint32_t)strtol(p_pidobj, (char **)NULL, 10)) 283155131Srwatson return (0); 284155131Srwatson } 285155131Srwatson return (1); 286155131Srwatson} 287155131Srwatson 288155131Srwatson/* 289155131Srwatson * Check if the given ipc object with the given type matches the selection 290155131Srwatson * criteria. 291155131Srwatson */ 292155131Srwatsonstatic int 293155131Srwatsonselect_ipcobj(u_char type, uint32_t id, uint32_t *optchkd) 294155131Srwatson{ 295155131Srwatson 296155131Srwatson if (type == AT_IPC_MSG) { 297155131Srwatson SETOPT((*optchkd), OPT_om); 298155131Srwatson if (ISOPTSET(opttochk, OPT_om)) { 299185573Srwatson if (id != (uint32_t)strtol(p_msgqobj, (char **)NULL, 300185573Srwatson 10)) 301155131Srwatson return (0); 302155131Srwatson } 303155131Srwatson return (1); 304155131Srwatson } else if (type == AT_IPC_SEM) { 305155131Srwatson SETOPT((*optchkd), OPT_ose); 306155131Srwatson if (ISOPTSET(opttochk, OPT_ose)) { 307185573Srwatson if (id != (uint32_t)strtol(p_semobj, (char **)NULL, 10)) 308155131Srwatson return (0); 309155131Srwatson } 310155131Srwatson return (1); 311155131Srwatson } else if (type == AT_IPC_SHM) { 312155131Srwatson SETOPT((*optchkd), OPT_osh); 313155131Srwatson if (ISOPTSET(opttochk, OPT_osh)) { 314185573Srwatson if (id != (uint32_t)strtol(p_shmobj, (char **)NULL, 10)) 315155131Srwatson return (0); 316155131Srwatson } 317155131Srwatson return (1); 318155131Srwatson } 319155131Srwatson 320155131Srwatson /* Unknown type -- filter if *any* ipc filtering is required. */ 321155131Srwatson if (ISOPTSET(opttochk, OPT_om) || ISOPTSET(opttochk, OPT_ose) 322155131Srwatson || ISOPTSET(opttochk, OPT_osh)) 323155131Srwatson return (0); 324155131Srwatson 325155131Srwatson return (1); 326155131Srwatson} 327155131Srwatson 328155131Srwatson 329155131Srwatson/* 330155131Srwatson * Check if the file name matches selection criteria. 331155131Srwatson */ 332155131Srwatsonstatic int 333155131Srwatsonselect_filepath(char *path, uint32_t *optchkd) 334155131Srwatson{ 335162621Srwatson struct re_entry *rep; 336162621Srwatson int match; 337155131Srwatson 338155131Srwatson SETOPT((*optchkd), OPT_of); 339162621Srwatson match = 1; 340155131Srwatson if (ISOPTSET(opttochk, OPT_of)) { 341162621Srwatson match = 0; 342162621Srwatson TAILQ_FOREACH(rep, &re_head, re_glue) { 343162621Srwatson if (regexec(&rep->re_regexp, path, 0, NULL, 344162621Srwatson 0) != REG_NOMATCH) 345162621Srwatson return (!rep->re_negate); 346155131Srwatson } 347155131Srwatson } 348162621Srwatson return (match); 349155131Srwatson} 350155131Srwatson 351155131Srwatson/* 352155131Srwatson * Returns 1 if the following pass the selection rules: 353155131Srwatson * 354155131Srwatson * before-time, 355155131Srwatson * after time, 356155131Srwatson * date, 357155131Srwatson * class, 358155131Srwatson * event 359155131Srwatson */ 360155131Srwatsonstatic int 361155131Srwatsonselect_hdr32(tokenstr_t tok, uint32_t *optchkd) 362155131Srwatson{ 363185573Srwatson uint16_t *ev; 364185573Srwatson int match; 365155131Srwatson 366185573Srwatson SETOPT((*optchkd), (OPT_A | OPT_a | OPT_b | OPT_c | OPT_m | OPT_v)); 367155131Srwatson 368155131Srwatson /* The A option overrides a, b and d. */ 369155131Srwatson if (!ISOPTSET(opttochk, OPT_A)) { 370155131Srwatson if (ISOPTSET(opttochk, OPT_a)) { 371155131Srwatson if (difftime((time_t)tok.tt.hdr32.s, p_atime) < 0) { 372155131Srwatson /* Record was created before p_atime. */ 373155131Srwatson return (0); 374155131Srwatson } 375155131Srwatson } 376155131Srwatson 377155131Srwatson if (ISOPTSET(opttochk, OPT_b)) { 378155131Srwatson if (difftime(p_btime, (time_t)tok.tt.hdr32.s) < 0) { 379155131Srwatson /* Record was created after p_btime. */ 380155131Srwatson return (0); 381155131Srwatson } 382155131Srwatson } 383155131Srwatson } 384155131Srwatson 385155131Srwatson if (ISOPTSET(opttochk, OPT_c)) { 386155131Srwatson /* 387155131Srwatson * Check if the classes represented by the event matches 388155131Srwatson * given class. 389155131Srwatson */ 390155131Srwatson if (au_preselect(tok.tt.hdr32.e_type, &maskp, AU_PRS_BOTH, 391155131Srwatson AU_PRS_USECACHE) != 1) 392155131Srwatson return (0); 393155131Srwatson } 394155131Srwatson 395155131Srwatson /* Check if event matches. */ 396155131Srwatson if (ISOPTSET(opttochk, OPT_m)) { 397185573Srwatson match = 0; 398185573Srwatson for (ev = p_evec; ev < &p_evec[p_evec_used]; ev++) 399185573Srwatson if (tok.tt.hdr32.e_type == *ev) 400185573Srwatson match = 1; 401185573Srwatson if (match == 0) 402155131Srwatson return (0); 403155131Srwatson } 404155131Srwatson 405155131Srwatson return (1); 406155131Srwatson} 407155131Srwatson 408162621Srwatsonstatic int 409162621Srwatsonselect_return32(tokenstr_t tok_ret32, tokenstr_t tok_hdr32, uint32_t *optchkd) 410162621Srwatson{ 411162621Srwatson int sorf; 412162621Srwatson 413162621Srwatson SETOPT((*optchkd), (OPT_c)); 414162621Srwatson if (tok_ret32.tt.ret32.status == 0) 415162621Srwatson sorf = AU_PRS_SUCCESS; 416162621Srwatson else 417162621Srwatson sorf = AU_PRS_FAILURE; 418162621Srwatson if (ISOPTSET(opttochk, OPT_c)) { 419162621Srwatson if (au_preselect(tok_hdr32.tt.hdr32.e_type, &maskp, sorf, 420162621Srwatson AU_PRS_USECACHE) != 1) 421162621Srwatson return (0); 422162621Srwatson } 423162621Srwatson return (1); 424162621Srwatson} 425162621Srwatson 426155131Srwatson/* 427155131Srwatson * Return 1 if checks for the the following succeed 428155131Srwatson * auid, 429155131Srwatson * euid, 430155131Srwatson * egid, 431155131Srwatson * rgid, 432155131Srwatson * ruid, 433155131Srwatson * process id 434155131Srwatson */ 435155131Srwatsonstatic int 436155131Srwatsonselect_proc32(tokenstr_t tok, uint32_t *optchkd) 437155131Srwatson{ 438155131Srwatson 439155131Srwatson SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_op)); 440155131Srwatson 441155131Srwatson if (!select_auid(tok.tt.proc32.auid)) 442155131Srwatson return (0); 443155131Srwatson if (!select_euid(tok.tt.proc32.euid)) 444155131Srwatson return (0); 445155131Srwatson if (!select_egid(tok.tt.proc32.egid)) 446155131Srwatson return (0); 447155131Srwatson if (!select_rgid(tok.tt.proc32.rgid)) 448155131Srwatson return (0); 449155131Srwatson if (!select_ruid(tok.tt.proc32.ruid)) 450155131Srwatson return (0); 451155131Srwatson if (!select_pidobj(tok.tt.proc32.pid)) 452155131Srwatson return (0); 453155131Srwatson return (1); 454155131Srwatson} 455155131Srwatson 456155131Srwatson/* 457155131Srwatson * Return 1 if checks for the the following succeed 458155131Srwatson * auid, 459155131Srwatson * euid, 460155131Srwatson * egid, 461155131Srwatson * rgid, 462155131Srwatson * ruid, 463155131Srwatson * subject id 464155131Srwatson */ 465155131Srwatsonstatic int 466155131Srwatsonselect_subj32(tokenstr_t tok, uint32_t *optchkd) 467155131Srwatson{ 468155131Srwatson 469155131Srwatson SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_j)); 470155131Srwatson 471155131Srwatson if (!select_auid(tok.tt.subj32.auid)) 472155131Srwatson return (0); 473155131Srwatson if (!select_euid(tok.tt.subj32.euid)) 474155131Srwatson return (0); 475155131Srwatson if (!select_egid(tok.tt.subj32.egid)) 476155131Srwatson return (0); 477155131Srwatson if (!select_rgid(tok.tt.subj32.rgid)) 478155131Srwatson return (0); 479155131Srwatson if (!select_ruid(tok.tt.subj32.ruid)) 480155131Srwatson return (0); 481155131Srwatson if (!select_subid(tok.tt.subj32.pid)) 482155131Srwatson return (0); 483155131Srwatson return (1); 484155131Srwatson} 485155131Srwatson 486155131Srwatson/* 487155131Srwatson * Read each record from the audit trail. Check if it is selected after 488155131Srwatson * passing through each of the options 489155131Srwatson */ 490155131Srwatsonstatic int 491155131Srwatsonselect_records(FILE *fp) 492155131Srwatson{ 493162621Srwatson tokenstr_t tok_hdr32_copy; 494155131Srwatson u_char *buf; 495155131Srwatson tokenstr_t tok; 496155131Srwatson int reclen; 497155131Srwatson int bytesread; 498155131Srwatson int selected; 499155131Srwatson uint32_t optchkd; 500185573Srwatson int print; 501155131Srwatson 502155131Srwatson int err = 0; 503155131Srwatson while ((reclen = au_read_rec(fp, &buf)) != -1) { 504155131Srwatson optchkd = 0; 505155131Srwatson bytesread = 0; 506155131Srwatson selected = 1; 507155131Srwatson while ((selected == 1) && (bytesread < reclen)) { 508155131Srwatson if (-1 == au_fetch_tok(&tok, buf + bytesread, 509155131Srwatson reclen - bytesread)) { 510155131Srwatson /* Is this an incomplete record? */ 511155131Srwatson err = 1; 512155131Srwatson break; 513155131Srwatson } 514155131Srwatson 515155131Srwatson /* 516155131Srwatson * For each token type we have have different 517155131Srwatson * selection criteria. 518155131Srwatson */ 519155131Srwatson switch(tok.id) { 520185573Srwatson case AUT_HEADER32: 521155131Srwatson selected = select_hdr32(tok, 522155131Srwatson &optchkd); 523162621Srwatson bcopy(&tok, &tok_hdr32_copy, 524162621Srwatson sizeof(tok)); 525155131Srwatson break; 526155131Srwatson 527185573Srwatson case AUT_PROCESS32: 528155131Srwatson selected = select_proc32(tok, 529155131Srwatson &optchkd); 530155131Srwatson break; 531155131Srwatson 532185573Srwatson case AUT_SUBJECT32: 533155131Srwatson selected = select_subj32(tok, 534155131Srwatson &optchkd); 535155131Srwatson break; 536155131Srwatson 537185573Srwatson case AUT_IPC: 538155131Srwatson selected = select_ipcobj( 539155131Srwatson tok.tt.ipc.type, tok.tt.ipc.id, 540155131Srwatson &optchkd); 541155131Srwatson break; 542155131Srwatson 543185573Srwatson case AUT_PATH: 544155131Srwatson selected = select_filepath( 545155131Srwatson tok.tt.path.path, &optchkd); 546155131Srwatson break; 547155131Srwatson 548185573Srwatson case AUT_RETURN32: 549162621Srwatson selected = select_return32(tok, 550162621Srwatson tok_hdr32_copy, &optchkd); 551162621Srwatson break; 552162621Srwatson 553155131Srwatson default: 554155131Srwatson break; 555155131Srwatson } 556155131Srwatson bytesread += tok.len; 557155131Srwatson } 558185573Srwatson /* Check if all the options were matched. */ 559185573Srwatson print = ((selected == 1) && (!err) && (!(opttochk & ~optchkd))); 560185573Srwatson if (ISOPTSET(opttochk, OPT_v)) 561185573Srwatson print = !print; 562185573Srwatson if (print) 563185573Srwatson (void) fwrite(buf, 1, reclen, stdout); 564155131Srwatson free(buf); 565155131Srwatson } 566155131Srwatson return (0); 567155131Srwatson} 568155131Srwatson 569155131Srwatson/* 570155131Srwatson * The -o option has the form object_type=object_value. Identify the object 571155131Srwatson * components. 572155131Srwatson */ 573186647Srwatsonstatic void 574155131Srwatsonparse_object_type(char *name, char *val) 575155131Srwatson{ 576155131Srwatson if (val == NULL) 577155131Srwatson return; 578155131Srwatson 579155131Srwatson if (!strcmp(name, FILEOBJ)) { 580155131Srwatson p_fileobj = val; 581162621Srwatson parse_regexp(val); 582155131Srwatson SETOPT(opttochk, OPT_of); 583155131Srwatson } else if (!strcmp(name, MSGQIDOBJ)) { 584155131Srwatson p_msgqobj = val; 585155131Srwatson SETOPT(opttochk, OPT_om); 586155131Srwatson } else if (!strcmp(name, PIDOBJ)) { 587155131Srwatson p_pidobj = val; 588155131Srwatson SETOPT(opttochk, OPT_op); 589155131Srwatson } else if (!strcmp(name, SEMIDOBJ)) { 590155131Srwatson p_semobj = val; 591155131Srwatson SETOPT(opttochk, OPT_ose); 592155131Srwatson } else if (!strcmp(name, SHMIDOBJ)) { 593155131Srwatson p_shmobj = val; 594155131Srwatson SETOPT(opttochk, OPT_osh); 595155131Srwatson } else if (!strcmp(name, SOCKOBJ)) { 596155131Srwatson p_sockobj = val; 597155131Srwatson SETOPT(opttochk, OPT_oso); 598155131Srwatson } else 599155131Srwatson usage("unknown value for -o"); 600155131Srwatson} 601155131Srwatson 602155131Srwatsonint 603155131Srwatsonmain(int argc, char **argv) 604155131Srwatson{ 605155131Srwatson struct group *grp; 606155131Srwatson struct passwd *pw; 607155131Srwatson struct tm tm; 608155131Srwatson au_event_t *n; 609155131Srwatson FILE *fp; 610155131Srwatson int i; 611155131Srwatson char *objval, *converr; 612155364Srwatson int ch; 613155131Srwatson char timestr[128]; 614155131Srwatson char *fname; 615185573Srwatson uint16_t *etp; 616155131Srwatson 617155131Srwatson converr = NULL; 618155131Srwatson 619185573Srwatson while ((ch = getopt(argc, argv, "Aa:b:c:d:e:f:g:j:m:o:r:u:v")) != -1) { 620155131Srwatson switch(ch) { 621155131Srwatson case 'A': 622155131Srwatson SETOPT(opttochk, OPT_A); 623155131Srwatson break; 624155131Srwatson 625155131Srwatson case 'a': 626155131Srwatson if (ISOPTSET(opttochk, OPT_a)) { 627155131Srwatson usage("d is exclusive with a and b"); 628155131Srwatson } 629155131Srwatson SETOPT(opttochk, OPT_a); 630171537Srwatson bzero(&tm, sizeof(tm)); 631155131Srwatson strptime(optarg, "%Y%m%d%H%M%S", &tm); 632155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", 633155131Srwatson &tm); 634155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 635155131Srwatson p_atime = mktime(&tm); 636155131Srwatson break; 637155131Srwatson 638155131Srwatson case 'b': 639155131Srwatson if (ISOPTSET(opttochk, OPT_b)) { 640155131Srwatson usage("d is exclusive with a and b"); 641155131Srwatson } 642155131Srwatson SETOPT(opttochk, OPT_b); 643171537Srwatson bzero(&tm, sizeof(tm)); 644155131Srwatson strptime(optarg, "%Y%m%d%H%M%S", &tm); 645155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", 646155131Srwatson &tm); 647155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 648155131Srwatson p_btime = mktime(&tm); 649155131Srwatson break; 650155131Srwatson 651155131Srwatson case 'c': 652155131Srwatson if (0 != getauditflagsbin(optarg, &maskp)) { 653155131Srwatson /* Incorrect class */ 654155131Srwatson usage("Incorrect class"); 655155131Srwatson } 656155131Srwatson SETOPT(opttochk, OPT_c); 657155131Srwatson break; 658155131Srwatson 659155131Srwatson case 'd': 660155131Srwatson if (ISOPTSET(opttochk, OPT_b) || ISOPTSET(opttochk, 661155131Srwatson OPT_a)) 662155131Srwatson usage("'d' is exclusive with 'a' and 'b'"); 663155131Srwatson SETOPT(opttochk, OPT_d); 664171537Srwatson bzero(&tm, sizeof(tm)); 665155131Srwatson strptime(optarg, "%Y%m%d", &tm); 666155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d", &tm); 667155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 668155131Srwatson p_atime = mktime(&tm); 669155131Srwatson tm.tm_hour = 23; 670155131Srwatson tm.tm_min = 59; 671155131Srwatson tm.tm_sec = 59; 672155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d", &tm); 673155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 674155131Srwatson p_btime = mktime(&tm); 675155131Srwatson break; 676155131Srwatson 677155131Srwatson case 'e': 678155131Srwatson p_euid = strtol(optarg, &converr, 10); 679155131Srwatson if (*converr != '\0') { 680155131Srwatson /* Try the actual name */ 681155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 682155131Srwatson break; 683155131Srwatson p_euid = pw->pw_uid; 684155131Srwatson } 685155131Srwatson SETOPT(opttochk, OPT_e); 686155131Srwatson break; 687155131Srwatson 688155131Srwatson case 'f': 689155131Srwatson p_egid = strtol(optarg, &converr, 10); 690155131Srwatson if (*converr != '\0') { 691155131Srwatson /* Try actual group name. */ 692155131Srwatson if ((grp = getgrnam(optarg)) == NULL) 693155131Srwatson break; 694155131Srwatson p_egid = grp->gr_gid; 695155131Srwatson } 696155131Srwatson SETOPT(opttochk, OPT_f); 697155131Srwatson break; 698155131Srwatson 699155131Srwatson case 'g': 700155131Srwatson p_rgid = strtol(optarg, &converr, 10); 701155131Srwatson if (*converr != '\0') { 702155131Srwatson /* Try actual group name. */ 703155131Srwatson if ((grp = getgrnam(optarg)) == NULL) 704155131Srwatson break; 705155131Srwatson p_rgid = grp->gr_gid; 706155131Srwatson } 707155131Srwatson SETOPT(opttochk, OPT_g); 708155131Srwatson break; 709155131Srwatson 710155131Srwatson case 'j': 711155131Srwatson p_subid = strtol(optarg, (char **)NULL, 10); 712155131Srwatson SETOPT(opttochk, OPT_j); 713155131Srwatson break; 714155131Srwatson 715155131Srwatson case 'm': 716185573Srwatson if (p_evec == NULL) { 717185573Srwatson p_evec_alloc = 32; 718185573Srwatson p_evec = malloc(sizeof(*etp) * p_evec_alloc); 719185573Srwatson if (p_evec == NULL) 720185573Srwatson err(1, "malloc"); 721185573Srwatson } else if (p_evec_alloc == p_evec_used) { 722185573Srwatson p_evec_alloc <<= 1; 723185573Srwatson p_evec = realloc(p_evec, 724185573Srwatson sizeof(*p_evec) * p_evec_alloc); 725185573Srwatson if (p_evec == NULL) 726185573Srwatson err(1, "realloc"); 727185573Srwatson } 728185573Srwatson etp = &p_evec[p_evec_used++]; 729185573Srwatson *etp = strtol(optarg, (char **)NULL, 10); 730185573Srwatson if (*etp == 0) { 731155131Srwatson /* Could be the string representation. */ 732155131Srwatson n = getauevnonam(optarg); 733155131Srwatson if (n == NULL) 734155131Srwatson usage("Incorrect event name"); 735185573Srwatson *etp = *n; 736155131Srwatson } 737155131Srwatson SETOPT(opttochk, OPT_m); 738155131Srwatson break; 739155131Srwatson 740155131Srwatson case 'o': 741155131Srwatson objval = strchr(optarg, '='); 742155131Srwatson if (objval != NULL) { 743155131Srwatson *objval = '\0'; 744155131Srwatson objval += 1; 745155131Srwatson parse_object_type(optarg, objval); 746155131Srwatson } 747155131Srwatson break; 748155131Srwatson 749155131Srwatson case 'r': 750155131Srwatson p_ruid = strtol(optarg, &converr, 10); 751155131Srwatson if (*converr != '\0') { 752155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 753155131Srwatson break; 754155131Srwatson p_ruid = pw->pw_uid; 755155131Srwatson } 756155131Srwatson SETOPT(opttochk, OPT_r); 757155131Srwatson break; 758155131Srwatson 759155131Srwatson case 'u': 760155131Srwatson p_auid = strtol(optarg, &converr, 10); 761155131Srwatson if (*converr != '\0') { 762155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 763155131Srwatson break; 764155131Srwatson p_auid = pw->pw_uid; 765155131Srwatson } 766155131Srwatson SETOPT(opttochk, OPT_u); 767155131Srwatson break; 768155131Srwatson 769185573Srwatson case 'v': 770185573Srwatson SETOPT(opttochk, OPT_v); 771185573Srwatson break; 772185573Srwatson 773155131Srwatson case '?': 774155131Srwatson default: 775155131Srwatson usage("Unknown option"); 776155131Srwatson } 777155131Srwatson } 778155131Srwatson argv += optind; 779155131Srwatson argc -= optind; 780155131Srwatson 781162621Srwatson if (argc == 0) { 782162621Srwatson if (select_records(stdin) == -1) 783162621Srwatson errx(EXIT_FAILURE, 784162621Srwatson "Couldn't select records from stdin"); 785162621Srwatson exit(EXIT_SUCCESS); 786162621Srwatson } 787155131Srwatson 788155131Srwatson /* 789155131Srwatson * XXX: We should actually be merging records here. 790155131Srwatson */ 791155131Srwatson for (i = 0; i < argc; i++) { 792155131Srwatson fname = argv[i]; 793155131Srwatson fp = fopen(fname, "r"); 794155131Srwatson if (fp == NULL) 795155131Srwatson errx(EXIT_FAILURE, "Couldn't open %s", fname); 796155131Srwatson if (select_records(fp) == -1) { 797155131Srwatson errx(EXIT_FAILURE, "Couldn't select records %s", 798155131Srwatson fname); 799155131Srwatson } 800155131Srwatson fclose(fp); 801155131Srwatson } 802155131Srwatson exit(EXIT_SUCCESS); 803155131Srwatson} 804