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 */ 29155131Srwatson 30155131Srwatson/* 31155131Srwatson * Tool used to merge and select audit records from audit trail files 32155131Srwatson */ 33155131Srwatson 34155131Srwatson/* 35155131Srwatson * XXX Currently we do not support merging of records from multiple 36155131Srwatson * XXX audit trail files 37155131Srwatson * XXX We assume that records are sorted chronologically - both wrt to 38155131Srwatson * XXX the records present within the file and between the files themselves 39155131Srwatson */ 40155131Srwatson 41162621Srwatson#include <config/config.h> 42187214Srwatson 43187214Srwatson#define _GNU_SOURCE /* Required for strptime() on glibc2. */ 44187214Srwatson 45162621Srwatson#ifdef HAVE_FULL_QUEUE_H 46162621Srwatson#include <sys/queue.h> 47162621Srwatson#else 48162621Srwatson#include <compat/queue.h> 49162621Srwatson#endif 50162621Srwatson 51155131Srwatson#include <bsm/libbsm.h> 52155131Srwatson 53159248Srwatson#include <err.h> 54159248Srwatson#include <grp.h> 55159248Srwatson#include <pwd.h> 56155131Srwatson#include <stdio.h> 57155131Srwatson#include <stdlib.h> 58155131Srwatson#include <sysexits.h> 59155131Srwatson#include <string.h> 60155131Srwatson#include <time.h> 61155131Srwatson#include <unistd.h> 62162621Srwatson#include <regex.h> 63162621Srwatson#include <errno.h> 64155131Srwatson 65185573Srwatson#ifndef HAVE_STRLCPY 66185573Srwatson#include <compat/strlcpy.h> 67185573Srwatson#endif 68185573Srwatson 69155131Srwatson#include "auditreduce.h" 70155131Srwatson 71162621Srwatsonstatic TAILQ_HEAD(tailhead, re_entry) re_head = 72162621Srwatson TAILQ_HEAD_INITIALIZER(re_head); 73162621Srwatson 74155131Srwatsonextern char *optarg; 75155131Srwatsonextern int optind, optopt, opterr,optreset; 76155131Srwatson 77155131Srwatsonstatic au_mask_t maskp; /* Class. */ 78155131Srwatsonstatic time_t p_atime; /* Created after this time. */ 79155131Srwatsonstatic time_t p_btime; /* Created before this time. */ 80155131Srwatsonstatic int p_auid; /* Audit id. */ 81155131Srwatsonstatic int p_euid; /* Effective user id. */ 82155131Srwatsonstatic int p_egid; /* Effective group id. */ 83155131Srwatsonstatic int p_rgid; /* Real group id. */ 84155131Srwatsonstatic int p_ruid; /* Real user id. */ 85155131Srwatsonstatic int p_subid; /* Subject id. */ 86155131Srwatson 87155131Srwatson/* 88185573Srwatson * Maintain a dynamically sized array of events for -m 89185573Srwatson */ 90185573Srwatsonstatic uint16_t *p_evec; /* Event type list */ 91185573Srwatsonstatic int p_evec_used; /* Number of events used */ 92185573Srwatsonstatic int p_evec_alloc; /* Number of events allocated */ 93185573Srwatson 94185573Srwatson/* 95155131Srwatson * Following are the objects (-o option) that we can select upon. 96155131Srwatson */ 97155131Srwatsonstatic char *p_fileobj = NULL; 98155131Srwatsonstatic char *p_msgqobj = NULL; 99155131Srwatsonstatic char *p_pidobj = NULL; 100155131Srwatsonstatic char *p_semobj = NULL; 101155131Srwatsonstatic char *p_shmobj = NULL; 102155131Srwatsonstatic char *p_sockobj = NULL; 103155131Srwatson 104155131Srwatsonstatic uint32_t opttochk = 0; 105155131Srwatson 106155131Srwatsonstatic void 107162621Srwatsonparse_regexp(char *re_string) 108162621Srwatson{ 109162621Srwatson char *orig, *copy, re_error[64]; 110162621Srwatson struct re_entry *rep; 111162621Srwatson int error, nstrs, i, len; 112162621Srwatson 113162621Srwatson copy = strdup(re_string); 114162621Srwatson orig = copy; 115162621Srwatson len = strlen(copy); 116162621Srwatson for (nstrs = 0, i = 0; i < len; i++) { 117162621Srwatson if (copy[i] == ',' && i > 0) { 118162621Srwatson if (copy[i - 1] == '\\') 119185573Srwatson strlcpy(©[i - 1], ©[i], len); 120162621Srwatson else { 121162621Srwatson nstrs++; 122162621Srwatson copy[i] = '\0'; 123162621Srwatson } 124162621Srwatson } 125162621Srwatson } 126162621Srwatson TAILQ_INIT(&re_head); 127162621Srwatson for (i = 0; i < nstrs + 1; i++) { 128162621Srwatson rep = calloc(1, sizeof(*rep)); 129162621Srwatson if (rep == NULL) { 130162621Srwatson (void) fprintf(stderr, "calloc: %s\n", 131162621Srwatson strerror(errno)); 132162621Srwatson exit(1); 133162621Srwatson } 134162621Srwatson if (*copy == '~') { 135162621Srwatson copy++; 136162621Srwatson rep->re_negate = 1; 137162621Srwatson } 138162621Srwatson rep->re_pattern = strdup(copy); 139162621Srwatson error = regcomp(&rep->re_regexp, rep->re_pattern, 140162621Srwatson REG_EXTENDED | REG_NOSUB); 141162621Srwatson if (error != 0) { 142162621Srwatson regerror(error, &rep->re_regexp, re_error, 64); 143162621Srwatson (void) fprintf(stderr, "regcomp: %s\n", re_error); 144162621Srwatson exit(1); 145162621Srwatson } 146162621Srwatson TAILQ_INSERT_TAIL(&re_head, rep, re_glue); 147162621Srwatson len = strlen(copy); 148162621Srwatson copy += len + 1; 149162621Srwatson } 150162621Srwatson free(orig); 151162621Srwatson} 152162621Srwatson 153162621Srwatsonstatic void 154155131Srwatsonusage(const char *msg) 155155131Srwatson{ 156155131Srwatson fprintf(stderr, "%s\n", msg); 157162621Srwatson fprintf(stderr, "Usage: auditreduce [options] [file ...]\n"); 158155131Srwatson fprintf(stderr, "\tOptions are : \n"); 159155131Srwatson fprintf(stderr, "\t-A : all records\n"); 160155131Srwatson fprintf(stderr, "\t-a YYYYMMDD[HH[[MM[SS]]] : after date\n"); 161155131Srwatson fprintf(stderr, "\t-b YYYYMMDD[HH[[MM[SS]]] : before date\n"); 162155131Srwatson fprintf(stderr, "\t-c <flags> : matching class\n"); 163155131Srwatson fprintf(stderr, "\t-d YYYYMMDD : on date\n"); 164155131Srwatson fprintf(stderr, "\t-e <uid|name> : effective user\n"); 165155131Srwatson fprintf(stderr, "\t-f <gid|group> : effective group\n"); 166155131Srwatson fprintf(stderr, "\t-g <gid|group> : real group\n"); 167155131Srwatson fprintf(stderr, "\t-j <pid> : subject id \n"); 168155131Srwatson fprintf(stderr, "\t-m <evno|evname> : matching event\n"); 169155131Srwatson fprintf(stderr, "\t-o objecttype=objectvalue\n"); 170155131Srwatson fprintf(stderr, "\t\t file=<pathname>\n"); 171155131Srwatson fprintf(stderr, "\t\t msgqid=<ID>\n"); 172155131Srwatson fprintf(stderr, "\t\t pid=<ID>\n"); 173155131Srwatson fprintf(stderr, "\t\t semid=<ID>\n"); 174155131Srwatson fprintf(stderr, "\t\t shmid=<ID>\n"); 175155131Srwatson fprintf(stderr, "\t-r <uid|name> : real user\n"); 176155131Srwatson fprintf(stderr, "\t-u <uid|name> : audit user\n"); 177185573Srwatson fprintf(stderr, "\t-v : select non-matching records\n"); 178155131Srwatson exit(EX_USAGE); 179155131Srwatson} 180155131Srwatson 181155131Srwatson/* 182155131Srwatson * Check if the given auid matches the selection criteria. 183155131Srwatson */ 184155131Srwatsonstatic int 185155131Srwatsonselect_auid(int au) 186155131Srwatson{ 187155131Srwatson 188155131Srwatson /* Check if we want to select on auid. */ 189155131Srwatson if (ISOPTSET(opttochk, OPT_u)) { 190155131Srwatson if (au != p_auid) 191155131Srwatson return (0); 192155131Srwatson } 193155131Srwatson return (1); 194155131Srwatson} 195155131Srwatson 196155131Srwatson/* 197155131Srwatson * Check if the given euid matches the selection criteria. 198155131Srwatson */ 199155131Srwatsonstatic int 200155131Srwatsonselect_euid(int euser) 201155131Srwatson{ 202155131Srwatson 203155131Srwatson /* Check if we want to select on euid. */ 204155131Srwatson if (ISOPTSET(opttochk, OPT_e)) { 205155131Srwatson if (euser != p_euid) 206155131Srwatson return (0); 207155131Srwatson } 208155131Srwatson return (1); 209155131Srwatson} 210155131Srwatson 211155131Srwatson/* 212155131Srwatson * Check if the given egid matches the selection criteria. 213155131Srwatson */ 214155131Srwatsonstatic int 215155131Srwatsonselect_egid(int egrp) 216155131Srwatson{ 217155131Srwatson 218155131Srwatson /* Check if we want to select on egid. */ 219155131Srwatson if (ISOPTSET(opttochk, OPT_f)) { 220155131Srwatson if (egrp != p_egid) 221155131Srwatson return (0); 222155131Srwatson } 223155131Srwatson return (1); 224155131Srwatson} 225155131Srwatson 226155131Srwatson/* 227155131Srwatson * Check if the given rgid matches the selection criteria. 228155131Srwatson */ 229155131Srwatsonstatic int 230155131Srwatsonselect_rgid(int grp) 231155131Srwatson{ 232155131Srwatson 233155131Srwatson /* Check if we want to select on rgid. */ 234155131Srwatson if (ISOPTSET(opttochk, OPT_g)) { 235155131Srwatson if (grp != p_rgid) 236155131Srwatson return (0); 237155131Srwatson } 238155131Srwatson return (1); 239155131Srwatson} 240155131Srwatson 241155131Srwatson/* 242155131Srwatson * Check if the given ruid matches the selection criteria. 243155131Srwatson */ 244155131Srwatsonstatic int 245155131Srwatsonselect_ruid(int user) 246155131Srwatson{ 247155131Srwatson 248155131Srwatson /* Check if we want to select on rgid. */ 249155131Srwatson if (ISOPTSET(opttochk, OPT_r)) { 250155131Srwatson if (user != p_ruid) 251155131Srwatson return (0); 252155131Srwatson } 253155131Srwatson return (1); 254155131Srwatson} 255155131Srwatson 256155131Srwatson/* 257155131Srwatson * Check if the given subject id (pid) matches the selection criteria. 258155131Srwatson */ 259155131Srwatsonstatic int 260155131Srwatsonselect_subid(int subid) 261155131Srwatson{ 262155131Srwatson 263155131Srwatson /* Check if we want to select on subject uid. */ 264155131Srwatson if (ISOPTSET(opttochk, OPT_j)) { 265155131Srwatson if (subid != p_subid) 266155131Srwatson return (0); 267155131Srwatson } 268155131Srwatson return (1); 269155131Srwatson} 270155131Srwatson 271155131Srwatson 272155131Srwatson/* 273155131Srwatson * Check if object's pid maches the given pid. 274155131Srwatson */ 275155131Srwatsonstatic int 276155131Srwatsonselect_pidobj(uint32_t pid) 277155131Srwatson{ 278155131Srwatson 279155131Srwatson if (ISOPTSET(opttochk, OPT_op)) { 280185573Srwatson if (pid != (uint32_t)strtol(p_pidobj, (char **)NULL, 10)) 281155131Srwatson return (0); 282155131Srwatson } 283155131Srwatson return (1); 284155131Srwatson} 285155131Srwatson 286155131Srwatson/* 287155131Srwatson * Check if the given ipc object with the given type matches the selection 288155131Srwatson * criteria. 289155131Srwatson */ 290155131Srwatsonstatic int 291155131Srwatsonselect_ipcobj(u_char type, uint32_t id, uint32_t *optchkd) 292155131Srwatson{ 293155131Srwatson 294155131Srwatson if (type == AT_IPC_MSG) { 295155131Srwatson SETOPT((*optchkd), OPT_om); 296155131Srwatson if (ISOPTSET(opttochk, OPT_om)) { 297185573Srwatson if (id != (uint32_t)strtol(p_msgqobj, (char **)NULL, 298185573Srwatson 10)) 299155131Srwatson return (0); 300155131Srwatson } 301155131Srwatson return (1); 302155131Srwatson } else if (type == AT_IPC_SEM) { 303155131Srwatson SETOPT((*optchkd), OPT_ose); 304155131Srwatson if (ISOPTSET(opttochk, OPT_ose)) { 305185573Srwatson if (id != (uint32_t)strtol(p_semobj, (char **)NULL, 10)) 306155131Srwatson return (0); 307155131Srwatson } 308155131Srwatson return (1); 309155131Srwatson } else if (type == AT_IPC_SHM) { 310155131Srwatson SETOPT((*optchkd), OPT_osh); 311155131Srwatson if (ISOPTSET(opttochk, OPT_osh)) { 312185573Srwatson if (id != (uint32_t)strtol(p_shmobj, (char **)NULL, 10)) 313155131Srwatson return (0); 314155131Srwatson } 315155131Srwatson return (1); 316155131Srwatson } 317155131Srwatson 318155131Srwatson /* Unknown type -- filter if *any* ipc filtering is required. */ 319155131Srwatson if (ISOPTSET(opttochk, OPT_om) || ISOPTSET(opttochk, OPT_ose) 320155131Srwatson || ISOPTSET(opttochk, OPT_osh)) 321155131Srwatson return (0); 322155131Srwatson 323155131Srwatson return (1); 324155131Srwatson} 325155131Srwatson 326155131Srwatson 327155131Srwatson/* 328155131Srwatson * Check if the file name matches selection criteria. 329155131Srwatson */ 330155131Srwatsonstatic int 331155131Srwatsonselect_filepath(char *path, uint32_t *optchkd) 332155131Srwatson{ 333162621Srwatson struct re_entry *rep; 334162621Srwatson int match; 335155131Srwatson 336155131Srwatson SETOPT((*optchkd), OPT_of); 337162621Srwatson match = 1; 338155131Srwatson if (ISOPTSET(opttochk, OPT_of)) { 339162621Srwatson match = 0; 340162621Srwatson TAILQ_FOREACH(rep, &re_head, re_glue) { 341162621Srwatson if (regexec(&rep->re_regexp, path, 0, NULL, 342162621Srwatson 0) != REG_NOMATCH) 343162621Srwatson return (!rep->re_negate); 344155131Srwatson } 345155131Srwatson } 346162621Srwatson return (match); 347155131Srwatson} 348155131Srwatson 349155131Srwatson/* 350155131Srwatson * Returns 1 if the following pass the selection rules: 351155131Srwatson * 352155131Srwatson * before-time, 353155131Srwatson * after time, 354155131Srwatson * date, 355155131Srwatson * class, 356155131Srwatson * event 357155131Srwatson */ 358155131Srwatsonstatic int 359155131Srwatsonselect_hdr32(tokenstr_t tok, uint32_t *optchkd) 360155131Srwatson{ 361185573Srwatson uint16_t *ev; 362185573Srwatson int match; 363155131Srwatson 364185573Srwatson SETOPT((*optchkd), (OPT_A | OPT_a | OPT_b | OPT_c | OPT_m | OPT_v)); 365155131Srwatson 366155131Srwatson /* The A option overrides a, b and d. */ 367155131Srwatson if (!ISOPTSET(opttochk, OPT_A)) { 368155131Srwatson if (ISOPTSET(opttochk, OPT_a)) { 369155131Srwatson if (difftime((time_t)tok.tt.hdr32.s, p_atime) < 0) { 370155131Srwatson /* Record was created before p_atime. */ 371155131Srwatson return (0); 372155131Srwatson } 373155131Srwatson } 374155131Srwatson 375155131Srwatson if (ISOPTSET(opttochk, OPT_b)) { 376155131Srwatson if (difftime(p_btime, (time_t)tok.tt.hdr32.s) < 0) { 377155131Srwatson /* Record was created after p_btime. */ 378155131Srwatson return (0); 379155131Srwatson } 380155131Srwatson } 381155131Srwatson } 382155131Srwatson 383155131Srwatson if (ISOPTSET(opttochk, OPT_c)) { 384155131Srwatson /* 385155131Srwatson * Check if the classes represented by the event matches 386155131Srwatson * given class. 387155131Srwatson */ 388155131Srwatson if (au_preselect(tok.tt.hdr32.e_type, &maskp, AU_PRS_BOTH, 389155131Srwatson AU_PRS_USECACHE) != 1) 390155131Srwatson return (0); 391155131Srwatson } 392155131Srwatson 393155131Srwatson /* Check if event matches. */ 394155131Srwatson if (ISOPTSET(opttochk, OPT_m)) { 395185573Srwatson match = 0; 396185573Srwatson for (ev = p_evec; ev < &p_evec[p_evec_used]; ev++) 397185573Srwatson if (tok.tt.hdr32.e_type == *ev) 398185573Srwatson match = 1; 399185573Srwatson if (match == 0) 400155131Srwatson return (0); 401155131Srwatson } 402155131Srwatson 403155131Srwatson return (1); 404155131Srwatson} 405155131Srwatson 406162621Srwatsonstatic int 407162621Srwatsonselect_return32(tokenstr_t tok_ret32, tokenstr_t tok_hdr32, uint32_t *optchkd) 408162621Srwatson{ 409162621Srwatson int sorf; 410162621Srwatson 411162621Srwatson SETOPT((*optchkd), (OPT_c)); 412162621Srwatson if (tok_ret32.tt.ret32.status == 0) 413162621Srwatson sorf = AU_PRS_SUCCESS; 414162621Srwatson else 415162621Srwatson sorf = AU_PRS_FAILURE; 416162621Srwatson if (ISOPTSET(opttochk, OPT_c)) { 417162621Srwatson if (au_preselect(tok_hdr32.tt.hdr32.e_type, &maskp, sorf, 418162621Srwatson AU_PRS_USECACHE) != 1) 419162621Srwatson return (0); 420162621Srwatson } 421162621Srwatson return (1); 422162621Srwatson} 423162621Srwatson 424155131Srwatson/* 425155131Srwatson * Return 1 if checks for the the following succeed 426155131Srwatson * auid, 427155131Srwatson * euid, 428155131Srwatson * egid, 429155131Srwatson * rgid, 430155131Srwatson * ruid, 431155131Srwatson * process id 432155131Srwatson */ 433155131Srwatsonstatic int 434155131Srwatsonselect_proc32(tokenstr_t tok, uint32_t *optchkd) 435155131Srwatson{ 436155131Srwatson 437155131Srwatson SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_op)); 438155131Srwatson 439155131Srwatson if (!select_auid(tok.tt.proc32.auid)) 440155131Srwatson return (0); 441155131Srwatson if (!select_euid(tok.tt.proc32.euid)) 442155131Srwatson return (0); 443155131Srwatson if (!select_egid(tok.tt.proc32.egid)) 444155131Srwatson return (0); 445155131Srwatson if (!select_rgid(tok.tt.proc32.rgid)) 446155131Srwatson return (0); 447155131Srwatson if (!select_ruid(tok.tt.proc32.ruid)) 448155131Srwatson return (0); 449155131Srwatson if (!select_pidobj(tok.tt.proc32.pid)) 450155131Srwatson return (0); 451155131Srwatson return (1); 452155131Srwatson} 453155131Srwatson 454155131Srwatson/* 455155131Srwatson * Return 1 if checks for the the following succeed 456155131Srwatson * auid, 457155131Srwatson * euid, 458155131Srwatson * egid, 459155131Srwatson * rgid, 460155131Srwatson * ruid, 461155131Srwatson * subject id 462155131Srwatson */ 463155131Srwatsonstatic int 464155131Srwatsonselect_subj32(tokenstr_t tok, uint32_t *optchkd) 465155131Srwatson{ 466155131Srwatson 467155131Srwatson SETOPT((*optchkd), (OPT_u | OPT_e | OPT_f | OPT_g | OPT_r | OPT_j)); 468155131Srwatson 469155131Srwatson if (!select_auid(tok.tt.subj32.auid)) 470155131Srwatson return (0); 471155131Srwatson if (!select_euid(tok.tt.subj32.euid)) 472155131Srwatson return (0); 473155131Srwatson if (!select_egid(tok.tt.subj32.egid)) 474155131Srwatson return (0); 475155131Srwatson if (!select_rgid(tok.tt.subj32.rgid)) 476155131Srwatson return (0); 477155131Srwatson if (!select_ruid(tok.tt.subj32.ruid)) 478155131Srwatson return (0); 479155131Srwatson if (!select_subid(tok.tt.subj32.pid)) 480155131Srwatson return (0); 481155131Srwatson return (1); 482155131Srwatson} 483155131Srwatson 484155131Srwatson/* 485155131Srwatson * Read each record from the audit trail. Check if it is selected after 486155131Srwatson * passing through each of the options 487155131Srwatson */ 488155131Srwatsonstatic int 489155131Srwatsonselect_records(FILE *fp) 490155131Srwatson{ 491162621Srwatson tokenstr_t tok_hdr32_copy; 492155131Srwatson u_char *buf; 493155131Srwatson tokenstr_t tok; 494155131Srwatson int reclen; 495155131Srwatson int bytesread; 496155131Srwatson int selected; 497155131Srwatson uint32_t optchkd; 498185573Srwatson int print; 499155131Srwatson 500155131Srwatson int err = 0; 501155131Srwatson while ((reclen = au_read_rec(fp, &buf)) != -1) { 502155131Srwatson optchkd = 0; 503155131Srwatson bytesread = 0; 504155131Srwatson selected = 1; 505155131Srwatson while ((selected == 1) && (bytesread < reclen)) { 506155131Srwatson if (-1 == au_fetch_tok(&tok, buf + bytesread, 507155131Srwatson reclen - bytesread)) { 508155131Srwatson /* Is this an incomplete record? */ 509155131Srwatson err = 1; 510155131Srwatson break; 511155131Srwatson } 512155131Srwatson 513155131Srwatson /* 514155131Srwatson * For each token type we have have different 515155131Srwatson * selection criteria. 516155131Srwatson */ 517155131Srwatson switch(tok.id) { 518185573Srwatson case AUT_HEADER32: 519155131Srwatson selected = select_hdr32(tok, 520155131Srwatson &optchkd); 521162621Srwatson bcopy(&tok, &tok_hdr32_copy, 522162621Srwatson sizeof(tok)); 523155131Srwatson break; 524155131Srwatson 525185573Srwatson case AUT_PROCESS32: 526155131Srwatson selected = select_proc32(tok, 527155131Srwatson &optchkd); 528155131Srwatson break; 529155131Srwatson 530185573Srwatson case AUT_SUBJECT32: 531155131Srwatson selected = select_subj32(tok, 532155131Srwatson &optchkd); 533155131Srwatson break; 534155131Srwatson 535185573Srwatson case AUT_IPC: 536155131Srwatson selected = select_ipcobj( 537155131Srwatson tok.tt.ipc.type, tok.tt.ipc.id, 538155131Srwatson &optchkd); 539155131Srwatson break; 540155131Srwatson 541185573Srwatson case AUT_PATH: 542155131Srwatson selected = select_filepath( 543155131Srwatson tok.tt.path.path, &optchkd); 544155131Srwatson break; 545155131Srwatson 546185573Srwatson case AUT_RETURN32: 547162621Srwatson selected = select_return32(tok, 548162621Srwatson tok_hdr32_copy, &optchkd); 549162621Srwatson break; 550162621Srwatson 551155131Srwatson default: 552155131Srwatson break; 553155131Srwatson } 554155131Srwatson bytesread += tok.len; 555155131Srwatson } 556185573Srwatson /* Check if all the options were matched. */ 557185573Srwatson print = ((selected == 1) && (!err) && (!(opttochk & ~optchkd))); 558185573Srwatson if (ISOPTSET(opttochk, OPT_v)) 559185573Srwatson print = !print; 560185573Srwatson if (print) 561185573Srwatson (void) fwrite(buf, 1, reclen, stdout); 562155131Srwatson free(buf); 563155131Srwatson } 564155131Srwatson return (0); 565155131Srwatson} 566155131Srwatson 567155131Srwatson/* 568155131Srwatson * The -o option has the form object_type=object_value. Identify the object 569155131Srwatson * components. 570155131Srwatson */ 571186647Srwatsonstatic void 572155131Srwatsonparse_object_type(char *name, char *val) 573155131Srwatson{ 574155131Srwatson if (val == NULL) 575155131Srwatson return; 576155131Srwatson 577155131Srwatson if (!strcmp(name, FILEOBJ)) { 578155131Srwatson p_fileobj = val; 579162621Srwatson parse_regexp(val); 580155131Srwatson SETOPT(opttochk, OPT_of); 581155131Srwatson } else if (!strcmp(name, MSGQIDOBJ)) { 582155131Srwatson p_msgqobj = val; 583155131Srwatson SETOPT(opttochk, OPT_om); 584155131Srwatson } else if (!strcmp(name, PIDOBJ)) { 585155131Srwatson p_pidobj = val; 586155131Srwatson SETOPT(opttochk, OPT_op); 587155131Srwatson } else if (!strcmp(name, SEMIDOBJ)) { 588155131Srwatson p_semobj = val; 589155131Srwatson SETOPT(opttochk, OPT_ose); 590155131Srwatson } else if (!strcmp(name, SHMIDOBJ)) { 591155131Srwatson p_shmobj = val; 592155131Srwatson SETOPT(opttochk, OPT_osh); 593155131Srwatson } else if (!strcmp(name, SOCKOBJ)) { 594155131Srwatson p_sockobj = val; 595155131Srwatson SETOPT(opttochk, OPT_oso); 596155131Srwatson } else 597155131Srwatson usage("unknown value for -o"); 598155131Srwatson} 599155131Srwatson 600155131Srwatsonint 601155131Srwatsonmain(int argc, char **argv) 602155131Srwatson{ 603155131Srwatson struct group *grp; 604155131Srwatson struct passwd *pw; 605155131Srwatson struct tm tm; 606155131Srwatson au_event_t *n; 607155131Srwatson FILE *fp; 608155131Srwatson int i; 609155131Srwatson char *objval, *converr; 610155364Srwatson int ch; 611155131Srwatson char timestr[128]; 612155131Srwatson char *fname; 613185573Srwatson uint16_t *etp; 614155131Srwatson 615155131Srwatson converr = NULL; 616155131Srwatson 617185573Srwatson while ((ch = getopt(argc, argv, "Aa:b:c:d:e:f:g:j:m:o:r:u:v")) != -1) { 618155131Srwatson switch(ch) { 619155131Srwatson case 'A': 620155131Srwatson SETOPT(opttochk, OPT_A); 621155131Srwatson break; 622155131Srwatson 623155131Srwatson case 'a': 624155131Srwatson if (ISOPTSET(opttochk, OPT_a)) { 625155131Srwatson usage("d is exclusive with a and b"); 626155131Srwatson } 627155131Srwatson SETOPT(opttochk, OPT_a); 628171537Srwatson bzero(&tm, sizeof(tm)); 629155131Srwatson strptime(optarg, "%Y%m%d%H%M%S", &tm); 630155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", 631155131Srwatson &tm); 632155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 633155131Srwatson p_atime = mktime(&tm); 634155131Srwatson break; 635155131Srwatson 636155131Srwatson case 'b': 637155131Srwatson if (ISOPTSET(opttochk, OPT_b)) { 638155131Srwatson usage("d is exclusive with a and b"); 639155131Srwatson } 640155131Srwatson SETOPT(opttochk, OPT_b); 641171537Srwatson bzero(&tm, sizeof(tm)); 642155131Srwatson strptime(optarg, "%Y%m%d%H%M%S", &tm); 643155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", 644155131Srwatson &tm); 645155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 646155131Srwatson p_btime = mktime(&tm); 647155131Srwatson break; 648155131Srwatson 649155131Srwatson case 'c': 650155131Srwatson if (0 != getauditflagsbin(optarg, &maskp)) { 651155131Srwatson /* Incorrect class */ 652155131Srwatson usage("Incorrect class"); 653155131Srwatson } 654155131Srwatson SETOPT(opttochk, OPT_c); 655155131Srwatson break; 656155131Srwatson 657155131Srwatson case 'd': 658155131Srwatson if (ISOPTSET(opttochk, OPT_b) || ISOPTSET(opttochk, 659155131Srwatson OPT_a)) 660155131Srwatson usage("'d' is exclusive with 'a' and 'b'"); 661155131Srwatson SETOPT(opttochk, OPT_d); 662171537Srwatson bzero(&tm, sizeof(tm)); 663155131Srwatson strptime(optarg, "%Y%m%d", &tm); 664155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d", &tm); 665155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 666155131Srwatson p_atime = mktime(&tm); 667155131Srwatson tm.tm_hour = 23; 668155131Srwatson tm.tm_min = 59; 669155131Srwatson tm.tm_sec = 59; 670155131Srwatson strftime(timestr, sizeof(timestr), "%Y%m%d", &tm); 671155131Srwatson /* fprintf(stderr, "Time converted = %s\n", timestr); */ 672155131Srwatson p_btime = mktime(&tm); 673155131Srwatson break; 674155131Srwatson 675155131Srwatson case 'e': 676155131Srwatson p_euid = strtol(optarg, &converr, 10); 677155131Srwatson if (*converr != '\0') { 678155131Srwatson /* Try the actual name */ 679155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 680155131Srwatson break; 681155131Srwatson p_euid = pw->pw_uid; 682155131Srwatson } 683155131Srwatson SETOPT(opttochk, OPT_e); 684155131Srwatson break; 685155131Srwatson 686155131Srwatson case 'f': 687155131Srwatson p_egid = strtol(optarg, &converr, 10); 688155131Srwatson if (*converr != '\0') { 689155131Srwatson /* Try actual group name. */ 690155131Srwatson if ((grp = getgrnam(optarg)) == NULL) 691155131Srwatson break; 692155131Srwatson p_egid = grp->gr_gid; 693155131Srwatson } 694155131Srwatson SETOPT(opttochk, OPT_f); 695155131Srwatson break; 696155131Srwatson 697155131Srwatson case 'g': 698155131Srwatson p_rgid = strtol(optarg, &converr, 10); 699155131Srwatson if (*converr != '\0') { 700155131Srwatson /* Try actual group name. */ 701155131Srwatson if ((grp = getgrnam(optarg)) == NULL) 702155131Srwatson break; 703155131Srwatson p_rgid = grp->gr_gid; 704155131Srwatson } 705155131Srwatson SETOPT(opttochk, OPT_g); 706155131Srwatson break; 707155131Srwatson 708155131Srwatson case 'j': 709155131Srwatson p_subid = strtol(optarg, (char **)NULL, 10); 710155131Srwatson SETOPT(opttochk, OPT_j); 711155131Srwatson break; 712155131Srwatson 713155131Srwatson case 'm': 714185573Srwatson if (p_evec == NULL) { 715185573Srwatson p_evec_alloc = 32; 716185573Srwatson p_evec = malloc(sizeof(*etp) * p_evec_alloc); 717185573Srwatson if (p_evec == NULL) 718185573Srwatson err(1, "malloc"); 719185573Srwatson } else if (p_evec_alloc == p_evec_used) { 720185573Srwatson p_evec_alloc <<= 1; 721185573Srwatson p_evec = realloc(p_evec, 722185573Srwatson sizeof(*p_evec) * p_evec_alloc); 723185573Srwatson if (p_evec == NULL) 724185573Srwatson err(1, "realloc"); 725185573Srwatson } 726185573Srwatson etp = &p_evec[p_evec_used++]; 727185573Srwatson *etp = strtol(optarg, (char **)NULL, 10); 728185573Srwatson if (*etp == 0) { 729155131Srwatson /* Could be the string representation. */ 730155131Srwatson n = getauevnonam(optarg); 731155131Srwatson if (n == NULL) 732155131Srwatson usage("Incorrect event name"); 733185573Srwatson *etp = *n; 734155131Srwatson } 735155131Srwatson SETOPT(opttochk, OPT_m); 736155131Srwatson break; 737155131Srwatson 738155131Srwatson case 'o': 739155131Srwatson objval = strchr(optarg, '='); 740155131Srwatson if (objval != NULL) { 741155131Srwatson *objval = '\0'; 742155131Srwatson objval += 1; 743155131Srwatson parse_object_type(optarg, objval); 744155131Srwatson } 745155131Srwatson break; 746155131Srwatson 747155131Srwatson case 'r': 748155131Srwatson p_ruid = strtol(optarg, &converr, 10); 749155131Srwatson if (*converr != '\0') { 750155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 751155131Srwatson break; 752155131Srwatson p_ruid = pw->pw_uid; 753155131Srwatson } 754155131Srwatson SETOPT(opttochk, OPT_r); 755155131Srwatson break; 756155131Srwatson 757155131Srwatson case 'u': 758155131Srwatson p_auid = strtol(optarg, &converr, 10); 759155131Srwatson if (*converr != '\0') { 760155131Srwatson if ((pw = getpwnam(optarg)) == NULL) 761155131Srwatson break; 762155131Srwatson p_auid = pw->pw_uid; 763155131Srwatson } 764155131Srwatson SETOPT(opttochk, OPT_u); 765155131Srwatson break; 766155131Srwatson 767185573Srwatson case 'v': 768185573Srwatson SETOPT(opttochk, OPT_v); 769185573Srwatson break; 770185573Srwatson 771155131Srwatson case '?': 772155131Srwatson default: 773155131Srwatson usage("Unknown option"); 774155131Srwatson } 775155131Srwatson } 776155131Srwatson argv += optind; 777155131Srwatson argc -= optind; 778155131Srwatson 779162621Srwatson if (argc == 0) { 780162621Srwatson if (select_records(stdin) == -1) 781162621Srwatson errx(EXIT_FAILURE, 782162621Srwatson "Couldn't select records from stdin"); 783162621Srwatson exit(EXIT_SUCCESS); 784162621Srwatson } 785155131Srwatson 786155131Srwatson /* 787155131Srwatson * XXX: We should actually be merging records here. 788155131Srwatson */ 789155131Srwatson for (i = 0; i < argc; i++) { 790155131Srwatson fname = argv[i]; 791155131Srwatson fp = fopen(fname, "r"); 792155131Srwatson if (fp == NULL) 793155131Srwatson errx(EXIT_FAILURE, "Couldn't open %s", fname); 794155131Srwatson if (select_records(fp) == -1) { 795155131Srwatson errx(EXIT_FAILURE, "Couldn't select records %s", 796155131Srwatson fname); 797155131Srwatson } 798155131Srwatson fclose(fp); 799155131Srwatson } 800155131Srwatson exit(EXIT_SUCCESS); 801155131Srwatson} 802