1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * Command line option processing for auditreduce. 31*7c478bd9Sstevel@tonic-gate * The entry point is process_options(), which is called by main(). 32*7c478bd9Sstevel@tonic-gate * Process_options() is the only function visible outside this module. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <locale.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/zone.h> /* for max zonename length */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #ifdef TSOL 39*7c478bd9Sstevel@tonic-gate #include <tsol/label.h> 40*7c478bd9Sstevel@tonic-gate #endif /* TSOL */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "auditr.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate /* 45*7c478bd9Sstevel@tonic-gate * Object entry. 46*7c478bd9Sstevel@tonic-gate * Maps object strings specified on the command line to a flag 47*7c478bd9Sstevel@tonic-gate * used when searching by object type. 48*7c478bd9Sstevel@tonic-gate */ 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate struct obj_ent { 51*7c478bd9Sstevel@tonic-gate char *obj_str; /* string specified on the command line */ 52*7c478bd9Sstevel@tonic-gate int obj_flag; /* flag used when searching */ 53*7c478bd9Sstevel@tonic-gate }; 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate typedef struct obj_ent obj_ent_t; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate /* 58*7c478bd9Sstevel@tonic-gate * Supports searches by object type. 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate static obj_ent_t obj_tbl[] = { 61*7c478bd9Sstevel@tonic-gate { "file", OBJ_PATH }, 62*7c478bd9Sstevel@tonic-gate { "filegroup", OBJ_FGROUP }, 63*7c478bd9Sstevel@tonic-gate { "fileowner", OBJ_FOWNER }, 64*7c478bd9Sstevel@tonic-gate { "lp", OBJ_LP }, 65*7c478bd9Sstevel@tonic-gate { "msgqid", OBJ_MSG }, 66*7c478bd9Sstevel@tonic-gate { "msgqgroup", OBJ_MSGGROUP }, 67*7c478bd9Sstevel@tonic-gate { "msgqowner", OBJ_MSGOWNER }, 68*7c478bd9Sstevel@tonic-gate { "path", OBJ_PATH }, 69*7c478bd9Sstevel@tonic-gate { "pid", OBJ_PROC }, 70*7c478bd9Sstevel@tonic-gate { "procgroup", OBJ_PGROUP }, 71*7c478bd9Sstevel@tonic-gate { "procowner", OBJ_POWNER }, 72*7c478bd9Sstevel@tonic-gate { "semid", OBJ_SEM }, 73*7c478bd9Sstevel@tonic-gate { "semgroup", OBJ_SEMGROUP }, 74*7c478bd9Sstevel@tonic-gate { "semowner", OBJ_SEMOWNER }, 75*7c478bd9Sstevel@tonic-gate { "shmid", OBJ_SHM }, 76*7c478bd9Sstevel@tonic-gate { "shmgroup", OBJ_SHMGROUP }, 77*7c478bd9Sstevel@tonic-gate { "shmowner", OBJ_SHMOWNER }, 78*7c478bd9Sstevel@tonic-gate { "sock", OBJ_SOCK } }; 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate extern int derive_date(char *, struct tm *); 81*7c478bd9Sstevel@tonic-gate extern int parse_time(char *, int); 82*7c478bd9Sstevel@tonic-gate extern char *re_comp2(char *); 83*7c478bd9Sstevel@tonic-gate extern time_t tm_to_secs(struct tm *); 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate static int a_isnum(char *, int); 86*7c478bd9Sstevel@tonic-gate static int check_file(audit_fcb_t *, int); 87*7c478bd9Sstevel@tonic-gate static int gather_dir(char *); 88*7c478bd9Sstevel@tonic-gate static audit_pcb_t *get_next_pcb(char *); 89*7c478bd9Sstevel@tonic-gate static obj_ent_t *obj_lkup(char *); 90*7c478bd9Sstevel@tonic-gate static int proc_class(char *); 91*7c478bd9Sstevel@tonic-gate static int proc_date(char *, int); 92*7c478bd9Sstevel@tonic-gate static int proc_file(char *, int); 93*7c478bd9Sstevel@tonic-gate static int process_fileopt(int, char *argv[], int); 94*7c478bd9Sstevel@tonic-gate static int proc_group(char *, gid_t *); 95*7c478bd9Sstevel@tonic-gate static int proc_id(char *, int); 96*7c478bd9Sstevel@tonic-gate static int proc_object(char *); 97*7c478bd9Sstevel@tonic-gate static void proc_pcb(audit_pcb_t *, char *, int); 98*7c478bd9Sstevel@tonic-gate #ifdef TSOL 99*7c478bd9Sstevel@tonic-gate static int proc_slabel(char *); 100*7c478bd9Sstevel@tonic-gate #endif /* TSOL */ 101*7c478bd9Sstevel@tonic-gate static int proc_subject(char *); 102*7c478bd9Sstevel@tonic-gate static int proc_type(char *); 103*7c478bd9Sstevel@tonic-gate static int proc_user(char *, uid_t *); 104*7c478bd9Sstevel@tonic-gate static int proc_zonename(char *); 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* 107*7c478bd9Sstevel@tonic-gate * .func process_options - process command line options. 108*7c478bd9Sstevel@tonic-gate * .desc Process the user's command line options. These are of two types: 109*7c478bd9Sstevel@tonic-gate * single letter flags that are denoted by '-', and filenames. Some 110*7c478bd9Sstevel@tonic-gate * of the flags have arguments. Getopt() is used to get the flags. 111*7c478bd9Sstevel@tonic-gate * When this is done it calls process_fileopt() to handle any filenames 112*7c478bd9Sstevel@tonic-gate * that were there. 113*7c478bd9Sstevel@tonic-gate * .call ret = process_options(argc, argv). 114*7c478bd9Sstevel@tonic-gate * .arg argc - the original value. 115*7c478bd9Sstevel@tonic-gate * .arg argv - the original value. 116*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 117*7c478bd9Sstevel@tonic-gate * .ret -1 - command line error detected (message already printed). 118*7c478bd9Sstevel@tonic-gate */ 119*7c478bd9Sstevel@tonic-gate int 120*7c478bd9Sstevel@tonic-gate process_options(int argc, char **argv) 121*7c478bd9Sstevel@tonic-gate { 122*7c478bd9Sstevel@tonic-gate int opt; 123*7c478bd9Sstevel@tonic-gate int error = FALSE; 124*7c478bd9Sstevel@tonic-gate int error_combo = FALSE; 125*7c478bd9Sstevel@tonic-gate extern int optind; /* in getopt() */ 126*7c478bd9Sstevel@tonic-gate extern char *optarg; /* in getopt() - holds arg to flag */ 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate static char *options = "ACD:M:NQR:S:VO:a:b:c:d:e:g:j:m:o:r:s:u:z:"; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate error_str = gettext("general error"); 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate zonename = NULL; 133*7c478bd9Sstevel@tonic-gate /* 134*7c478bd9Sstevel@tonic-gate * Big switch to process the flags. 135*7c478bd9Sstevel@tonic-gate * Start_over: is for handling the '-' for standard input. Getopt() 136*7c478bd9Sstevel@tonic-gate * doesn't recognize it. 137*7c478bd9Sstevel@tonic-gate */ 138*7c478bd9Sstevel@tonic-gate start_over: 139*7c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, options)) != EOF) { 140*7c478bd9Sstevel@tonic-gate switch (opt) { 141*7c478bd9Sstevel@tonic-gate case 'A': /* all records from the files */ 142*7c478bd9Sstevel@tonic-gate f_all = TRUE; 143*7c478bd9Sstevel@tonic-gate break; 144*7c478bd9Sstevel@tonic-gate case 'C': /* process only completed files */ 145*7c478bd9Sstevel@tonic-gate f_complete = TRUE; 146*7c478bd9Sstevel@tonic-gate break; 147*7c478bd9Sstevel@tonic-gate case 'D': /* delete the files when done */ 148*7c478bd9Sstevel@tonic-gate /* force 'A' 'C' 'O' to be active */ 149*7c478bd9Sstevel@tonic-gate f_all = f_complete = TRUE; 150*7c478bd9Sstevel@tonic-gate f_outfile = optarg; 151*7c478bd9Sstevel@tonic-gate f_delete = TRUE; 152*7c478bd9Sstevel@tonic-gate break; 153*7c478bd9Sstevel@tonic-gate case 'M': /* only files from a certain machine */ 154*7c478bd9Sstevel@tonic-gate f_machine = optarg; 155*7c478bd9Sstevel@tonic-gate break; 156*7c478bd9Sstevel@tonic-gate case 'N': /* new object selection mode */ 157*7c478bd9Sstevel@tonic-gate new_mode = TRUE; 158*7c478bd9Sstevel@tonic-gate break; 159*7c478bd9Sstevel@tonic-gate case 'Q': /* no file error reporting */ 160*7c478bd9Sstevel@tonic-gate f_quiet = TRUE; 161*7c478bd9Sstevel@tonic-gate break; 162*7c478bd9Sstevel@tonic-gate case 'R': /* from specified root */ 163*7c478bd9Sstevel@tonic-gate f_root = optarg; 164*7c478bd9Sstevel@tonic-gate break; 165*7c478bd9Sstevel@tonic-gate case 'S': /* from specified server */ 166*7c478bd9Sstevel@tonic-gate f_server = optarg; 167*7c478bd9Sstevel@tonic-gate break; 168*7c478bd9Sstevel@tonic-gate case 'V': /* list all files as they are opened */ 169*7c478bd9Sstevel@tonic-gate f_verbose = TRUE; 170*7c478bd9Sstevel@tonic-gate break; 171*7c478bd9Sstevel@tonic-gate case 'O': /* write to outfile */ 172*7c478bd9Sstevel@tonic-gate f_outfile = optarg; 173*7c478bd9Sstevel@tonic-gate break; 174*7c478bd9Sstevel@tonic-gate case 'a': /* after 'date' */ 175*7c478bd9Sstevel@tonic-gate case 'b': /* before 'date' */ 176*7c478bd9Sstevel@tonic-gate case 'd': /* from 'day' */ 177*7c478bd9Sstevel@tonic-gate if (proc_date(optarg, opt)) 178*7c478bd9Sstevel@tonic-gate error = TRUE; 179*7c478bd9Sstevel@tonic-gate break; 180*7c478bd9Sstevel@tonic-gate case 'j': /* subject */ 181*7c478bd9Sstevel@tonic-gate if (proc_subject(optarg)) 182*7c478bd9Sstevel@tonic-gate error = TRUE; 183*7c478bd9Sstevel@tonic-gate break; 184*7c478bd9Sstevel@tonic-gate case 'm': /* message 'type' */ 185*7c478bd9Sstevel@tonic-gate if (proc_type(optarg)) 186*7c478bd9Sstevel@tonic-gate error = TRUE; 187*7c478bd9Sstevel@tonic-gate break; 188*7c478bd9Sstevel@tonic-gate case 'o': /* object type */ 189*7c478bd9Sstevel@tonic-gate if (proc_object(optarg)) 190*7c478bd9Sstevel@tonic-gate error = TRUE; 191*7c478bd9Sstevel@tonic-gate break; 192*7c478bd9Sstevel@tonic-gate case 'c': /* message class */ 193*7c478bd9Sstevel@tonic-gate if (proc_class(optarg)) 194*7c478bd9Sstevel@tonic-gate error = TRUE; 195*7c478bd9Sstevel@tonic-gate break; 196*7c478bd9Sstevel@tonic-gate case 'u': /* form audit user */ 197*7c478bd9Sstevel@tonic-gate case 'e': /* form effective user */ 198*7c478bd9Sstevel@tonic-gate case 'r': /* form real user */ 199*7c478bd9Sstevel@tonic-gate case 'f': /* form effective group */ 200*7c478bd9Sstevel@tonic-gate case 'g': /* form real group */ 201*7c478bd9Sstevel@tonic-gate if (proc_id(optarg, opt)) 202*7c478bd9Sstevel@tonic-gate error = TRUE; 203*7c478bd9Sstevel@tonic-gate break; 204*7c478bd9Sstevel@tonic-gate #ifdef TSOL 205*7c478bd9Sstevel@tonic-gate case 's': /* sensitivity label range */ 206*7c478bd9Sstevel@tonic-gate if (proc_slabel(optarg)) 207*7c478bd9Sstevel@tonic-gate error = TRUE; 208*7c478bd9Sstevel@tonic-gate break; 209*7c478bd9Sstevel@tonic-gate #endif /* TSOL */ 210*7c478bd9Sstevel@tonic-gate case 'z': /* zone name */ 211*7c478bd9Sstevel@tonic-gate if (proc_zonename(optarg)) 212*7c478bd9Sstevel@tonic-gate error = TRUE; 213*7c478bd9Sstevel@tonic-gate break; 214*7c478bd9Sstevel@tonic-gate default: 215*7c478bd9Sstevel@tonic-gate return (-1); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate if (error) { 218*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 219*7c478bd9Sstevel@tonic-gate gettext("%s command line error - %s.\n"), 220*7c478bd9Sstevel@tonic-gate ar, error_str); 221*7c478bd9Sstevel@tonic-gate return (-1); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate } 224*7c478bd9Sstevel@tonic-gate /* catch '-' option for stdin processing - getopt() won't see it */ 225*7c478bd9Sstevel@tonic-gate if (optind < argc) { 226*7c478bd9Sstevel@tonic-gate if (argv[optind][0] == '-' && argv[optind][1] == '\0') { 227*7c478bd9Sstevel@tonic-gate optind++; 228*7c478bd9Sstevel@tonic-gate f_stdin = TRUE; 229*7c478bd9Sstevel@tonic-gate goto start_over; 230*7c478bd9Sstevel@tonic-gate } 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate /* 233*7c478bd9Sstevel@tonic-gate * Give a default value for 'b' option if not specified. 234*7c478bd9Sstevel@tonic-gate */ 235*7c478bd9Sstevel@tonic-gate if (m_before == 0) 236*7c478bd9Sstevel@tonic-gate m_before = MAXLONG; /* forever */ 237*7c478bd9Sstevel@tonic-gate /* 238*7c478bd9Sstevel@tonic-gate * Validate combinations of options. 239*7c478bd9Sstevel@tonic-gate * The following are done: 240*7c478bd9Sstevel@tonic-gate * 1. Can't have 'M' or 'S' or 'R' with filenames. 241*7c478bd9Sstevel@tonic-gate * 2. Can't have an after ('a') time after a before ('b') time. 242*7c478bd9Sstevel@tonic-gate * 3. Delete ('D') must have 'C' and 'A' and 'O' with it. 243*7c478bd9Sstevel@tonic-gate * 4. Input from stdin ('-') can't have filenames too. 244*7c478bd9Sstevel@tonic-gate */ 245*7c478bd9Sstevel@tonic-gate if ((f_machine || f_server || f_root) && (argc != optind)) { 246*7c478bd9Sstevel@tonic-gate error_str = gettext( 247*7c478bd9Sstevel@tonic-gate "no filenames allowed with 'M' or 'S' or 'R' options"); 248*7c478bd9Sstevel@tonic-gate error_combo = TRUE; 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate if (m_after >= m_before) { 251*7c478bd9Sstevel@tonic-gate error_str = 252*7c478bd9Sstevel@tonic-gate gettext("'a' parameter must be before 'b' parameter"); 253*7c478bd9Sstevel@tonic-gate error_combo = TRUE; 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate if (f_delete && 256*7c478bd9Sstevel@tonic-gate (!f_complete || !f_all || !f_outfile)) { 257*7c478bd9Sstevel@tonic-gate error_str = gettext( 258*7c478bd9Sstevel@tonic-gate "'C', 'A', and 'O' must be specified with 'D'"); 259*7c478bd9Sstevel@tonic-gate error_combo = TRUE; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate if (f_stdin && (argc != optind)) { 262*7c478bd9Sstevel@tonic-gate error_str = gettext("no filenames allowed with '-' option"); 263*7c478bd9Sstevel@tonic-gate error_combo = TRUE; 264*7c478bd9Sstevel@tonic-gate } 265*7c478bd9Sstevel@tonic-gate /* 266*7c478bd9Sstevel@tonic-gate * If error with option combos then print message and exit. 267*7c478bd9Sstevel@tonic-gate * If there was an error with just an option then exit. 268*7c478bd9Sstevel@tonic-gate */ 269*7c478bd9Sstevel@tonic-gate if (error_combo) { 270*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 271*7c478bd9Sstevel@tonic-gate gettext("%s command line error - %s.\n"), ar, error_str); 272*7c478bd9Sstevel@tonic-gate return (-1); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate if (f_root == NULL) 275*7c478bd9Sstevel@tonic-gate f_root = "/etc/security/audit"; 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * Now handle any filenames included in the command line. 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate return (process_fileopt(argc, argv, optind)); 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate int 283*7c478bd9Sstevel@tonic-gate proc_subject(char *optarg) 284*7c478bd9Sstevel@tonic-gate { 285*7c478bd9Sstevel@tonic-gate if (flags & M_SUBJECT) { 286*7c478bd9Sstevel@tonic-gate error_str = gettext("'j' option specified multiple times"); 287*7c478bd9Sstevel@tonic-gate return (-1); 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate flags |= M_SUBJECT; 290*7c478bd9Sstevel@tonic-gate subj_id = atol(optarg); 291*7c478bd9Sstevel@tonic-gate return (0); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate int 296*7c478bd9Sstevel@tonic-gate proc_object(char *optarg) 297*7c478bd9Sstevel@tonic-gate { 298*7c478bd9Sstevel@tonic-gate char *obj_str; 299*7c478bd9Sstevel@tonic-gate char *obj_val; 300*7c478bd9Sstevel@tonic-gate char *obj_arg; 301*7c478bd9Sstevel@tonic-gate int err; 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate obj_ent_t *oep; 304*7c478bd9Sstevel@tonic-gate struct hostent *he; 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate if (flags & M_OBJECT) { 307*7c478bd9Sstevel@tonic-gate error_str = gettext("'o' option specified multiple times"); 308*7c478bd9Sstevel@tonic-gate return (-1); 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate flags |= M_OBJECT; 311*7c478bd9Sstevel@tonic-gate if ((obj_arg = strdup(optarg)) == (char *)0) 312*7c478bd9Sstevel@tonic-gate return (-1); 313*7c478bd9Sstevel@tonic-gate if ((obj_str = strtok(optarg, "=")) == (char *)0 || 314*7c478bd9Sstevel@tonic-gate (oep = obj_lkup(obj_str)) == (obj_ent_t *)0 || 315*7c478bd9Sstevel@tonic-gate (obj_val = strtok((char *)0, "=")) == (char *)0) { 316*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid object arg (%s)"), 317*7c478bd9Sstevel@tonic-gate obj_arg); 318*7c478bd9Sstevel@tonic-gate error_str = errbuf; 319*7c478bd9Sstevel@tonic-gate return (-1); 320*7c478bd9Sstevel@tonic-gate } 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate obj_flag = oep->obj_flag; 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate switch (obj_flag) { 325*7c478bd9Sstevel@tonic-gate case OBJ_PATH: 326*7c478bd9Sstevel@tonic-gate if ((error_str = re_comp2(obj_val)) != (char *)NULL) { 327*7c478bd9Sstevel@tonic-gate return (-1); 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate return (0); 330*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 331*7c478bd9Sstevel@tonic-gate case OBJ_SOCK: 332*7c478bd9Sstevel@tonic-gate if (!a_isnum(obj_val, TRUE)) { 333*7c478bd9Sstevel@tonic-gate obj_id = atol(obj_val); 334*7c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_PORT; 335*7c478bd9Sstevel@tonic-gate return (0); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate if (*obj_val == '0') { 338*7c478bd9Sstevel@tonic-gate (void) sscanf(obj_val, "%x", (uint_t *)&obj_id); 339*7c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_PORT; 340*7c478bd9Sstevel@tonic-gate return (0); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate he = getipnodebyname((const void *)obj_val, AF_INET6, 0, &err); 344*7c478bd9Sstevel@tonic-gate if (he == 0) { 345*7c478bd9Sstevel@tonic-gate he = getipnodebyname((const void *)obj_val, AF_INET, 346*7c478bd9Sstevel@tonic-gate 0, &err); 347*7c478bd9Sstevel@tonic-gate if (he == 0) { 348*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 349*7c478bd9Sstevel@tonic-gate gettext("invalid machine name (%s)"), 350*7c478bd9Sstevel@tonic-gate obj_val); 351*7c478bd9Sstevel@tonic-gate error_str = errbuf; 352*7c478bd9Sstevel@tonic-gate return (-1); 353*7c478bd9Sstevel@tonic-gate } 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate if (he->h_addrtype == AF_INET6) { 357*7c478bd9Sstevel@tonic-gate /* LINTED */ 358*7c478bd9Sstevel@tonic-gate if (IN6_IS_ADDR_V4MAPPED((in6_addr_t *) 359*7c478bd9Sstevel@tonic-gate he->h_addr_list[0])) { 360*7c478bd9Sstevel@tonic-gate /* address is IPv4 (32 bits) */ 361*7c478bd9Sstevel@tonic-gate (void) memcpy(&obj_id, he->h_addr_list[0], 4); 362*7c478bd9Sstevel@tonic-gate ip_type = AU_IPv4; 363*7c478bd9Sstevel@tonic-gate } else { 364*7c478bd9Sstevel@tonic-gate (void) memcpy(ip_ipv6, he->h_addr_list[0], 16); 365*7c478bd9Sstevel@tonic-gate ip_type = AU_IPv6; 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate } else { 368*7c478bd9Sstevel@tonic-gate /* address is IPv4 (32 bits) */ 369*7c478bd9Sstevel@tonic-gate (void) memcpy(&obj_id, he->h_addr_list[0], 4); 370*7c478bd9Sstevel@tonic-gate ip_type = AU_IPv4; 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate freehostent(he); 374*7c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_MACHINE; 375*7c478bd9Sstevel@tonic-gate return (0); 376*7c478bd9Sstevel@tonic-gate break; 377*7c478bd9Sstevel@tonic-gate case OBJ_MSG: 378*7c478bd9Sstevel@tonic-gate case OBJ_SEM: 379*7c478bd9Sstevel@tonic-gate case OBJ_SHM: 380*7c478bd9Sstevel@tonic-gate case OBJ_PROC: 381*7c478bd9Sstevel@tonic-gate obj_id = atol(obj_val); 382*7c478bd9Sstevel@tonic-gate return (0); 383*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 384*7c478bd9Sstevel@tonic-gate case OBJ_FGROUP: 385*7c478bd9Sstevel@tonic-gate case OBJ_MSGGROUP: 386*7c478bd9Sstevel@tonic-gate case OBJ_SEMGROUP: 387*7c478bd9Sstevel@tonic-gate case OBJ_SHMGROUP: 388*7c478bd9Sstevel@tonic-gate case OBJ_PGROUP: 389*7c478bd9Sstevel@tonic-gate return (proc_group(obj_val, &obj_group)); 390*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 391*7c478bd9Sstevel@tonic-gate case OBJ_FOWNER: 392*7c478bd9Sstevel@tonic-gate case OBJ_MSGOWNER: 393*7c478bd9Sstevel@tonic-gate case OBJ_SEMOWNER: 394*7c478bd9Sstevel@tonic-gate case OBJ_SHMOWNER: 395*7c478bd9Sstevel@tonic-gate case OBJ_POWNER: 396*7c478bd9Sstevel@tonic-gate return (proc_user(obj_val, &obj_owner)); 397*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 398*7c478bd9Sstevel@tonic-gate case OBJ_LP: /* lp objects have not yet been defined */ 399*7c478bd9Sstevel@tonic-gate default: /* impossible */ 400*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid object type (%s)"), 401*7c478bd9Sstevel@tonic-gate obj_str); 402*7c478bd9Sstevel@tonic-gate error_str = errbuf; 403*7c478bd9Sstevel@tonic-gate return (-1); 404*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 405*7c478bd9Sstevel@tonic-gate } /* switch */ 406*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate obj_ent_t * 411*7c478bd9Sstevel@tonic-gate obj_lkup(char *obj_str) 412*7c478bd9Sstevel@tonic-gate { 413*7c478bd9Sstevel@tonic-gate int i; 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (obj_tbl) / sizeof (obj_ent_t); i++) 416*7c478bd9Sstevel@tonic-gate if (strcmp(obj_str, obj_tbl[i].obj_str) == 0) 417*7c478bd9Sstevel@tonic-gate return (&obj_tbl[i]); 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate /* not in table */ 420*7c478bd9Sstevel@tonic-gate return ((obj_ent_t *)0); 421*7c478bd9Sstevel@tonic-gate } 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * .func proc_type - process record type. 426*7c478bd9Sstevel@tonic-gate * .desc Process a record type. It is either as a number or a mnemonic. 427*7c478bd9Sstevel@tonic-gate * .call ret = proc_type(optstr). 428*7c478bd9Sstevel@tonic-gate * .arg optstr - ptr to name or number. 429*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 430*7c478bd9Sstevel@tonic-gate * .ret -1 - error detected (error_str contains description). 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate int 433*7c478bd9Sstevel@tonic-gate proc_type(char *optstr) 434*7c478bd9Sstevel@tonic-gate { 435*7c478bd9Sstevel@tonic-gate struct au_event_ent *aep; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate /* 438*7c478bd9Sstevel@tonic-gate * Either a number or a name. 439*7c478bd9Sstevel@tonic-gate */ 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate if (flags & M_TYPE) { 442*7c478bd9Sstevel@tonic-gate error_str = gettext("'m' option specified multiple times"); 443*7c478bd9Sstevel@tonic-gate return (-1); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate flags |= M_TYPE; 446*7c478bd9Sstevel@tonic-gate m_type = 0; 447*7c478bd9Sstevel@tonic-gate if (a_isnum(optstr, TRUE)) { 448*7c478bd9Sstevel@tonic-gate if ((aep = getauevnam(optstr)) != (struct au_event_ent *)NULL) 449*7c478bd9Sstevel@tonic-gate m_type = aep->ae_number; 450*7c478bd9Sstevel@tonic-gate } else { 451*7c478bd9Sstevel@tonic-gate if ((aep = getauevnum((au_event_t)atoi(optstr))) != 452*7c478bd9Sstevel@tonic-gate (struct au_event_ent *)NULL) 453*7c478bd9Sstevel@tonic-gate m_type = aep->ae_number; 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate if ((m_type == 0)) { 456*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid event (%s)"), optstr); 457*7c478bd9Sstevel@tonic-gate error_str = errbuf; 458*7c478bd9Sstevel@tonic-gate return (-1); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate return (0); 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate /* 465*7c478bd9Sstevel@tonic-gate * .func a_isnum - is it a number? 466*7c478bd9Sstevel@tonic-gate * .desc Determine if a string is a number or a name. 467*7c478bd9Sstevel@tonic-gate * A number may have a leading '+' or '-', but then must be 468*7c478bd9Sstevel@tonic-gate * all digits. 469*7c478bd9Sstevel@tonic-gate * .call ret = a_isnum(str). 470*7c478bd9Sstevel@tonic-gate * .arg str - ptr to the string. 471*7c478bd9Sstevel@tonic-gate * .arg leading - TRUE if leading '+-' allowed. 472*7c478bd9Sstevel@tonic-gate * .ret 0 - is a number. 473*7c478bd9Sstevel@tonic-gate * .ret 1 - is not a number. 474*7c478bd9Sstevel@tonic-gate */ 475*7c478bd9Sstevel@tonic-gate int 476*7c478bd9Sstevel@tonic-gate a_isnum(char *str, int leading) 477*7c478bd9Sstevel@tonic-gate { 478*7c478bd9Sstevel@tonic-gate char *strs; 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate if ((leading == TRUE) && (*str == '-' || *str == '+')) 481*7c478bd9Sstevel@tonic-gate strs = str + 1; 482*7c478bd9Sstevel@tonic-gate else 483*7c478bd9Sstevel@tonic-gate strs = str; 484*7c478bd9Sstevel@tonic-gate 485*7c478bd9Sstevel@tonic-gate if (strlen(strs) == strspn(strs, "0123456789")) 486*7c478bd9Sstevel@tonic-gate return (0); 487*7c478bd9Sstevel@tonic-gate else 488*7c478bd9Sstevel@tonic-gate return (1); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate /* 493*7c478bd9Sstevel@tonic-gate * .func proc_id - process user/group id's/ 494*7c478bd9Sstevel@tonic-gate * .desc Process either a user number/name or group number/name. 495*7c478bd9Sstevel@tonic-gate * For names check to see if the name is active in the system 496*7c478bd9Sstevel@tonic-gate * to derive the number. If it is not active then fail. For a number 497*7c478bd9Sstevel@tonic-gate * also check to see if it is active, but only print a warning if it 498*7c478bd9Sstevel@tonic-gate * is not. An administrator may be looking at activity of a 'phantom' 499*7c478bd9Sstevel@tonic-gate * user. 500*7c478bd9Sstevel@tonic-gate * .call ret = proc_id(optstr, opt). 501*7c478bd9Sstevel@tonic-gate * .arg optstr - ptr to name or number. 502*7c478bd9Sstevel@tonic-gate * .arg opt - 'u' - audit user, 'e' - effective user, 'r' - real user, 503*7c478bd9Sstevel@tonic-gate * 'g' - group, 'f' - effective group. 504*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 505*7c478bd9Sstevel@tonic-gate * .ret -1 - error detected (error_str contains description). 506*7c478bd9Sstevel@tonic-gate */ 507*7c478bd9Sstevel@tonic-gate int 508*7c478bd9Sstevel@tonic-gate proc_id(char *optstr, int opt) 509*7c478bd9Sstevel@tonic-gate { 510*7c478bd9Sstevel@tonic-gate switch (opt) { 511*7c478bd9Sstevel@tonic-gate case 'e': /* effective user id */ 512*7c478bd9Sstevel@tonic-gate if (flags & M_USERE) { 513*7c478bd9Sstevel@tonic-gate error_str = gettext( 514*7c478bd9Sstevel@tonic-gate "'e' option specified multiple times"); 515*7c478bd9Sstevel@tonic-gate return (-1); 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate flags |= M_USERE; 518*7c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_usere)); 519*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 520*7c478bd9Sstevel@tonic-gate case 'f': /* effective group id */ 521*7c478bd9Sstevel@tonic-gate if (flags & M_GROUPE) { 522*7c478bd9Sstevel@tonic-gate error_str = gettext( 523*7c478bd9Sstevel@tonic-gate "'f' option specified multiple times"); 524*7c478bd9Sstevel@tonic-gate return (-1); 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate flags |= M_GROUPE; 527*7c478bd9Sstevel@tonic-gate return (proc_group(optstr, &m_groupe)); 528*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 529*7c478bd9Sstevel@tonic-gate case 'r': /* real user id */ 530*7c478bd9Sstevel@tonic-gate if (flags & M_USERR) { 531*7c478bd9Sstevel@tonic-gate error_str = gettext( 532*7c478bd9Sstevel@tonic-gate "'r' option specified multiple times"); 533*7c478bd9Sstevel@tonic-gate return (-1); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate flags |= M_USERR; 536*7c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_userr)); 537*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 538*7c478bd9Sstevel@tonic-gate case 'u': /* audit user id */ 539*7c478bd9Sstevel@tonic-gate if (flags & M_USERA) { 540*7c478bd9Sstevel@tonic-gate error_str = gettext( 541*7c478bd9Sstevel@tonic-gate "'u' option specified multiple times"); 542*7c478bd9Sstevel@tonic-gate return (-1); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate flags |= M_USERA; 545*7c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_usera)); 546*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 547*7c478bd9Sstevel@tonic-gate case 'g': /* real group id */ 548*7c478bd9Sstevel@tonic-gate if (flags & M_GROUPR) { 549*7c478bd9Sstevel@tonic-gate error_str = gettext( 550*7c478bd9Sstevel@tonic-gate "'g' option specified multiple times"); 551*7c478bd9Sstevel@tonic-gate return (-1); 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate flags |= M_GROUPR; 554*7c478bd9Sstevel@tonic-gate return (proc_group(optstr, &m_groupr)); 555*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 556*7c478bd9Sstevel@tonic-gate default: /* impossible */ 557*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("'%c' unknown option"), opt); 558*7c478bd9Sstevel@tonic-gate error_str = errbuf; 559*7c478bd9Sstevel@tonic-gate return (-1); 560*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate int 567*7c478bd9Sstevel@tonic-gate proc_group(char *optstr, gid_t *gid) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate struct group *grp; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate if ((grp = getgrnam(optstr)) == NULL) { 572*7c478bd9Sstevel@tonic-gate if (!a_isnum(optstr, TRUE)) { 573*7c478bd9Sstevel@tonic-gate *gid = (gid_t)atoi(optstr); 574*7c478bd9Sstevel@tonic-gate return (0); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("group name invalid (%s)"), 577*7c478bd9Sstevel@tonic-gate optstr); 578*7c478bd9Sstevel@tonic-gate error_str = errbuf; 579*7c478bd9Sstevel@tonic-gate return (-1); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate *gid = grp->gr_gid; 582*7c478bd9Sstevel@tonic-gate return (0); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate int 587*7c478bd9Sstevel@tonic-gate proc_user(char *optstr, uid_t *uid) 588*7c478bd9Sstevel@tonic-gate { 589*7c478bd9Sstevel@tonic-gate struct passwd *usr; 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate if ((usr = getpwnam(optstr)) == NULL) { 592*7c478bd9Sstevel@tonic-gate if (!a_isnum(optstr, TRUE)) { 593*7c478bd9Sstevel@tonic-gate *uid = (uid_t)atoi(optstr); 594*7c478bd9Sstevel@tonic-gate return (0); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("user name invalid (%s)"), 597*7c478bd9Sstevel@tonic-gate optstr); 598*7c478bd9Sstevel@tonic-gate error_str = errbuf; 599*7c478bd9Sstevel@tonic-gate return (-1); 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate *uid = usr->pw_uid; 602*7c478bd9Sstevel@tonic-gate return (0); 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* 607*7c478bd9Sstevel@tonic-gate * .func proc_date - process date argument. 608*7c478bd9Sstevel@tonic-gate * .desc Handle a date/time argument. See if the user has erred in combining 609*7c478bd9Sstevel@tonic-gate * the types of date arguments. Then parse the string and check for 610*7c478bd9Sstevel@tonic-gate * validity of each part. 611*7c478bd9Sstevel@tonic-gate * .call ret = proc_date(optstr, opt). 612*7c478bd9Sstevel@tonic-gate * .arg optstr - ptr to date/time string. 613*7c478bd9Sstevel@tonic-gate * .arg opt - 'd' for day, 'a' for after, or 'b' for before. 614*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 615*7c478bd9Sstevel@tonic-gate * .ret -1 - errors detected (error_str knows what it is). 616*7c478bd9Sstevel@tonic-gate */ 617*7c478bd9Sstevel@tonic-gate int 618*7c478bd9Sstevel@tonic-gate proc_date(char *optstr, int opt) 619*7c478bd9Sstevel@tonic-gate { 620*7c478bd9Sstevel@tonic-gate static int m_day = FALSE; 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate if (opt == 'd') { 623*7c478bd9Sstevel@tonic-gate if (m_day == TRUE) { 624*7c478bd9Sstevel@tonic-gate error_str = gettext( 625*7c478bd9Sstevel@tonic-gate "'d' option may not be used with 'a' or 'b'"); 626*7c478bd9Sstevel@tonic-gate return (-1); 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate m_day = TRUE; 629*7c478bd9Sstevel@tonic-gate } 630*7c478bd9Sstevel@tonic-gate if ((opt == 'd') && (m_before || m_after)) { 631*7c478bd9Sstevel@tonic-gate error_str = gettext( 632*7c478bd9Sstevel@tonic-gate "'d' option may not be used with 'a' or 'b'"); 633*7c478bd9Sstevel@tonic-gate return (-1); 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate if ((opt == 'a' || opt == 'b') && m_day) { 636*7c478bd9Sstevel@tonic-gate error_str = gettext( 637*7c478bd9Sstevel@tonic-gate "'a' or 'b' option may not be used with 'd'"); 638*7c478bd9Sstevel@tonic-gate return (-1); 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate if ((opt == 'a') && (m_after != 0)) { 641*7c478bd9Sstevel@tonic-gate error_str = gettext("'a' option specified multiple times"); 642*7c478bd9Sstevel@tonic-gate return (-1); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate if ((opt == 'b') && (m_before != 0)) { 645*7c478bd9Sstevel@tonic-gate error_str = gettext("'b' option specified multiple times"); 646*7c478bd9Sstevel@tonic-gate return (-1); 647*7c478bd9Sstevel@tonic-gate } 648*7c478bd9Sstevel@tonic-gate if (parse_time(optstr, opt)) 649*7c478bd9Sstevel@tonic-gate return (-1); 650*7c478bd9Sstevel@tonic-gate return (0); 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate /* 655*7c478bd9Sstevel@tonic-gate * .func proc_class - process message class argument. 656*7c478bd9Sstevel@tonic-gate * .desc Process class type and see if it is for real. 657*7c478bd9Sstevel@tonic-gate * .call ret = proc_class(optstr). 658*7c478bd9Sstevel@tonic-gate * .arg optstr - ptr to class. 659*7c478bd9Sstevel@tonic-gate * .ret 0 - class has class. 660*7c478bd9Sstevel@tonic-gate * .ret -1 - class in no good. 661*7c478bd9Sstevel@tonic-gate */ 662*7c478bd9Sstevel@tonic-gate int 663*7c478bd9Sstevel@tonic-gate proc_class(char *optstr) 664*7c478bd9Sstevel@tonic-gate { 665*7c478bd9Sstevel@tonic-gate if (flags & M_CLASS) { 666*7c478bd9Sstevel@tonic-gate error_str = gettext("'c' option specified multiple times"); 667*7c478bd9Sstevel@tonic-gate return (-1); 668*7c478bd9Sstevel@tonic-gate } 669*7c478bd9Sstevel@tonic-gate flags |= M_CLASS; 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate if (getauditflagsbin(optstr, &mask) != 0) { 672*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("unknown class (%s)"), optstr); 673*7c478bd9Sstevel@tonic-gate error_str = errbuf; 674*7c478bd9Sstevel@tonic-gate return (-1); 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate if (mask.am_success != mask.am_failure) { 678*7c478bd9Sstevel@tonic-gate flags |= M_SORF; 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate return (0); 682*7c478bd9Sstevel@tonic-gate } 683*7c478bd9Sstevel@tonic-gate 684*7c478bd9Sstevel@tonic-gate 685*7c478bd9Sstevel@tonic-gate /* 686*7c478bd9Sstevel@tonic-gate * .func process_fileopt - process command line file options. 687*7c478bd9Sstevel@tonic-gate * .desc Process the command line file options and gather the specified files 688*7c478bd9Sstevel@tonic-gate * together in file groups based upon file name suffix. The user can 689*7c478bd9Sstevel@tonic-gate * specify files explicitly on the command line or via a directory. 690*7c478bd9Sstevel@tonic-gate * This is called after the command line flags are processed (as 691*7c478bd9Sstevel@tonic-gate * denoted by '-'). 692*7c478bd9Sstevel@tonic-gate * .call ret = process_fileopt(argc, argv, optindex). 693*7c478bd9Sstevel@tonic-gate * .arg argc - current value of argc. 694*7c478bd9Sstevel@tonic-gate * .arg argv - current value of argv. 695*7c478bd9Sstevel@tonic-gate * .arg optindex- current index into argv (as setup by getopt()). 696*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 697*7c478bd9Sstevel@tonic-gate * .ret -1 - error detected (message already printed). 698*7c478bd9Sstevel@tonic-gate */ 699*7c478bd9Sstevel@tonic-gate int 700*7c478bd9Sstevel@tonic-gate process_fileopt(int argc, char **argv, int optindex) 701*7c478bd9Sstevel@tonic-gate { 702*7c478bd9Sstevel@tonic-gate int f_mode = FM_ALLDIR; 703*7c478bd9Sstevel@tonic-gate char f_dr[MAXNAMLEN+1]; 704*7c478bd9Sstevel@tonic-gate char *f_dir = f_dr; 705*7c478bd9Sstevel@tonic-gate char *fname; 706*7c478bd9Sstevel@tonic-gate static char *std = "standard input"; 707*7c478bd9Sstevel@tonic-gate audit_fcb_t *fcb; 708*7c478bd9Sstevel@tonic-gate DIR * dirp; 709*7c478bd9Sstevel@tonic-gate struct dirent *dp; 710*7c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate /* 713*7c478bd9Sstevel@tonic-gate * Take input from stdin, not any files. 714*7c478bd9Sstevel@tonic-gate * Use a single fcb to do this. 715*7c478bd9Sstevel@tonic-gate */ 716*7c478bd9Sstevel@tonic-gate if (f_stdin) { 717*7c478bd9Sstevel@tonic-gate fcb = (audit_fcb_t *)a_calloc(1, sizeof (*fcb) + strlen(std)); 718*7c478bd9Sstevel@tonic-gate (void) strcpy(fcb->fcb_file, std); 719*7c478bd9Sstevel@tonic-gate fcb->fcb_suffix = fcb->fcb_name = fcb->fcb_file; 720*7c478bd9Sstevel@tonic-gate fcb->fcb_next = NULL; 721*7c478bd9Sstevel@tonic-gate fcb->fcb_start = 0; 722*7c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 723*7c478bd9Sstevel@tonic-gate if ((pcb = get_next_pcb((char *)NULL)) == (audit_pcb_t *)NULL) 724*7c478bd9Sstevel@tonic-gate return (-1); 725*7c478bd9Sstevel@tonic-gate pcb->pcb_suffix = fcb->fcb_file; 726*7c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; /* one-item list */ 727*7c478bd9Sstevel@tonic-gate pcb->pcb_dlast = pcb->pcb_last = fcb; 728*7c478bd9Sstevel@tonic-gate pcb->pcb_cur = fcb; 729*7c478bd9Sstevel@tonic-gate } 730*7c478bd9Sstevel@tonic-gate /* 731*7c478bd9Sstevel@tonic-gate * No files specified on the command line. 732*7c478bd9Sstevel@tonic-gate * Process a directory of files or subdirectories. 733*7c478bd9Sstevel@tonic-gate */ 734*7c478bd9Sstevel@tonic-gate else if (argc == optindex) { 735*7c478bd9Sstevel@tonic-gate /* 736*7c478bd9Sstevel@tonic-gate * A specific server directory was requested. 737*7c478bd9Sstevel@tonic-gate */ 738*7c478bd9Sstevel@tonic-gate if (f_server) { 739*7c478bd9Sstevel@tonic-gate if (strchr(f_server, '/')) { /* given full path */ 740*7c478bd9Sstevel@tonic-gate f_dir = f_server; 741*7c478bd9Sstevel@tonic-gate f_mode = FM_ALLFILE; /* all files here */ 742*7c478bd9Sstevel@tonic-gate } else { /* directory off audit root */ 743*7c478bd9Sstevel@tonic-gate f_dir[0] = '\0'; 744*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_root); 745*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, "/"); 746*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_server); 747*7c478bd9Sstevel@tonic-gate f_mode = FM_ALLFILE; 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate /* 751*7c478bd9Sstevel@tonic-gate * Gather all of the files in the directory 'f_dir'. 752*7c478bd9Sstevel@tonic-gate */ 753*7c478bd9Sstevel@tonic-gate if (f_mode == FM_ALLFILE) { 754*7c478bd9Sstevel@tonic-gate if (gather_dir(f_dir)) { /* get those files together */ 755*7c478bd9Sstevel@tonic-gate return (-1); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate } else { 758*7c478bd9Sstevel@tonic-gate /* 759*7c478bd9Sstevel@tonic-gate * Gather all of the files in all of the 760*7c478bd9Sstevel@tonic-gate * directories in 'f_root'. 761*7c478bd9Sstevel@tonic-gate */ 762*7c478bd9Sstevel@tonic-gate if ((dirp = opendir(f_root)) == NULL) { 763*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext( 764*7c478bd9Sstevel@tonic-gate "%s can't open directory %s"), ar, f_root); 765*7c478bd9Sstevel@tonic-gate perror(errbuf); 766*7c478bd9Sstevel@tonic-gate return (-1); 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate /* read the directory and process all of the subs */ 769*7c478bd9Sstevel@tonic-gate for (dp = readdir(dirp); 770*7c478bd9Sstevel@tonic-gate dp != NULL; dp = readdir(dirp)) { 771*7c478bd9Sstevel@tonic-gate if (dp->d_name[0] == '.') 772*7c478bd9Sstevel@tonic-gate continue; 773*7c478bd9Sstevel@tonic-gate f_dir[0] = '\0'; 774*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_root); 775*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, "/"); 776*7c478bd9Sstevel@tonic-gate (void) strcat(f_dir, dp->d_name); 777*7c478bd9Sstevel@tonic-gate if (gather_dir(f_dir)) /* process a sub */ 778*7c478bd9Sstevel@tonic-gate return (-1); 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate (void) closedir(dirp); 781*7c478bd9Sstevel@tonic-gate } 782*7c478bd9Sstevel@tonic-gate } else { 783*7c478bd9Sstevel@tonic-gate /* 784*7c478bd9Sstevel@tonic-gate * User specified filenames on the comm and line. 785*7c478bd9Sstevel@tonic-gate */ 786*7c478bd9Sstevel@tonic-gate f_cmdline = TRUE; 787*7c478bd9Sstevel@tonic-gate for (; optindex < argc; optindex++) { 788*7c478bd9Sstevel@tonic-gate fname = argv[optindex]; /* get a filename */ 789*7c478bd9Sstevel@tonic-gate if (proc_file(fname, FALSE)) 790*7c478bd9Sstevel@tonic-gate return (-1); 791*7c478bd9Sstevel@tonic-gate } 792*7c478bd9Sstevel@tonic-gate } 793*7c478bd9Sstevel@tonic-gate return (0); 794*7c478bd9Sstevel@tonic-gate } 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate 797*7c478bd9Sstevel@tonic-gate /* 798*7c478bd9Sstevel@tonic-gate * .func gather_dir - gather a directory's files together. 799*7c478bd9Sstevel@tonic-gate * .desc Process all of the files in a specific directory. The files may 800*7c478bd9Sstevel@tonic-gate * be checked for adherence to the file name form at. 801*7c478bd9Sstevel@tonic-gate * If the directory can't be opened that is ok - just print 802*7c478bd9Sstevel@tonic-gate * a message and continue. 803*7c478bd9Sstevel@tonic-gate * .call ret = gather_dir(dir). 804*7c478bd9Sstevel@tonic-gate * .arg dir - ptr to full pathname of directory. 805*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 806*7c478bd9Sstevel@tonic-gate * .ret -1 - error detected (message already printed). 807*7c478bd9Sstevel@tonic-gate */ 808*7c478bd9Sstevel@tonic-gate int 809*7c478bd9Sstevel@tonic-gate gather_dir(char *dir) 810*7c478bd9Sstevel@tonic-gate { 811*7c478bd9Sstevel@tonic-gate char dname[MAXNAMLEN+1]; 812*7c478bd9Sstevel@tonic-gate char fname[MAXNAMLEN+1]; 813*7c478bd9Sstevel@tonic-gate DIR * dirp; 814*7c478bd9Sstevel@tonic-gate struct dirent *dp; 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate (void) snprintf(dname, sizeof (dname), "%s/files", dir); 817*7c478bd9Sstevel@tonic-gate 818*7c478bd9Sstevel@tonic-gate if ((dirp = opendir(dname)) == NULL) { 819*7c478bd9Sstevel@tonic-gate if (errno != ENOTDIR) { 820*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 821*7c478bd9Sstevel@tonic-gate gettext("%s can't open directory - %s"), ar, dname); 822*7c478bd9Sstevel@tonic-gate perror(errbuf); 823*7c478bd9Sstevel@tonic-gate } 824*7c478bd9Sstevel@tonic-gate return (0); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 827*7c478bd9Sstevel@tonic-gate if (dp->d_name[0] == '.') /* can't see hidden files */ 828*7c478bd9Sstevel@tonic-gate continue; 829*7c478bd9Sstevel@tonic-gate fname[0] = '\0'; 830*7c478bd9Sstevel@tonic-gate (void) strcat(fname, dname); /* create pathname of file */ 831*7c478bd9Sstevel@tonic-gate (void) strcat(fname, "/"); 832*7c478bd9Sstevel@tonic-gate (void) strcat(fname, dp->d_name); 833*7c478bd9Sstevel@tonic-gate if (proc_file(fname, TRUE)) 834*7c478bd9Sstevel@tonic-gate return (-1); 835*7c478bd9Sstevel@tonic-gate } 836*7c478bd9Sstevel@tonic-gate (void) closedir(dirp); 837*7c478bd9Sstevel@tonic-gate return (0); 838*7c478bd9Sstevel@tonic-gate } 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate 841*7c478bd9Sstevel@tonic-gate /* 842*7c478bd9Sstevel@tonic-gate * .func proc_file - process a single candidate file. 843*7c478bd9Sstevel@tonic-gate * .desc Check out a file to see if it should be used in the merge. 844*7c478bd9Sstevel@tonic-gate * This includes checking the name (mode is TRUE) against the 845*7c478bd9Sstevel@tonic-gate * file format, checking access rights to the file, and thence 846*7c478bd9Sstevel@tonic-gate * getting and fcb and installing the fcb into the correct pcb. 847*7c478bd9Sstevel@tonic-gate * If the file fails then the fcb is not installed into a pcb 848*7c478bd9Sstevel@tonic-gate * and the file dissapears from view. 849*7c478bd9Sstevel@tonic-gate * .call proc_file(fname, mode). 850*7c478bd9Sstevel@tonic-gate * .arg fname - ptr to full pathna me of file. 851*7c478bd9Sstevel@tonic-gate * .arg mode - TRUE if checking adherence to file name format. 852*7c478bd9Sstevel@tonic-gate * .ret 0 - no fatal errors detected. 853*7c478bd9Sstevel@tonic-gate * .ret -1 - fatal error detected - quit altogether 854*7c478bd9Sstevel@tonic-gate * (message already printed). 855*7c478bd9Sstevel@tonic-gate */ 856*7c478bd9Sstevel@tonic-gate int 857*7c478bd9Sstevel@tonic-gate proc_file(char *fname, int mode) 858*7c478bd9Sstevel@tonic-gate { 859*7c478bd9Sstevel@tonic-gate int reject = FALSE; 860*7c478bd9Sstevel@tonic-gate size_t len; 861*7c478bd9Sstevel@tonic-gate struct stat stat_buf; 862*7c478bd9Sstevel@tonic-gate audit_fcb_t *fcb, *fcbp, *fcbprev; 863*7c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 864*7c478bd9Sstevel@tonic-gate 865*7c478bd9Sstevel@tonic-gate /* 866*7c478bd9Sstevel@tonic-gate * See if it is a weird file like a directory or 867*7c478bd9Sstevel@tonic-gate * character special (around here?). 868*7c478bd9Sstevel@tonic-gate */ 869*7c478bd9Sstevel@tonic-gate if (stat(fname, &stat_buf)) { 870*7c478bd9Sstevel@tonic-gate return (0); 871*7c478bd9Sstevel@tonic-gate } 872*7c478bd9Sstevel@tonic-gate if ((stat_buf.st_mode & S_IFREG) == 0) 873*7c478bd9Sstevel@tonic-gate return (0); 874*7c478bd9Sstevel@tonic-gate /* 875*7c478bd9Sstevel@tonic-gate * Allocate a new fcb to hold fcb and full filename. 876*7c478bd9Sstevel@tonic-gate */ 877*7c478bd9Sstevel@tonic-gate len = sizeof (audit_fcb_t) + strlen(fname); 878*7c478bd9Sstevel@tonic-gate fcb = (audit_fcb_t *)a_calloc(1, len); 879*7c478bd9Sstevel@tonic-gate (void) strcpy(fcb->fcb_file, fname); 880*7c478bd9Sstevel@tonic-gate if (check_file(fcb, mode)) { /* check file name */ 881*7c478bd9Sstevel@tonic-gate if (!f_quiet) { 882*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s %s:\n %s.\n", ar, 883*7c478bd9Sstevel@tonic-gate error_str, fname); 884*7c478bd9Sstevel@tonic-gate } 885*7c478bd9Sstevel@tonic-gate reject = TRUE; 886*7c478bd9Sstevel@tonic-gate } else { 887*7c478bd9Sstevel@tonic-gate /* 888*7c478bd9Sstevel@tonic-gate * Check against file criteria. 889*7c478bd9Sstevel@tonic-gate * Check finish-time here, and start-time later on 890*7c478bd9Sstevel@tonic-gate * while processing. 891*7c478bd9Sstevel@tonic-gate * This is because the start time on a file can be after 892*7c478bd9Sstevel@tonic-gate * the first record(s). 893*7c478bd9Sstevel@tonic-gate */ 894*7c478bd9Sstevel@tonic-gate if (f_complete && (fcb->fcb_flags & FF_NOTTERM) && !f_cmdline) 895*7c478bd9Sstevel@tonic-gate reject = TRUE; 896*7c478bd9Sstevel@tonic-gate if (!f_all && (fcb->fcb_end < m_after)) 897*7c478bd9Sstevel@tonic-gate reject = TRUE; 898*7c478bd9Sstevel@tonic-gate if (f_machine) { 899*7c478bd9Sstevel@tonic-gate if (strlen(fcb->fcb_suffix) != strlen(f_machine) || 900*7c478bd9Sstevel@tonic-gate (strcmp(fcb->fcb_suffix, f_machine) != 0)) { 901*7c478bd9Sstevel@tonic-gate reject = TRUE; 902*7c478bd9Sstevel@tonic-gate } 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate } 905*7c478bd9Sstevel@tonic-gate if (reject == FALSE) { 906*7c478bd9Sstevel@tonic-gate filenum++; /* count of total files to be processed */ 907*7c478bd9Sstevel@tonic-gate fcb->fcb_next = NULL; 908*7c478bd9Sstevel@tonic-gate if ((pcb = get_next_pcb(fcb->fcb_suffix)) == NULL) { 909*7c478bd9Sstevel@tonic-gate return (-1); 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate /* Place FCB into the PCB in order - oldest first. */ 912*7c478bd9Sstevel@tonic-gate fcbp = pcb->pcb_first; 913*7c478bd9Sstevel@tonic-gate fcbprev = NULL; 914*7c478bd9Sstevel@tonic-gate while (fcbp != NULL) { 915*7c478bd9Sstevel@tonic-gate if (fcb->fcb_start < fcbp->fcb_start) { 916*7c478bd9Sstevel@tonic-gate if (fcbprev) 917*7c478bd9Sstevel@tonic-gate fcbprev->fcb_next = fcb; 918*7c478bd9Sstevel@tonic-gate else 919*7c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; 920*7c478bd9Sstevel@tonic-gate fcb->fcb_next = fcbp; 921*7c478bd9Sstevel@tonic-gate break; 922*7c478bd9Sstevel@tonic-gate } 923*7c478bd9Sstevel@tonic-gate fcbprev = fcbp; 924*7c478bd9Sstevel@tonic-gate fcbp = fcbp->fcb_next; 925*7c478bd9Sstevel@tonic-gate } 926*7c478bd9Sstevel@tonic-gate /* younger than all || empty list */ 927*7c478bd9Sstevel@tonic-gate if (!fcb->fcb_next) { 928*7c478bd9Sstevel@tonic-gate if (pcb->pcb_first == NULL) 929*7c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; 930*7c478bd9Sstevel@tonic-gate pcb->pcb_dlast = pcb->pcb_last = fcb; 931*7c478bd9Sstevel@tonic-gate if (fcbprev) 932*7c478bd9Sstevel@tonic-gate fcbprev->fcb_next = fcb; 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate } else { 935*7c478bd9Sstevel@tonic-gate free((char *)fcb); /* rejected */ 936*7c478bd9Sstevel@tonic-gate } 937*7c478bd9Sstevel@tonic-gate return (0); 938*7c478bd9Sstevel@tonic-gate } 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate 941*7c478bd9Sstevel@tonic-gate /* 942*7c478bd9Sstevel@tonic-gate * .func check_file - check filename and setup fcb. 943*7c478bd9Sstevel@tonic-gate * .desc Check adherence to the file format (do_check is TRUE) and setup 944*7c478bd9Sstevel@tonic-gate * the fcb with useful information. 945*7c478bd9Sstevel@tonic-gate * filename format: yyyymmddhhmmss.yyyymmddhhmmss.suffix 946*7c478bd9Sstevel@tonic-gate * yyyymmddhhmmss.not_terminated.suffix 947*7c478bd9Sstevel@tonic-gate * If do_check is FALSE then still see if the filename does confirm 948*7c478bd9Sstevel@tonic-gate * to the format. If it does then extract useful information from 949*7c478bd9Sstevel@tonic-gate * it (start time and end time). But if it doesn't then don't print 950*7c478bd9Sstevel@tonic-gate * any error messages. 951*7c478bd9Sstevel@tonic-gate * .call ret = check_file(fcb, do_check). 952*7c478bd9Sstevel@tonic-gate * .arg fcb - ptr to fcb that holds the file. 953*7c478bd9Sstevel@tonic-gate * .arg do_check - if TRUE do check adherence to file format. 954*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 955*7c478bd9Sstevel@tonic-gate * .ret -1 - file failed somehow (error_str tells why). 956*7c478bd9Sstevel@tonic-gate */ 957*7c478bd9Sstevel@tonic-gate int 958*7c478bd9Sstevel@tonic-gate check_file(audit_fcb_t *fcb, int do_check) 959*7c478bd9Sstevel@tonic-gate { 960*7c478bd9Sstevel@tonic-gate int ret; 961*7c478bd9Sstevel@tonic-gate char *namep, *slp; 962*7c478bd9Sstevel@tonic-gate char errb[256]; /* build error message */ 963*7c478bd9Sstevel@tonic-gate struct tm tme; 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate errb[0] = '\0'; 966*7c478bd9Sstevel@tonic-gate /* get just the filename */ 967*7c478bd9Sstevel@tonic-gate for (slp = namep = fcb->fcb_file; *namep; namep++) { 968*7c478bd9Sstevel@tonic-gate if (*namep == '/') 969*7c478bd9Sstevel@tonic-gate slp = namep + 1; /* slp -> the filename itself */ 970*7c478bd9Sstevel@tonic-gate } 971*7c478bd9Sstevel@tonic-gate if (do_check == FALSE) { 972*7c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 973*7c478bd9Sstevel@tonic-gate fcb->fcb_suffix = NULL; 974*7c478bd9Sstevel@tonic-gate fcb->fcb_name = slp; 975*7c478bd9Sstevel@tonic-gate ret = 0; 976*7c478bd9Sstevel@tonic-gate } else { 977*7c478bd9Sstevel@tonic-gate ret = -1; 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate if ((int)strlen(slp) < 31) { 980*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("filename too short (%d)"), 981*7c478bd9Sstevel@tonic-gate strlen(slp)); 982*7c478bd9Sstevel@tonic-gate error_str = errbuf; 983*7c478bd9Sstevel@tonic-gate return (ret); 984*7c478bd9Sstevel@tonic-gate } 985*7c478bd9Sstevel@tonic-gate /* 986*7c478bd9Sstevel@tonic-gate * Get working copy of filename. 987*7c478bd9Sstevel@tonic-gate */ 988*7c478bd9Sstevel@tonic-gate namep = (char *)a_calloc(1, strlen(slp) + 1); 989*7c478bd9Sstevel@tonic-gate (void) strcpy(namep, slp); 990*7c478bd9Sstevel@tonic-gate if (namep[14] != '.' || namep[29] != '.') { 991*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 992*7c478bd9Sstevel@tonic-gate gettext("invalid filename format (%c or %c)"), namep[14], 993*7c478bd9Sstevel@tonic-gate namep[29]); 994*7c478bd9Sstevel@tonic-gate error_str = errbuf; 995*7c478bd9Sstevel@tonic-gate free(namep); 996*7c478bd9Sstevel@tonic-gate return (ret); 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate namep[14] = '\0'; /* mark off start time */ 999*7c478bd9Sstevel@tonic-gate namep[29] = '\0'; /* mark off finish time */ 1000*7c478bd9Sstevel@tonic-gate if (derive_date(namep, &tme)) { 1001*7c478bd9Sstevel@tonic-gate (void) strcat(errb, gettext("starting time-stamp invalid - ")); 1002*7c478bd9Sstevel@tonic-gate (void) strcat(errb, error_str); 1003*7c478bd9Sstevel@tonic-gate (void) strcpy(errbuf, errb); 1004*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1005*7c478bd9Sstevel@tonic-gate free(namep); 1006*7c478bd9Sstevel@tonic-gate return (ret); 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate /* 1009*7c478bd9Sstevel@tonic-gate * Keep start time from filename. Use it to order files in 1010*7c478bd9Sstevel@tonic-gate * the file list. Later we will update this when we read 1011*7c478bd9Sstevel@tonic-gate * the first record from the file. 1012*7c478bd9Sstevel@tonic-gate */ 1013*7c478bd9Sstevel@tonic-gate fcb->fcb_start = tm_to_secs(&tme); 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate if (strcmp(&namep[15], "not_terminated") == 0) { 1016*7c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 1017*7c478bd9Sstevel@tonic-gate /* 1018*7c478bd9Sstevel@tonic-gate * Only treat a 'not_terminated' file as such if 1019*7c478bd9Sstevel@tonic-gate * it is not on the command line. 1020*7c478bd9Sstevel@tonic-gate */ 1021*7c478bd9Sstevel@tonic-gate if (do_check == TRUE) 1022*7c478bd9Sstevel@tonic-gate fcb->fcb_flags |= FF_NOTTERM; 1023*7c478bd9Sstevel@tonic-gate } else if (derive_date(&namep[15], &tme)) { 1024*7c478bd9Sstevel@tonic-gate (void) strcat(errb, gettext("ending time-stamp invalid - ")); 1025*7c478bd9Sstevel@tonic-gate (void) strcat(errb, error_str); 1026*7c478bd9Sstevel@tonic-gate (void) strcpy(errbuf, errb); 1027*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1028*7c478bd9Sstevel@tonic-gate free(namep); 1029*7c478bd9Sstevel@tonic-gate return (ret); 1030*7c478bd9Sstevel@tonic-gate } else { 1031*7c478bd9Sstevel@tonic-gate fcb->fcb_end = tm_to_secs(&tme); 1032*7c478bd9Sstevel@tonic-gate } 1033*7c478bd9Sstevel@tonic-gate fcb->fcb_name = slp; 1034*7c478bd9Sstevel@tonic-gate fcb->fcb_suffix = &slp[30]; 1035*7c478bd9Sstevel@tonic-gate free(namep); 1036*7c478bd9Sstevel@tonic-gate return (0); 1037*7c478bd9Sstevel@tonic-gate } 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate 1040*7c478bd9Sstevel@tonic-gate /* 1041*7c478bd9Sstevel@tonic-gate * .func get_next_pcb - get a pcb to use. 1042*7c478bd9Sstevel@tonic-gate * .desc The pcb's in the array audit_pcbs are used to hold single file 1043*7c478bd9Sstevel@tonic-gate * groups in the form of a linked list. Each pcb holds files that 1044*7c478bd9Sstevel@tonic-gate * are tied together by a common suffix in the file name. Here we 1045*7c478bd9Sstevel@tonic-gate * get either 1. the existing pcb holding a specified sufix or 1046*7c478bd9Sstevel@tonic-gate * 2. a new pcb if we can't find an existing one. 1047*7c478bd9Sstevel@tonic-gate * .call pcb = get_next_pcb(suffix). 1048*7c478bd9Sstevel@tonic-gate * .arg suffix - ptr to suffix we are seeking. 1049*7c478bd9Sstevel@tonic-gate * .ret pcb - ptr to pcb that hold s the sought suffix. 1050*7c478bd9Sstevel@tonic-gate * .ret NULL- serious failure in memory allocation. Quit processing. 1051*7c478bd9Sstevel@tonic-gate */ 1052*7c478bd9Sstevel@tonic-gate audit_pcb_t * 1053*7c478bd9Sstevel@tonic-gate get_next_pcb(char *suffix) 1054*7c478bd9Sstevel@tonic-gate { 1055*7c478bd9Sstevel@tonic-gate int i = 0; 1056*7c478bd9Sstevel@tonic-gate int zerosize; 1057*7c478bd9Sstevel@tonic-gate unsigned int size; 1058*7c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate /* Search through (maybe) entire array. */ 1061*7c478bd9Sstevel@tonic-gate while (i < pcbsize) { 1062*7c478bd9Sstevel@tonic-gate pcb = &audit_pcbs[i++]; 1063*7c478bd9Sstevel@tonic-gate if (pcb->pcb_first == NULL) { 1064*7c478bd9Sstevel@tonic-gate proc_pcb(pcb, suffix, i); 1065*7c478bd9Sstevel@tonic-gate return (pcb); /* came to an unused one */ 1066*7c478bd9Sstevel@tonic-gate } 1067*7c478bd9Sstevel@tonic-gate if (suffix) { 1068*7c478bd9Sstevel@tonic-gate if (strcmp(pcb->pcb_suffix, suffix) == 0) 1069*7c478bd9Sstevel@tonic-gate return (pcb); /* matched one with suffix */ 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate /* 1073*7c478bd9Sstevel@tonic-gate * Uh-oh, the entire array is used and we haven't gotten one yet. 1074*7c478bd9Sstevel@tonic-gate * Allocate a bigger array. 1075*7c478bd9Sstevel@tonic-gate */ 1076*7c478bd9Sstevel@tonic-gate pcbsize += PCB_INC; 1077*7c478bd9Sstevel@tonic-gate size = pcbsize * sizeof (audit_pcb_t); 1078*7c478bd9Sstevel@tonic-gate zerosize = size - ((pcbsize - PCB_INC) * sizeof (audit_pcb_t)); 1079*7c478bd9Sstevel@tonic-gate if ((audit_pcbs = (audit_pcb_t *)realloc((char *)audit_pcbs, size)) == 1080*7c478bd9Sstevel@tonic-gate NULL) { 1081*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1082*7c478bd9Sstevel@tonic-gate gettext("%s memory reallocation failed (%d bytes)"), ar, 1083*7c478bd9Sstevel@tonic-gate size); 1084*7c478bd9Sstevel@tonic-gate perror(errbuf); 1085*7c478bd9Sstevel@tonic-gate audit_stats(); /* give user statistics on usage */ 1086*7c478bd9Sstevel@tonic-gate return (NULL); /* really bad thing to have happen */ 1087*7c478bd9Sstevel@tonic-gate } 1088*7c478bd9Sstevel@tonic-gate /* 1089*7c478bd9Sstevel@tonic-gate * Don't know if realloc clears the new memory like calloc would. 1090*7c478bd9Sstevel@tonic-gate */ 1091*7c478bd9Sstevel@tonic-gate (void) memset((void *) & audit_pcbs[pcbsize-PCB_INC], 0, 1092*7c478bd9Sstevel@tonic-gate (size_t)zerosize); 1093*7c478bd9Sstevel@tonic-gate pcb = &audit_pcbs[pcbsize-PCB_INC]; /* allocate the first new one */ 1094*7c478bd9Sstevel@tonic-gate proc_pcb(pcb, suffix, pcbsize - PCB_INC); 1095*7c478bd9Sstevel@tonic-gate return (pcb); 1096*7c478bd9Sstevel@tonic-gate } 1097*7c478bd9Sstevel@tonic-gate 1098*7c478bd9Sstevel@tonic-gate 1099*7c478bd9Sstevel@tonic-gate /* 1100*7c478bd9Sstevel@tonic-gate * .func proc_pcb - process pcb. 1101*7c478bd9Sstevel@tonic-gate * .desc Common pcb processing for above routine. 1102*7c478bd9Sstevel@tonic-gate * .call proc_pcb(pcb, suffix, i). 1103*7c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb. 1104*7c478bd9Sstevel@tonic-gate * .arg suffix - prt to suffix tha t ties this group together. 1105*7c478bd9Sstevel@tonic-gate * .arg i - index into audit_pcbs[ ]. 1106*7c478bd9Sstevel@tonic-gate * .ret void. 1107*7c478bd9Sstevel@tonic-gate */ 1108*7c478bd9Sstevel@tonic-gate void 1109*7c478bd9Sstevel@tonic-gate proc_pcb(audit_pcb_t *pcb, char *suffix, int i) 1110*7c478bd9Sstevel@tonic-gate { 1111*7c478bd9Sstevel@tonic-gate if (suffix) 1112*7c478bd9Sstevel@tonic-gate pcb->pcb_suffix = suffix; 1113*7c478bd9Sstevel@tonic-gate pcbnum++; /* one more pcb in use */ 1114*7c478bd9Sstevel@tonic-gate pcb->pcb_size = AUDITBUFSIZE; 1115*7c478bd9Sstevel@tonic-gate pcb->pcb_rec = (char *)a_calloc(1, AUDITBUFSIZE); 1116*7c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; 1117*7c478bd9Sstevel@tonic-gate pcb->pcb_flags |= PF_FILE; /* note this one controls files */ 1118*7c478bd9Sstevel@tonic-gate pcb->pcb_procno = i; /* save index into audit_pcbs [] for id */ 1119*7c478bd9Sstevel@tonic-gate } 1120*7c478bd9Sstevel@tonic-gate 1121*7c478bd9Sstevel@tonic-gate 1122*7c478bd9Sstevel@tonic-gate #ifdef TSOL 1123*7c478bd9Sstevel@tonic-gate /* 1124*7c478bd9Sstevel@tonic-gate * .func proc_slabel - process sensitivity label range argument. 1125*7c478bd9Sstevel@tonic-gate * .desc Parse sensitivity label range sl:sl 1126*7c478bd9Sstevel@tonic-gate * .call ret = proc_slabel(optstr). 1127*7c478bd9Sstevel@tonic-gate * .arg opstr - ptr to label range string 1128*7c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 1129*7c478bd9Sstevel@tonic-gate * .ret -1 - errors detected or not Trusted Solaris (error_str set). 1130*7c478bd9Sstevel@tonic-gate */ 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate int 1133*7c478bd9Sstevel@tonic-gate proc_slabel(char *optstr) 1134*7c478bd9Sstevel@tonic-gate { 1135*7c478bd9Sstevel@tonic-gate char *p; 1136*7c478bd9Sstevel@tonic-gate int error; 1137*7c478bd9Sstevel@tonic-gate 1138*7c478bd9Sstevel@tonic-gate if (flags & M_SLABEL) { 1139*7c478bd9Sstevel@tonic-gate error_str = gettext("'s' option specified multiple times"); 1140*7c478bd9Sstevel@tonic-gate return (-1); 1141*7c478bd9Sstevel@tonic-gate } 1142*7c478bd9Sstevel@tonic-gate 1143*7c478bd9Sstevel@tonic-gate flags |= M_SLABEL; 1144*7c478bd9Sstevel@tonic-gate p = strchr(optstr, ':'); 1145*7c478bd9Sstevel@tonic-gate if (p == NULL) { 1146*7c478bd9Sstevel@tonic-gate /* exact label match, lower and upper range bounds the same */ 1147*7c478bd9Sstevel@tonic-gate if (stobsl(optstr, &m_slabel.lower_bound, NO_CORRECTION, 1148*7c478bd9Sstevel@tonic-gate &error) == 0) { 1149*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1150*7c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), 1151*7c478bd9Sstevel@tonic-gate optstr, error); 1152*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1153*7c478bd9Sstevel@tonic-gate return (-1); 1154*7c478bd9Sstevel@tonic-gate } 1155*7c478bd9Sstevel@tonic-gate m_slabel.upper_bound = m_slabel.lower_bound; 1156*7c478bd9Sstevel@tonic-gate return (0); 1157*7c478bd9Sstevel@tonic-gate } 1158*7c478bd9Sstevel@tonic-gate if (p == optstr) { 1159*7c478bd9Sstevel@tonic-gate /* lower bound is not specified .. default is admin_low */ 1160*7c478bd9Sstevel@tonic-gate bsllow(&m_slabel.lower_bound); 1161*7c478bd9Sstevel@tonic-gate if (stobsl(p + 1, &m_slabel.upper_bound, NO_CORRECTION, 1162*7c478bd9Sstevel@tonic-gate &error) == 0) { 1163*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1164*7c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), 1165*7c478bd9Sstevel@tonic-gate p + 1, error); 1166*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1167*7c478bd9Sstevel@tonic-gate return (-1); 1168*7c478bd9Sstevel@tonic-gate } 1169*7c478bd9Sstevel@tonic-gate return (0); 1170*7c478bd9Sstevel@tonic-gate } 1171*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 1172*7c478bd9Sstevel@tonic-gate if (stobsl(optstr, &m_slabel.lower_bound, NO_CORRECTION, &error) == 0) { 1173*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1174*7c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), optstr, 1175*7c478bd9Sstevel@tonic-gate error); 1176*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1177*7c478bd9Sstevel@tonic-gate return (-1); 1178*7c478bd9Sstevel@tonic-gate } 1179*7c478bd9Sstevel@tonic-gate if (*p == '\0') 1180*7c478bd9Sstevel@tonic-gate /* upper bound is not specified .. default is admin_high */ 1181*7c478bd9Sstevel@tonic-gate bslhigh(&m_slabel.upper_bound); 1182*7c478bd9Sstevel@tonic-gate else { 1183*7c478bd9Sstevel@tonic-gate if (stobsl(p, &m_slabel.upper_bound, NO_CORRECTION, &error) == 1184*7c478bd9Sstevel@tonic-gate 0) { 1185*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1186*7c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), 1187*7c478bd9Sstevel@tonic-gate p, error); 1188*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1189*7c478bd9Sstevel@tonic-gate return (-1); 1190*7c478bd9Sstevel@tonic-gate } 1191*7c478bd9Sstevel@tonic-gate } 1192*7c478bd9Sstevel@tonic-gate /* make sure that upper bound dominates the lower bound */ 1193*7c478bd9Sstevel@tonic-gate if (!bldominates(&m_slabel.upper_bound, &m_slabel.lower_bound)) { 1194*7c478bd9Sstevel@tonic-gate *--p = ':'; 1195*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1196*7c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label range (%s)"), optstr); 1197*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1198*7c478bd9Sstevel@tonic-gate return (-1); 1199*7c478bd9Sstevel@tonic-gate } 1200*7c478bd9Sstevel@tonic-gate return (0); 1201*7c478bd9Sstevel@tonic-gate } 1202*7c478bd9Sstevel@tonic-gate #endif /* !TSOL */ 1203*7c478bd9Sstevel@tonic-gate 1204*7c478bd9Sstevel@tonic-gate /* 1205*7c478bd9Sstevel@tonic-gate * proc_zonename - pick up zone name. 1206*7c478bd9Sstevel@tonic-gate * 1207*7c478bd9Sstevel@tonic-gate * all non-empty and not-too-long strings are valid since any name 1208*7c478bd9Sstevel@tonic-gate * may be valid. 1209*7c478bd9Sstevel@tonic-gate * 1210*7c478bd9Sstevel@tonic-gate * ret 0: non-empty string 1211*7c478bd9Sstevel@tonic-gate * ret -1: empty string or string is too long. 1212*7c478bd9Sstevel@tonic-gate */ 1213*7c478bd9Sstevel@tonic-gate static int 1214*7c478bd9Sstevel@tonic-gate proc_zonename(char *optstr) 1215*7c478bd9Sstevel@tonic-gate { 1216*7c478bd9Sstevel@tonic-gate size_t length = strlen(optstr); 1217*7c478bd9Sstevel@tonic-gate if ((length < 1) || (length > ZONENAME_MAX)) { 1218*7c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 1219*7c478bd9Sstevel@tonic-gate gettext("invalid zone name: %s"), optstr); 1220*7c478bd9Sstevel@tonic-gate error_str = errbuf; 1221*7c478bd9Sstevel@tonic-gate return (-1); 1222*7c478bd9Sstevel@tonic-gate } 1223*7c478bd9Sstevel@tonic-gate zonename = strdup(optstr); 1224*7c478bd9Sstevel@tonic-gate flags |= M_ZONENAME; 1225*7c478bd9Sstevel@tonic-gate return (0); 1226*7c478bd9Sstevel@tonic-gate } 1227