17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*9073e376SMarek Pospisil * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Command line option processing for auditreduce. 287c478bd9Sstevel@tonic-gate * The entry point is process_options(), which is called by main(). 297c478bd9Sstevel@tonic-gate * Process_options() is the only function visible outside this module. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <locale.h> 337c478bd9Sstevel@tonic-gate #include <sys/zone.h> /* for max zonename length */ 347c478bd9Sstevel@tonic-gate #include "auditr.h" 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate /* 377c478bd9Sstevel@tonic-gate * Object entry. 387c478bd9Sstevel@tonic-gate * Maps object strings specified on the command line to a flag 397c478bd9Sstevel@tonic-gate * used when searching by object type. 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate struct obj_ent { 437c478bd9Sstevel@tonic-gate char *obj_str; /* string specified on the command line */ 447c478bd9Sstevel@tonic-gate int obj_flag; /* flag used when searching */ 457c478bd9Sstevel@tonic-gate }; 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate typedef struct obj_ent obj_ent_t; 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * Supports searches by object type. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate static obj_ent_t obj_tbl[] = { 537c478bd9Sstevel@tonic-gate { "file", OBJ_PATH }, 547c478bd9Sstevel@tonic-gate { "filegroup", OBJ_FGROUP }, 557c478bd9Sstevel@tonic-gate { "fileowner", OBJ_FOWNER }, 56103b2b15Sgww { "fmri", OBJ_FMRI }, 577c478bd9Sstevel@tonic-gate { "lp", OBJ_LP }, 587c478bd9Sstevel@tonic-gate { "msgqid", OBJ_MSG }, 597c478bd9Sstevel@tonic-gate { "msgqgroup", OBJ_MSGGROUP }, 607c478bd9Sstevel@tonic-gate { "msgqowner", OBJ_MSGOWNER }, 617c478bd9Sstevel@tonic-gate { "path", OBJ_PATH }, 627c478bd9Sstevel@tonic-gate { "pid", OBJ_PROC }, 637c478bd9Sstevel@tonic-gate { "procgroup", OBJ_PGROUP }, 647c478bd9Sstevel@tonic-gate { "procowner", OBJ_POWNER }, 657c478bd9Sstevel@tonic-gate { "semid", OBJ_SEM }, 667c478bd9Sstevel@tonic-gate { "semgroup", OBJ_SEMGROUP }, 677c478bd9Sstevel@tonic-gate { "semowner", OBJ_SEMOWNER }, 687c478bd9Sstevel@tonic-gate { "shmid", OBJ_SHM }, 697c478bd9Sstevel@tonic-gate { "shmgroup", OBJ_SHMGROUP }, 707c478bd9Sstevel@tonic-gate { "shmowner", OBJ_SHMOWNER }, 717c478bd9Sstevel@tonic-gate { "sock", OBJ_SOCK } }; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate extern int derive_date(char *, struct tm *); 747c478bd9Sstevel@tonic-gate extern int parse_time(char *, int); 757c478bd9Sstevel@tonic-gate extern char *re_comp2(char *); 767c478bd9Sstevel@tonic-gate extern time_t tm_to_secs(struct tm *); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate static int a_isnum(char *, int); 797c478bd9Sstevel@tonic-gate static int check_file(audit_fcb_t *, int); 807c478bd9Sstevel@tonic-gate static int gather_dir(char *); 817c478bd9Sstevel@tonic-gate static audit_pcb_t *get_next_pcb(char *); 827c478bd9Sstevel@tonic-gate static obj_ent_t *obj_lkup(char *); 837c478bd9Sstevel@tonic-gate static int proc_class(char *); 847c478bd9Sstevel@tonic-gate static int proc_date(char *, int); 857c478bd9Sstevel@tonic-gate static int proc_file(char *, int); 867c478bd9Sstevel@tonic-gate static int process_fileopt(int, char *argv[], int); 877c478bd9Sstevel@tonic-gate static int proc_group(char *, gid_t *); 887c478bd9Sstevel@tonic-gate static int proc_id(char *, int); 897c478bd9Sstevel@tonic-gate static int proc_object(char *); 907c478bd9Sstevel@tonic-gate static void proc_pcb(audit_pcb_t *, char *, int); 91a13cf099Sgww static int proc_label(char *); 927c478bd9Sstevel@tonic-gate static int proc_subject(char *); 93924c9144Sgww static int proc_sid(char *); 947c478bd9Sstevel@tonic-gate static int proc_type(char *); 957c478bd9Sstevel@tonic-gate static int proc_user(char *, uid_t *); 967c478bd9Sstevel@tonic-gate static int proc_zonename(char *); 97103b2b15Sgww static int proc_fmri(char *); 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * .func process_options - process command line options. 1017c478bd9Sstevel@tonic-gate * .desc Process the user's command line options. These are of two types: 1027c478bd9Sstevel@tonic-gate * single letter flags that are denoted by '-', and filenames. Some 1037c478bd9Sstevel@tonic-gate * of the flags have arguments. Getopt() is used to get the flags. 1047c478bd9Sstevel@tonic-gate * When this is done it calls process_fileopt() to handle any filenames 1057c478bd9Sstevel@tonic-gate * that were there. 1067c478bd9Sstevel@tonic-gate * .call ret = process_options(argc, argv). 1077c478bd9Sstevel@tonic-gate * .arg argc - the original value. 1087c478bd9Sstevel@tonic-gate * .arg argv - the original value. 1097c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 1107c478bd9Sstevel@tonic-gate * .ret -1 - command line error detected (message already printed). 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate int 1137c478bd9Sstevel@tonic-gate process_options(int argc, char **argv) 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate int opt; 1167c478bd9Sstevel@tonic-gate int error = FALSE; 1177c478bd9Sstevel@tonic-gate int error_combo = FALSE; 1187c478bd9Sstevel@tonic-gate extern int optind; /* in getopt() */ 1197c478bd9Sstevel@tonic-gate extern char *optarg; /* in getopt() - holds arg to flag */ 1207c478bd9Sstevel@tonic-gate 121924c9144Sgww static char *options = "ACD:M:NQR:S:VO:" 122924c9144Sgww "a:b:c:d:e:g:j:l:m:o:r:s:t:u:z:"; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate error_str = gettext("general error"); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate zonename = NULL; 1277c478bd9Sstevel@tonic-gate /* 1287c478bd9Sstevel@tonic-gate * Big switch to process the flags. 1297c478bd9Sstevel@tonic-gate * Start_over: is for handling the '-' for standard input. Getopt() 1307c478bd9Sstevel@tonic-gate * doesn't recognize it. 1317c478bd9Sstevel@tonic-gate */ 1327c478bd9Sstevel@tonic-gate start_over: 1337c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, options)) != EOF) { 1347c478bd9Sstevel@tonic-gate switch (opt) { 1357c478bd9Sstevel@tonic-gate case 'A': /* all records from the files */ 1367c478bd9Sstevel@tonic-gate f_all = TRUE; 1377c478bd9Sstevel@tonic-gate break; 1387c478bd9Sstevel@tonic-gate case 'C': /* process only completed files */ 1397c478bd9Sstevel@tonic-gate f_complete = TRUE; 1407c478bd9Sstevel@tonic-gate break; 1417c478bd9Sstevel@tonic-gate case 'D': /* delete the files when done */ 1427c478bd9Sstevel@tonic-gate /* force 'A' 'C' 'O' to be active */ 1437c478bd9Sstevel@tonic-gate f_all = f_complete = TRUE; 1447c478bd9Sstevel@tonic-gate f_outfile = optarg; 1457c478bd9Sstevel@tonic-gate f_delete = TRUE; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case 'M': /* only files from a certain machine */ 1487c478bd9Sstevel@tonic-gate f_machine = optarg; 1497c478bd9Sstevel@tonic-gate break; 1507c478bd9Sstevel@tonic-gate case 'N': /* new object selection mode */ 1517c478bd9Sstevel@tonic-gate new_mode = TRUE; 1527c478bd9Sstevel@tonic-gate break; 1537c478bd9Sstevel@tonic-gate case 'Q': /* no file error reporting */ 1547c478bd9Sstevel@tonic-gate f_quiet = TRUE; 1557c478bd9Sstevel@tonic-gate break; 1567c478bd9Sstevel@tonic-gate case 'R': /* from specified root */ 1577c478bd9Sstevel@tonic-gate f_root = optarg; 1587c478bd9Sstevel@tonic-gate break; 1597c478bd9Sstevel@tonic-gate case 'S': /* from specified server */ 1607c478bd9Sstevel@tonic-gate f_server = optarg; 1617c478bd9Sstevel@tonic-gate break; 1627c478bd9Sstevel@tonic-gate case 'V': /* list all files as they are opened */ 1637c478bd9Sstevel@tonic-gate f_verbose = TRUE; 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate case 'O': /* write to outfile */ 1667c478bd9Sstevel@tonic-gate f_outfile = optarg; 1677c478bd9Sstevel@tonic-gate break; 1687c478bd9Sstevel@tonic-gate case 'a': /* after 'date' */ 1697c478bd9Sstevel@tonic-gate case 'b': /* before 'date' */ 1707c478bd9Sstevel@tonic-gate case 'd': /* from 'day' */ 1717c478bd9Sstevel@tonic-gate if (proc_date(optarg, opt)) 1727c478bd9Sstevel@tonic-gate error = TRUE; 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate case 'j': /* subject */ 1757c478bd9Sstevel@tonic-gate if (proc_subject(optarg)) 1767c478bd9Sstevel@tonic-gate error = TRUE; 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate case 'm': /* message 'type' */ 1797c478bd9Sstevel@tonic-gate if (proc_type(optarg)) 1807c478bd9Sstevel@tonic-gate error = TRUE; 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate case 'o': /* object type */ 1837c478bd9Sstevel@tonic-gate if (proc_object(optarg)) 1847c478bd9Sstevel@tonic-gate error = TRUE; 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate case 'c': /* message class */ 1877c478bd9Sstevel@tonic-gate if (proc_class(optarg)) 1887c478bd9Sstevel@tonic-gate error = TRUE; 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate case 'u': /* form audit user */ 1917c478bd9Sstevel@tonic-gate case 'e': /* form effective user */ 1927c478bd9Sstevel@tonic-gate case 'r': /* form real user */ 1937c478bd9Sstevel@tonic-gate case 'f': /* form effective group */ 1947c478bd9Sstevel@tonic-gate case 'g': /* form real group */ 1957c478bd9Sstevel@tonic-gate if (proc_id(optarg, opt)) 1967c478bd9Sstevel@tonic-gate error = TRUE; 1977c478bd9Sstevel@tonic-gate break; 198a13cf099Sgww case 'l': /* TX label range */ 19945916cd2Sjpk if (!is_system_labeled()) { 20045916cd2Sjpk (void) fprintf(stderr, 20145916cd2Sjpk gettext("%s option 'l' requires " 20245916cd2Sjpk "Trusted Extensions.\n"), ar); 20345916cd2Sjpk return (-1); 20445916cd2Sjpk } 205a13cf099Sgww if (proc_label(optarg)) 2067c478bd9Sstevel@tonic-gate error = TRUE; 2077c478bd9Sstevel@tonic-gate break; 208924c9144Sgww case 's': /* session ID */ 209924c9144Sgww if (proc_sid(optarg)) 210924c9144Sgww error = TRUE; 211924c9144Sgww break; 2127c478bd9Sstevel@tonic-gate case 'z': /* zone name */ 2137c478bd9Sstevel@tonic-gate if (proc_zonename(optarg)) 2147c478bd9Sstevel@tonic-gate error = TRUE; 2157c478bd9Sstevel@tonic-gate break; 216924c9144Sgww case 't': /* termial ID reserved for later */ 2177c478bd9Sstevel@tonic-gate default: 2187c478bd9Sstevel@tonic-gate return (-1); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate if (error) { 2217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 222406d6273SPalle Lyckegaard gettext("%s command line error - %s.\n"), 223406d6273SPalle Lyckegaard ar, error_str); 2247c478bd9Sstevel@tonic-gate return (-1); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate /* catch '-' option for stdin processing - getopt() won't see it */ 2287c478bd9Sstevel@tonic-gate if (optind < argc) { 2297c478bd9Sstevel@tonic-gate if (argv[optind][0] == '-' && argv[optind][1] == '\0') { 2307c478bd9Sstevel@tonic-gate optind++; 2317c478bd9Sstevel@tonic-gate f_stdin = TRUE; 2327c478bd9Sstevel@tonic-gate goto start_over; 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * Give a default value for 'b' option if not specified. 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate if (m_before == 0) 2397c478bd9Sstevel@tonic-gate m_before = MAXLONG; /* forever */ 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * Validate combinations of options. 2427c478bd9Sstevel@tonic-gate * The following are done: 2437c478bd9Sstevel@tonic-gate * 1. Can't have 'M' or 'S' or 'R' with filenames. 2447c478bd9Sstevel@tonic-gate * 2. Can't have an after ('a') time after a before ('b') time. 2457c478bd9Sstevel@tonic-gate * 3. Delete ('D') must have 'C' and 'A' and 'O' with it. 2467c478bd9Sstevel@tonic-gate * 4. Input from stdin ('-') can't have filenames too. 2477c478bd9Sstevel@tonic-gate */ 2487c478bd9Sstevel@tonic-gate if ((f_machine || f_server || f_root) && (argc != optind)) { 2497c478bd9Sstevel@tonic-gate error_str = gettext( 2507c478bd9Sstevel@tonic-gate "no filenames allowed with 'M' or 'S' or 'R' options"); 2517c478bd9Sstevel@tonic-gate error_combo = TRUE; 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate if (m_after >= m_before) { 2547c478bd9Sstevel@tonic-gate error_str = 255406d6273SPalle Lyckegaard gettext("'a' parameter must be before 'b' parameter"); 2567c478bd9Sstevel@tonic-gate error_combo = TRUE; 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate if (f_delete && 2597c478bd9Sstevel@tonic-gate (!f_complete || !f_all || !f_outfile)) { 2607c478bd9Sstevel@tonic-gate error_str = gettext( 2617c478bd9Sstevel@tonic-gate "'C', 'A', and 'O' must be specified with 'D'"); 2627c478bd9Sstevel@tonic-gate error_combo = TRUE; 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate if (f_stdin && (argc != optind)) { 2657c478bd9Sstevel@tonic-gate error_str = gettext("no filenames allowed with '-' option"); 2667c478bd9Sstevel@tonic-gate error_combo = TRUE; 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate /* 2697c478bd9Sstevel@tonic-gate * If error with option combos then print message and exit. 2707c478bd9Sstevel@tonic-gate * If there was an error with just an option then exit. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate if (error_combo) { 2737c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 2747c478bd9Sstevel@tonic-gate gettext("%s command line error - %s.\n"), ar, error_str); 2757c478bd9Sstevel@tonic-gate return (-1); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate if (f_root == NULL) 2787c478bd9Sstevel@tonic-gate f_root = "/etc/security/audit"; 2797c478bd9Sstevel@tonic-gate /* 2807c478bd9Sstevel@tonic-gate * Now handle any filenames included in the command line. 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate return (process_fileopt(argc, argv, optind)); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate int 2867c478bd9Sstevel@tonic-gate proc_subject(char *optarg) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate if (flags & M_SUBJECT) { 2897c478bd9Sstevel@tonic-gate error_str = gettext("'j' option specified multiple times"); 2907c478bd9Sstevel@tonic-gate return (-1); 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate flags |= M_SUBJECT; 2937c478bd9Sstevel@tonic-gate subj_id = atol(optarg); 2947c478bd9Sstevel@tonic-gate return (0); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 297924c9144Sgww int 298924c9144Sgww proc_sid(char *optarg) 299924c9144Sgww { 300924c9144Sgww if (flags & M_SID) { 301924c9144Sgww error_str = gettext("'s' option specified multiple times"); 302924c9144Sgww return (-1); 303924c9144Sgww } 304924c9144Sgww flags |= M_SID; 305d0fa49b7STony Nguyen m_sid = (au_asid_t)atol(optarg); 306924c9144Sgww return (0); 307924c9144Sgww } 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate int 3107c478bd9Sstevel@tonic-gate proc_object(char *optarg) 3117c478bd9Sstevel@tonic-gate { 3127c478bd9Sstevel@tonic-gate char *obj_str; 3137c478bd9Sstevel@tonic-gate char *obj_val; 3147c478bd9Sstevel@tonic-gate char *obj_arg; 3157c478bd9Sstevel@tonic-gate int err; 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate obj_ent_t *oep; 3187c478bd9Sstevel@tonic-gate struct hostent *he; 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate if (flags & M_OBJECT) { 3217c478bd9Sstevel@tonic-gate error_str = gettext("'o' option specified multiple times"); 3227c478bd9Sstevel@tonic-gate return (-1); 3237c478bd9Sstevel@tonic-gate } 3247c478bd9Sstevel@tonic-gate flags |= M_OBJECT; 3257c478bd9Sstevel@tonic-gate if ((obj_arg = strdup(optarg)) == (char *)0) 3267c478bd9Sstevel@tonic-gate return (-1); 3277c478bd9Sstevel@tonic-gate if ((obj_str = strtok(optarg, "=")) == (char *)0 || 3287c478bd9Sstevel@tonic-gate (oep = obj_lkup(obj_str)) == (obj_ent_t *)0 || 3297c478bd9Sstevel@tonic-gate (obj_val = strtok((char *)0, "=")) == (char *)0) { 3307c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid object arg (%s)"), 3317c478bd9Sstevel@tonic-gate obj_arg); 3327c478bd9Sstevel@tonic-gate error_str = errbuf; 3337c478bd9Sstevel@tonic-gate return (-1); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate obj_flag = oep->obj_flag; 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate switch (obj_flag) { 3397c478bd9Sstevel@tonic-gate case OBJ_PATH: 3407c478bd9Sstevel@tonic-gate if ((error_str = re_comp2(obj_val)) != (char *)NULL) { 3417c478bd9Sstevel@tonic-gate return (-1); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate return (0); 3447c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3457c478bd9Sstevel@tonic-gate case OBJ_SOCK: 3467c478bd9Sstevel@tonic-gate if (!a_isnum(obj_val, TRUE)) { 3477c478bd9Sstevel@tonic-gate obj_id = atol(obj_val); 3487c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_PORT; 3497c478bd9Sstevel@tonic-gate return (0); 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate if (*obj_val == '0') { 3527c478bd9Sstevel@tonic-gate (void) sscanf(obj_val, "%x", (uint_t *)&obj_id); 3537c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_PORT; 3547c478bd9Sstevel@tonic-gate return (0); 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate he = getipnodebyname((const void *)obj_val, AF_INET6, 0, &err); 3587c478bd9Sstevel@tonic-gate if (he == 0) { 3597c478bd9Sstevel@tonic-gate he = getipnodebyname((const void *)obj_val, AF_INET, 3607c478bd9Sstevel@tonic-gate 0, &err); 3617c478bd9Sstevel@tonic-gate if (he == 0) { 3627c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 3637c478bd9Sstevel@tonic-gate gettext("invalid machine name (%s)"), 3647c478bd9Sstevel@tonic-gate obj_val); 3657c478bd9Sstevel@tonic-gate error_str = errbuf; 3667c478bd9Sstevel@tonic-gate return (-1); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate if (he->h_addrtype == AF_INET6) { 3717c478bd9Sstevel@tonic-gate /* LINTED */ 372406d6273SPalle Lyckegaard if (IN6_IS_ADDR_V4MAPPED( 373406d6273SPalle Lyckegaard (in6_addr_t *)he->h_addr_list[0])) { 3747c478bd9Sstevel@tonic-gate /* address is IPv4 (32 bits) */ 375*9073e376SMarek Pospisil (void) memcpy(&obj_id, 376*9073e376SMarek Pospisil he->h_addr_list[0] + 12, 4); 3777c478bd9Sstevel@tonic-gate ip_type = AU_IPv4; 3787c478bd9Sstevel@tonic-gate } else { 3797c478bd9Sstevel@tonic-gate (void) memcpy(ip_ipv6, he->h_addr_list[0], 16); 3807c478bd9Sstevel@tonic-gate ip_type = AU_IPv6; 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate } else { 3837c478bd9Sstevel@tonic-gate /* address is IPv4 (32 bits) */ 3847c478bd9Sstevel@tonic-gate (void) memcpy(&obj_id, he->h_addr_list[0], 4); 3857c478bd9Sstevel@tonic-gate ip_type = AU_IPv4; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate freehostent(he); 3897c478bd9Sstevel@tonic-gate socket_flag = SOCKFLG_MACHINE; 3907c478bd9Sstevel@tonic-gate return (0); 3917c478bd9Sstevel@tonic-gate break; 3927c478bd9Sstevel@tonic-gate case OBJ_MSG: 3937c478bd9Sstevel@tonic-gate case OBJ_SEM: 3947c478bd9Sstevel@tonic-gate case OBJ_SHM: 3957c478bd9Sstevel@tonic-gate case OBJ_PROC: 3967c478bd9Sstevel@tonic-gate obj_id = atol(obj_val); 3977c478bd9Sstevel@tonic-gate return (0); 3987c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3997c478bd9Sstevel@tonic-gate case OBJ_FGROUP: 4007c478bd9Sstevel@tonic-gate case OBJ_MSGGROUP: 4017c478bd9Sstevel@tonic-gate case OBJ_SEMGROUP: 4027c478bd9Sstevel@tonic-gate case OBJ_SHMGROUP: 4037c478bd9Sstevel@tonic-gate case OBJ_PGROUP: 4047c478bd9Sstevel@tonic-gate return (proc_group(obj_val, &obj_group)); 4057c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4067c478bd9Sstevel@tonic-gate case OBJ_FOWNER: 4077c478bd9Sstevel@tonic-gate case OBJ_MSGOWNER: 4087c478bd9Sstevel@tonic-gate case OBJ_SEMOWNER: 4097c478bd9Sstevel@tonic-gate case OBJ_SHMOWNER: 4107c478bd9Sstevel@tonic-gate case OBJ_POWNER: 4117c478bd9Sstevel@tonic-gate return (proc_user(obj_val, &obj_owner)); 4127c478bd9Sstevel@tonic-gate /* NOTREACHED */ 413103b2b15Sgww case OBJ_FMRI: 414103b2b15Sgww return (proc_fmri(obj_val)); 415103b2b15Sgww /* NOTREACHED */ 4167c478bd9Sstevel@tonic-gate case OBJ_LP: /* lp objects have not yet been defined */ 4177c478bd9Sstevel@tonic-gate default: /* impossible */ 4187c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid object type (%s)"), 4197c478bd9Sstevel@tonic-gate obj_str); 4207c478bd9Sstevel@tonic-gate error_str = errbuf; 4217c478bd9Sstevel@tonic-gate return (-1); 4227c478bd9Sstevel@tonic-gate /* NOTREACHED */ 4237c478bd9Sstevel@tonic-gate } /* switch */ 4247c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 4257c478bd9Sstevel@tonic-gate } 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate obj_ent_t * 4297c478bd9Sstevel@tonic-gate obj_lkup(char *obj_str) 4307c478bd9Sstevel@tonic-gate { 4317c478bd9Sstevel@tonic-gate int i; 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof (obj_tbl) / sizeof (obj_ent_t); i++) 4347c478bd9Sstevel@tonic-gate if (strcmp(obj_str, obj_tbl[i].obj_str) == 0) 4357c478bd9Sstevel@tonic-gate return (&obj_tbl[i]); 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate /* not in table */ 438d0fa49b7STony Nguyen return (NULL); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate 4427c478bd9Sstevel@tonic-gate /* 4437c478bd9Sstevel@tonic-gate * .func proc_type - process record type. 4447c478bd9Sstevel@tonic-gate * .desc Process a record type. It is either as a number or a mnemonic. 4457c478bd9Sstevel@tonic-gate * .call ret = proc_type(optstr). 4467c478bd9Sstevel@tonic-gate * .arg optstr - ptr to name or number. 4477c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 4487c478bd9Sstevel@tonic-gate * .ret -1 - error detected (error_str contains description). 4497c478bd9Sstevel@tonic-gate */ 4507c478bd9Sstevel@tonic-gate int 4517c478bd9Sstevel@tonic-gate proc_type(char *optstr) 4527c478bd9Sstevel@tonic-gate { 4537c478bd9Sstevel@tonic-gate struct au_event_ent *aep; 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate /* 4567c478bd9Sstevel@tonic-gate * Either a number or a name. 4577c478bd9Sstevel@tonic-gate */ 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate if (flags & M_TYPE) { 4607c478bd9Sstevel@tonic-gate error_str = gettext("'m' option specified multiple times"); 4617c478bd9Sstevel@tonic-gate return (-1); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate flags |= M_TYPE; 4647c478bd9Sstevel@tonic-gate m_type = 0; 4657c478bd9Sstevel@tonic-gate if (a_isnum(optstr, TRUE)) { 466d0fa49b7STony Nguyen if ((aep = getauevnam(optstr)) != NULL) 4677c478bd9Sstevel@tonic-gate m_type = aep->ae_number; 4687c478bd9Sstevel@tonic-gate } else { 4697c478bd9Sstevel@tonic-gate if ((aep = getauevnum((au_event_t)atoi(optstr))) != 4707c478bd9Sstevel@tonic-gate (struct au_event_ent *)NULL) 4717c478bd9Sstevel@tonic-gate m_type = aep->ae_number; 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate if ((m_type == 0)) { 4747c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("invalid event (%s)"), optstr); 4757c478bd9Sstevel@tonic-gate error_str = errbuf; 4767c478bd9Sstevel@tonic-gate return (-1); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate return (0); 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* 4837c478bd9Sstevel@tonic-gate * .func a_isnum - is it a number? 4847c478bd9Sstevel@tonic-gate * .desc Determine if a string is a number or a name. 4857c478bd9Sstevel@tonic-gate * A number may have a leading '+' or '-', but then must be 4867c478bd9Sstevel@tonic-gate * all digits. 4877c478bd9Sstevel@tonic-gate * .call ret = a_isnum(str). 4887c478bd9Sstevel@tonic-gate * .arg str - ptr to the string. 4897c478bd9Sstevel@tonic-gate * .arg leading - TRUE if leading '+-' allowed. 4907c478bd9Sstevel@tonic-gate * .ret 0 - is a number. 4917c478bd9Sstevel@tonic-gate * .ret 1 - is not a number. 4927c478bd9Sstevel@tonic-gate */ 4937c478bd9Sstevel@tonic-gate int 4947c478bd9Sstevel@tonic-gate a_isnum(char *str, int leading) 4957c478bd9Sstevel@tonic-gate { 4967c478bd9Sstevel@tonic-gate char *strs; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if ((leading == TRUE) && (*str == '-' || *str == '+')) 4997c478bd9Sstevel@tonic-gate strs = str + 1; 5007c478bd9Sstevel@tonic-gate else 5017c478bd9Sstevel@tonic-gate strs = str; 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate if (strlen(strs) == strspn(strs, "0123456789")) 5047c478bd9Sstevel@tonic-gate return (0); 5057c478bd9Sstevel@tonic-gate else 5067c478bd9Sstevel@tonic-gate return (1); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate /* 5117c478bd9Sstevel@tonic-gate * .func proc_id - process user/group id's/ 5127c478bd9Sstevel@tonic-gate * .desc Process either a user number/name or group number/name. 5137c478bd9Sstevel@tonic-gate * For names check to see if the name is active in the system 5147c478bd9Sstevel@tonic-gate * to derive the number. If it is not active then fail. For a number 5157c478bd9Sstevel@tonic-gate * also check to see if it is active, but only print a warning if it 5167c478bd9Sstevel@tonic-gate * is not. An administrator may be looking at activity of a 'phantom' 5177c478bd9Sstevel@tonic-gate * user. 5187c478bd9Sstevel@tonic-gate * .call ret = proc_id(optstr, opt). 5197c478bd9Sstevel@tonic-gate * .arg optstr - ptr to name or number. 5207c478bd9Sstevel@tonic-gate * .arg opt - 'u' - audit user, 'e' - effective user, 'r' - real user, 5217c478bd9Sstevel@tonic-gate * 'g' - group, 'f' - effective group. 5227c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 5237c478bd9Sstevel@tonic-gate * .ret -1 - error detected (error_str contains description). 5247c478bd9Sstevel@tonic-gate */ 5257c478bd9Sstevel@tonic-gate int 5267c478bd9Sstevel@tonic-gate proc_id(char *optstr, int opt) 5277c478bd9Sstevel@tonic-gate { 5287c478bd9Sstevel@tonic-gate switch (opt) { 5297c478bd9Sstevel@tonic-gate case 'e': /* effective user id */ 5307c478bd9Sstevel@tonic-gate if (flags & M_USERE) { 5317c478bd9Sstevel@tonic-gate error_str = gettext( 5327c478bd9Sstevel@tonic-gate "'e' option specified multiple times"); 5337c478bd9Sstevel@tonic-gate return (-1); 5347c478bd9Sstevel@tonic-gate } 5357c478bd9Sstevel@tonic-gate flags |= M_USERE; 5367c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_usere)); 5377c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5387c478bd9Sstevel@tonic-gate case 'f': /* effective group id */ 5397c478bd9Sstevel@tonic-gate if (flags & M_GROUPE) { 5407c478bd9Sstevel@tonic-gate error_str = gettext( 5417c478bd9Sstevel@tonic-gate "'f' option specified multiple times"); 5427c478bd9Sstevel@tonic-gate return (-1); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate flags |= M_GROUPE; 5457c478bd9Sstevel@tonic-gate return (proc_group(optstr, &m_groupe)); 5467c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5477c478bd9Sstevel@tonic-gate case 'r': /* real user id */ 5487c478bd9Sstevel@tonic-gate if (flags & M_USERR) { 5497c478bd9Sstevel@tonic-gate error_str = gettext( 5507c478bd9Sstevel@tonic-gate "'r' option specified multiple times"); 5517c478bd9Sstevel@tonic-gate return (-1); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate flags |= M_USERR; 5547c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_userr)); 5557c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5567c478bd9Sstevel@tonic-gate case 'u': /* audit user id */ 5577c478bd9Sstevel@tonic-gate if (flags & M_USERA) { 5587c478bd9Sstevel@tonic-gate error_str = gettext( 5597c478bd9Sstevel@tonic-gate "'u' option specified multiple times"); 5607c478bd9Sstevel@tonic-gate return (-1); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate flags |= M_USERA; 5637c478bd9Sstevel@tonic-gate return (proc_user(optstr, &m_usera)); 5647c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5657c478bd9Sstevel@tonic-gate case 'g': /* real group id */ 5667c478bd9Sstevel@tonic-gate if (flags & M_GROUPR) { 5677c478bd9Sstevel@tonic-gate error_str = gettext( 5687c478bd9Sstevel@tonic-gate "'g' option specified multiple times"); 5697c478bd9Sstevel@tonic-gate return (-1); 5707c478bd9Sstevel@tonic-gate } 5717c478bd9Sstevel@tonic-gate flags |= M_GROUPR; 5727c478bd9Sstevel@tonic-gate return (proc_group(optstr, &m_groupr)); 5737c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5747c478bd9Sstevel@tonic-gate default: /* impossible */ 5757c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("'%c' unknown option"), opt); 5767c478bd9Sstevel@tonic-gate error_str = errbuf; 5777c478bd9Sstevel@tonic-gate return (-1); 5787c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 5817c478bd9Sstevel@tonic-gate } 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate int 5857c478bd9Sstevel@tonic-gate proc_group(char *optstr, gid_t *gid) 5867c478bd9Sstevel@tonic-gate { 5877c478bd9Sstevel@tonic-gate struct group *grp; 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate if ((grp = getgrnam(optstr)) == NULL) { 5907c478bd9Sstevel@tonic-gate if (!a_isnum(optstr, TRUE)) { 5917c478bd9Sstevel@tonic-gate *gid = (gid_t)atoi(optstr); 5927c478bd9Sstevel@tonic-gate return (0); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("group name invalid (%s)"), 5957c478bd9Sstevel@tonic-gate optstr); 5967c478bd9Sstevel@tonic-gate error_str = errbuf; 5977c478bd9Sstevel@tonic-gate return (-1); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate *gid = grp->gr_gid; 6007c478bd9Sstevel@tonic-gate return (0); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate int 6057c478bd9Sstevel@tonic-gate proc_user(char *optstr, uid_t *uid) 6067c478bd9Sstevel@tonic-gate { 6077c478bd9Sstevel@tonic-gate struct passwd *usr; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if ((usr = getpwnam(optstr)) == NULL) { 6107c478bd9Sstevel@tonic-gate if (!a_isnum(optstr, TRUE)) { 6117c478bd9Sstevel@tonic-gate *uid = (uid_t)atoi(optstr); 6127c478bd9Sstevel@tonic-gate return (0); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("user name invalid (%s)"), 6157c478bd9Sstevel@tonic-gate optstr); 6167c478bd9Sstevel@tonic-gate error_str = errbuf; 6177c478bd9Sstevel@tonic-gate return (-1); 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate *uid = usr->pw_uid; 6207c478bd9Sstevel@tonic-gate return (0); 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate /* 6257c478bd9Sstevel@tonic-gate * .func proc_date - process date argument. 6267c478bd9Sstevel@tonic-gate * .desc Handle a date/time argument. See if the user has erred in combining 6277c478bd9Sstevel@tonic-gate * the types of date arguments. Then parse the string and check for 6287c478bd9Sstevel@tonic-gate * validity of each part. 6297c478bd9Sstevel@tonic-gate * .call ret = proc_date(optstr, opt). 6307c478bd9Sstevel@tonic-gate * .arg optstr - ptr to date/time string. 6317c478bd9Sstevel@tonic-gate * .arg opt - 'd' for day, 'a' for after, or 'b' for before. 6327c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 6337c478bd9Sstevel@tonic-gate * .ret -1 - errors detected (error_str knows what it is). 6347c478bd9Sstevel@tonic-gate */ 6357c478bd9Sstevel@tonic-gate int 6367c478bd9Sstevel@tonic-gate proc_date(char *optstr, int opt) 6377c478bd9Sstevel@tonic-gate { 6387c478bd9Sstevel@tonic-gate static int m_day = FALSE; 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate if (opt == 'd') { 6417c478bd9Sstevel@tonic-gate if (m_day == TRUE) { 6427c478bd9Sstevel@tonic-gate error_str = gettext( 6437c478bd9Sstevel@tonic-gate "'d' option may not be used with 'a' or 'b'"); 6447c478bd9Sstevel@tonic-gate return (-1); 6457c478bd9Sstevel@tonic-gate } 6467c478bd9Sstevel@tonic-gate m_day = TRUE; 6477c478bd9Sstevel@tonic-gate } 6487c478bd9Sstevel@tonic-gate if ((opt == 'd') && (m_before || m_after)) { 6497c478bd9Sstevel@tonic-gate error_str = gettext( 6507c478bd9Sstevel@tonic-gate "'d' option may not be used with 'a' or 'b'"); 6517c478bd9Sstevel@tonic-gate return (-1); 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate if ((opt == 'a' || opt == 'b') && m_day) { 6547c478bd9Sstevel@tonic-gate error_str = gettext( 6557c478bd9Sstevel@tonic-gate "'a' or 'b' option may not be used with 'd'"); 6567c478bd9Sstevel@tonic-gate return (-1); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate if ((opt == 'a') && (m_after != 0)) { 6597c478bd9Sstevel@tonic-gate error_str = gettext("'a' option specified multiple times"); 6607c478bd9Sstevel@tonic-gate return (-1); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate if ((opt == 'b') && (m_before != 0)) { 6637c478bd9Sstevel@tonic-gate error_str = gettext("'b' option specified multiple times"); 6647c478bd9Sstevel@tonic-gate return (-1); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate if (parse_time(optstr, opt)) 6677c478bd9Sstevel@tonic-gate return (-1); 6687c478bd9Sstevel@tonic-gate return (0); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * .func proc_class - process message class argument. 6747c478bd9Sstevel@tonic-gate * .desc Process class type and see if it is for real. 6757c478bd9Sstevel@tonic-gate * .call ret = proc_class(optstr). 6767c478bd9Sstevel@tonic-gate * .arg optstr - ptr to class. 6777c478bd9Sstevel@tonic-gate * .ret 0 - class has class. 6787c478bd9Sstevel@tonic-gate * .ret -1 - class in no good. 6797c478bd9Sstevel@tonic-gate */ 6807c478bd9Sstevel@tonic-gate int 6817c478bd9Sstevel@tonic-gate proc_class(char *optstr) 6827c478bd9Sstevel@tonic-gate { 6837c478bd9Sstevel@tonic-gate if (flags & M_CLASS) { 6847c478bd9Sstevel@tonic-gate error_str = gettext("'c' option specified multiple times"); 6857c478bd9Sstevel@tonic-gate return (-1); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate flags |= M_CLASS; 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate if (getauditflagsbin(optstr, &mask) != 0) { 6907c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("unknown class (%s)"), optstr); 6917c478bd9Sstevel@tonic-gate error_str = errbuf; 6927c478bd9Sstevel@tonic-gate return (-1); 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate if (mask.am_success != mask.am_failure) { 6967c478bd9Sstevel@tonic-gate flags |= M_SORF; 6977c478bd9Sstevel@tonic-gate } 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate return (0); 7007c478bd9Sstevel@tonic-gate } 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate /* 7047c478bd9Sstevel@tonic-gate * .func process_fileopt - process command line file options. 7057c478bd9Sstevel@tonic-gate * .desc Process the command line file options and gather the specified files 7067c478bd9Sstevel@tonic-gate * together in file groups based upon file name suffix. The user can 7077c478bd9Sstevel@tonic-gate * specify files explicitly on the command line or via a directory. 7087c478bd9Sstevel@tonic-gate * This is called after the command line flags are processed (as 7097c478bd9Sstevel@tonic-gate * denoted by '-'). 7107c478bd9Sstevel@tonic-gate * .call ret = process_fileopt(argc, argv, optindex). 7117c478bd9Sstevel@tonic-gate * .arg argc - current value of argc. 7127c478bd9Sstevel@tonic-gate * .arg argv - current value of argv. 7137c478bd9Sstevel@tonic-gate * .arg optindex- current index into argv (as setup by getopt()). 7147c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 7157c478bd9Sstevel@tonic-gate * .ret -1 - error detected (message already printed). 7167c478bd9Sstevel@tonic-gate */ 7177c478bd9Sstevel@tonic-gate int 7187c478bd9Sstevel@tonic-gate process_fileopt(int argc, char **argv, int optindex) 7197c478bd9Sstevel@tonic-gate { 7207c478bd9Sstevel@tonic-gate int f_mode = FM_ALLDIR; 7217c478bd9Sstevel@tonic-gate char f_dr[MAXNAMLEN+1]; 7227c478bd9Sstevel@tonic-gate char *f_dir = f_dr; 7237c478bd9Sstevel@tonic-gate char *fname; 7247c478bd9Sstevel@tonic-gate static char *std = "standard input"; 7257c478bd9Sstevel@tonic-gate audit_fcb_t *fcb; 7267c478bd9Sstevel@tonic-gate DIR * dirp; 7277c478bd9Sstevel@tonic-gate struct dirent *dp; 7287c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate /* 7317c478bd9Sstevel@tonic-gate * Take input from stdin, not any files. 7327c478bd9Sstevel@tonic-gate * Use a single fcb to do this. 7337c478bd9Sstevel@tonic-gate */ 7347c478bd9Sstevel@tonic-gate if (f_stdin) { 7357c478bd9Sstevel@tonic-gate fcb = (audit_fcb_t *)a_calloc(1, sizeof (*fcb) + strlen(std)); 7367c478bd9Sstevel@tonic-gate (void) strcpy(fcb->fcb_file, std); 7377c478bd9Sstevel@tonic-gate fcb->fcb_suffix = fcb->fcb_name = fcb->fcb_file; 7387c478bd9Sstevel@tonic-gate fcb->fcb_next = NULL; 7397c478bd9Sstevel@tonic-gate fcb->fcb_start = 0; 7407c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 7417c478bd9Sstevel@tonic-gate if ((pcb = get_next_pcb((char *)NULL)) == (audit_pcb_t *)NULL) 7427c478bd9Sstevel@tonic-gate return (-1); 7437c478bd9Sstevel@tonic-gate pcb->pcb_suffix = fcb->fcb_file; 7447c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; /* one-item list */ 7457c478bd9Sstevel@tonic-gate pcb->pcb_dlast = pcb->pcb_last = fcb; 7467c478bd9Sstevel@tonic-gate pcb->pcb_cur = fcb; 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate /* 7497c478bd9Sstevel@tonic-gate * No files specified on the command line. 7507c478bd9Sstevel@tonic-gate * Process a directory of files or subdirectories. 7517c478bd9Sstevel@tonic-gate */ 7527c478bd9Sstevel@tonic-gate else if (argc == optindex) { 7537c478bd9Sstevel@tonic-gate /* 7547c478bd9Sstevel@tonic-gate * A specific server directory was requested. 7557c478bd9Sstevel@tonic-gate */ 7567c478bd9Sstevel@tonic-gate if (f_server) { 7577c478bd9Sstevel@tonic-gate if (strchr(f_server, '/')) { /* given full path */ 7587c478bd9Sstevel@tonic-gate f_dir = f_server; 7597c478bd9Sstevel@tonic-gate f_mode = FM_ALLFILE; /* all files here */ 7607c478bd9Sstevel@tonic-gate } else { /* directory off audit root */ 7617c478bd9Sstevel@tonic-gate f_dir[0] = '\0'; 7627c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_root); 7637c478bd9Sstevel@tonic-gate (void) strcat(f_dir, "/"); 7647c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_server); 7657c478bd9Sstevel@tonic-gate f_mode = FM_ALLFILE; 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate /* 7697c478bd9Sstevel@tonic-gate * Gather all of the files in the directory 'f_dir'. 7707c478bd9Sstevel@tonic-gate */ 7717c478bd9Sstevel@tonic-gate if (f_mode == FM_ALLFILE) { 7727c478bd9Sstevel@tonic-gate if (gather_dir(f_dir)) { /* get those files together */ 7737c478bd9Sstevel@tonic-gate return (-1); 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate } else { 7767c478bd9Sstevel@tonic-gate /* 7777c478bd9Sstevel@tonic-gate * Gather all of the files in all of the 7787c478bd9Sstevel@tonic-gate * directories in 'f_root'. 7797c478bd9Sstevel@tonic-gate */ 7807c478bd9Sstevel@tonic-gate if ((dirp = opendir(f_root)) == NULL) { 7817c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext( 7827c478bd9Sstevel@tonic-gate "%s can't open directory %s"), ar, f_root); 7837c478bd9Sstevel@tonic-gate perror(errbuf); 7847c478bd9Sstevel@tonic-gate return (-1); 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate /* read the directory and process all of the subs */ 7877c478bd9Sstevel@tonic-gate for (dp = readdir(dirp); 7887c478bd9Sstevel@tonic-gate dp != NULL; dp = readdir(dirp)) { 7897c478bd9Sstevel@tonic-gate if (dp->d_name[0] == '.') 7907c478bd9Sstevel@tonic-gate continue; 7917c478bd9Sstevel@tonic-gate f_dir[0] = '\0'; 7927c478bd9Sstevel@tonic-gate (void) strcat(f_dir, f_root); 7937c478bd9Sstevel@tonic-gate (void) strcat(f_dir, "/"); 7947c478bd9Sstevel@tonic-gate (void) strcat(f_dir, dp->d_name); 7957c478bd9Sstevel@tonic-gate if (gather_dir(f_dir)) /* process a sub */ 7967c478bd9Sstevel@tonic-gate return (-1); 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate (void) closedir(dirp); 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate } else { 8017c478bd9Sstevel@tonic-gate /* 8027c478bd9Sstevel@tonic-gate * User specified filenames on the comm and line. 8037c478bd9Sstevel@tonic-gate */ 8047c478bd9Sstevel@tonic-gate f_cmdline = TRUE; 8057c478bd9Sstevel@tonic-gate for (; optindex < argc; optindex++) { 8067c478bd9Sstevel@tonic-gate fname = argv[optindex]; /* get a filename */ 8077c478bd9Sstevel@tonic-gate if (proc_file(fname, FALSE)) 8087c478bd9Sstevel@tonic-gate return (-1); 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate return (0); 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* 8167c478bd9Sstevel@tonic-gate * .func gather_dir - gather a directory's files together. 8177c478bd9Sstevel@tonic-gate * .desc Process all of the files in a specific directory. The files may 8187c478bd9Sstevel@tonic-gate * be checked for adherence to the file name form at. 8197c478bd9Sstevel@tonic-gate * If the directory can't be opened that is ok - just print 8207c478bd9Sstevel@tonic-gate * a message and continue. 8217c478bd9Sstevel@tonic-gate * .call ret = gather_dir(dir). 8227c478bd9Sstevel@tonic-gate * .arg dir - ptr to full pathname of directory. 8237c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 8247c478bd9Sstevel@tonic-gate * .ret -1 - error detected (message already printed). 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate int 8277c478bd9Sstevel@tonic-gate gather_dir(char *dir) 8287c478bd9Sstevel@tonic-gate { 8297c478bd9Sstevel@tonic-gate char dname[MAXNAMLEN+1]; 8307c478bd9Sstevel@tonic-gate char fname[MAXNAMLEN+1]; 8317c478bd9Sstevel@tonic-gate DIR * dirp; 8327c478bd9Sstevel@tonic-gate struct dirent *dp; 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate (void) snprintf(dname, sizeof (dname), "%s/files", dir); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate if ((dirp = opendir(dname)) == NULL) { 8377c478bd9Sstevel@tonic-gate if (errno != ENOTDIR) { 8387c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 8397c478bd9Sstevel@tonic-gate gettext("%s can't open directory - %s"), ar, dname); 8407c478bd9Sstevel@tonic-gate perror(errbuf); 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate return (0); 8437c478bd9Sstevel@tonic-gate } 8447c478bd9Sstevel@tonic-gate for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { 8457c478bd9Sstevel@tonic-gate if (dp->d_name[0] == '.') /* can't see hidden files */ 8467c478bd9Sstevel@tonic-gate continue; 8477c478bd9Sstevel@tonic-gate fname[0] = '\0'; 8487c478bd9Sstevel@tonic-gate (void) strcat(fname, dname); /* create pathname of file */ 8497c478bd9Sstevel@tonic-gate (void) strcat(fname, "/"); 8507c478bd9Sstevel@tonic-gate (void) strcat(fname, dp->d_name); 8517c478bd9Sstevel@tonic-gate if (proc_file(fname, TRUE)) 8527c478bd9Sstevel@tonic-gate return (-1); 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate (void) closedir(dirp); 8557c478bd9Sstevel@tonic-gate return (0); 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate /* 8607c478bd9Sstevel@tonic-gate * .func proc_file - process a single candidate file. 8617c478bd9Sstevel@tonic-gate * .desc Check out a file to see if it should be used in the merge. 8627c478bd9Sstevel@tonic-gate * This includes checking the name (mode is TRUE) against the 8637c478bd9Sstevel@tonic-gate * file format, checking access rights to the file, and thence 8647c478bd9Sstevel@tonic-gate * getting and fcb and installing the fcb into the correct pcb. 8657c478bd9Sstevel@tonic-gate * If the file fails then the fcb is not installed into a pcb 8667c478bd9Sstevel@tonic-gate * and the file dissapears from view. 8677c478bd9Sstevel@tonic-gate * .call proc_file(fname, mode). 8687c478bd9Sstevel@tonic-gate * .arg fname - ptr to full pathna me of file. 8697c478bd9Sstevel@tonic-gate * .arg mode - TRUE if checking adherence to file name format. 8707c478bd9Sstevel@tonic-gate * .ret 0 - no fatal errors detected. 8717c478bd9Sstevel@tonic-gate * .ret -1 - fatal error detected - quit altogether 8727c478bd9Sstevel@tonic-gate * (message already printed). 8737c478bd9Sstevel@tonic-gate */ 8747c478bd9Sstevel@tonic-gate int 8757c478bd9Sstevel@tonic-gate proc_file(char *fname, int mode) 8767c478bd9Sstevel@tonic-gate { 8777c478bd9Sstevel@tonic-gate int reject = FALSE; 8787c478bd9Sstevel@tonic-gate size_t len; 8797c478bd9Sstevel@tonic-gate struct stat stat_buf; 8807c478bd9Sstevel@tonic-gate audit_fcb_t *fcb, *fcbp, *fcbprev; 8817c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate /* 8847c478bd9Sstevel@tonic-gate * See if it is a weird file like a directory or 8857c478bd9Sstevel@tonic-gate * character special (around here?). 8867c478bd9Sstevel@tonic-gate */ 8877c478bd9Sstevel@tonic-gate if (stat(fname, &stat_buf)) { 8887c478bd9Sstevel@tonic-gate return (0); 8897c478bd9Sstevel@tonic-gate } 8904bc0a2efScasper if (!S_ISREG(stat_buf.st_mode)) 8917c478bd9Sstevel@tonic-gate return (0); 8927c478bd9Sstevel@tonic-gate /* 8937c478bd9Sstevel@tonic-gate * Allocate a new fcb to hold fcb and full filename. 8947c478bd9Sstevel@tonic-gate */ 8957c478bd9Sstevel@tonic-gate len = sizeof (audit_fcb_t) + strlen(fname); 8967c478bd9Sstevel@tonic-gate fcb = (audit_fcb_t *)a_calloc(1, len); 8977c478bd9Sstevel@tonic-gate (void) strcpy(fcb->fcb_file, fname); 8987c478bd9Sstevel@tonic-gate if (check_file(fcb, mode)) { /* check file name */ 8997c478bd9Sstevel@tonic-gate if (!f_quiet) { 9007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s %s:\n %s.\n", ar, 9017c478bd9Sstevel@tonic-gate error_str, fname); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate reject = TRUE; 9047c478bd9Sstevel@tonic-gate } else { 9057c478bd9Sstevel@tonic-gate /* 9067c478bd9Sstevel@tonic-gate * Check against file criteria. 9077c478bd9Sstevel@tonic-gate * Check finish-time here, and start-time later on 9087c478bd9Sstevel@tonic-gate * while processing. 9097c478bd9Sstevel@tonic-gate * This is because the start time on a file can be after 9107c478bd9Sstevel@tonic-gate * the first record(s). 9117c478bd9Sstevel@tonic-gate */ 9127c478bd9Sstevel@tonic-gate if (f_complete && (fcb->fcb_flags & FF_NOTTERM) && !f_cmdline) 9137c478bd9Sstevel@tonic-gate reject = TRUE; 9147c478bd9Sstevel@tonic-gate if (!f_all && (fcb->fcb_end < m_after)) 9157c478bd9Sstevel@tonic-gate reject = TRUE; 9167c478bd9Sstevel@tonic-gate if (f_machine) { 9177c478bd9Sstevel@tonic-gate if (strlen(fcb->fcb_suffix) != strlen(f_machine) || 9187c478bd9Sstevel@tonic-gate (strcmp(fcb->fcb_suffix, f_machine) != 0)) { 9197c478bd9Sstevel@tonic-gate reject = TRUE; 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate if (reject == FALSE) { 9247c478bd9Sstevel@tonic-gate filenum++; /* count of total files to be processed */ 9257c478bd9Sstevel@tonic-gate fcb->fcb_next = NULL; 9267c478bd9Sstevel@tonic-gate if ((pcb = get_next_pcb(fcb->fcb_suffix)) == NULL) { 9277c478bd9Sstevel@tonic-gate return (-1); 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate /* Place FCB into the PCB in order - oldest first. */ 9307c478bd9Sstevel@tonic-gate fcbp = pcb->pcb_first; 9317c478bd9Sstevel@tonic-gate fcbprev = NULL; 9327c478bd9Sstevel@tonic-gate while (fcbp != NULL) { 9337c478bd9Sstevel@tonic-gate if (fcb->fcb_start < fcbp->fcb_start) { 9347c478bd9Sstevel@tonic-gate if (fcbprev) 9357c478bd9Sstevel@tonic-gate fcbprev->fcb_next = fcb; 9367c478bd9Sstevel@tonic-gate else 9377c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; 9387c478bd9Sstevel@tonic-gate fcb->fcb_next = fcbp; 9397c478bd9Sstevel@tonic-gate break; 9407c478bd9Sstevel@tonic-gate } 9417c478bd9Sstevel@tonic-gate fcbprev = fcbp; 9427c478bd9Sstevel@tonic-gate fcbp = fcbp->fcb_next; 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate /* younger than all || empty list */ 9457c478bd9Sstevel@tonic-gate if (!fcb->fcb_next) { 9467c478bd9Sstevel@tonic-gate if (pcb->pcb_first == NULL) 9477c478bd9Sstevel@tonic-gate pcb->pcb_dfirst = pcb->pcb_first = fcb; 9487c478bd9Sstevel@tonic-gate pcb->pcb_dlast = pcb->pcb_last = fcb; 9497c478bd9Sstevel@tonic-gate if (fcbprev) 9507c478bd9Sstevel@tonic-gate fcbprev->fcb_next = fcb; 9517c478bd9Sstevel@tonic-gate } 9527c478bd9Sstevel@tonic-gate } else { 9537c478bd9Sstevel@tonic-gate free((char *)fcb); /* rejected */ 9547c478bd9Sstevel@tonic-gate } 9557c478bd9Sstevel@tonic-gate return (0); 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate /* 9607c478bd9Sstevel@tonic-gate * .func check_file - check filename and setup fcb. 9617c478bd9Sstevel@tonic-gate * .desc Check adherence to the file format (do_check is TRUE) and setup 9627c478bd9Sstevel@tonic-gate * the fcb with useful information. 9637c478bd9Sstevel@tonic-gate * filename format: yyyymmddhhmmss.yyyymmddhhmmss.suffix 9647c478bd9Sstevel@tonic-gate * yyyymmddhhmmss.not_terminated.suffix 9657c478bd9Sstevel@tonic-gate * If do_check is FALSE then still see if the filename does confirm 9667c478bd9Sstevel@tonic-gate * to the format. If it does then extract useful information from 9677c478bd9Sstevel@tonic-gate * it (start time and end time). But if it doesn't then don't print 9687c478bd9Sstevel@tonic-gate * any error messages. 9697c478bd9Sstevel@tonic-gate * .call ret = check_file(fcb, do_check). 9707c478bd9Sstevel@tonic-gate * .arg fcb - ptr to fcb that holds the file. 9717c478bd9Sstevel@tonic-gate * .arg do_check - if TRUE do check adherence to file format. 9727c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 9737c478bd9Sstevel@tonic-gate * .ret -1 - file failed somehow (error_str tells why). 9747c478bd9Sstevel@tonic-gate */ 9757c478bd9Sstevel@tonic-gate int 9767c478bd9Sstevel@tonic-gate check_file(audit_fcb_t *fcb, int do_check) 9777c478bd9Sstevel@tonic-gate { 9787c478bd9Sstevel@tonic-gate int ret; 9797c478bd9Sstevel@tonic-gate char *namep, *slp; 9807c478bd9Sstevel@tonic-gate char errb[256]; /* build error message */ 9817c478bd9Sstevel@tonic-gate struct tm tme; 9827c478bd9Sstevel@tonic-gate 9837c478bd9Sstevel@tonic-gate errb[0] = '\0'; 9847c478bd9Sstevel@tonic-gate /* get just the filename */ 9857c478bd9Sstevel@tonic-gate for (slp = namep = fcb->fcb_file; *namep; namep++) { 9867c478bd9Sstevel@tonic-gate if (*namep == '/') 9877c478bd9Sstevel@tonic-gate slp = namep + 1; /* slp -> the filename itself */ 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate if (do_check == FALSE) { 9907c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 9917c478bd9Sstevel@tonic-gate fcb->fcb_suffix = NULL; 9927c478bd9Sstevel@tonic-gate fcb->fcb_name = slp; 9937c478bd9Sstevel@tonic-gate ret = 0; 9947c478bd9Sstevel@tonic-gate } else { 9957c478bd9Sstevel@tonic-gate ret = -1; 9967c478bd9Sstevel@tonic-gate } 9977c478bd9Sstevel@tonic-gate if ((int)strlen(slp) < 31) { 9987c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, gettext("filename too short (%d)"), 9997c478bd9Sstevel@tonic-gate strlen(slp)); 10007c478bd9Sstevel@tonic-gate error_str = errbuf; 10017c478bd9Sstevel@tonic-gate return (ret); 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * Get working copy of filename. 10057c478bd9Sstevel@tonic-gate */ 10067c478bd9Sstevel@tonic-gate namep = (char *)a_calloc(1, strlen(slp) + 1); 10077c478bd9Sstevel@tonic-gate (void) strcpy(namep, slp); 10087c478bd9Sstevel@tonic-gate if (namep[14] != '.' || namep[29] != '.') { 10097c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 10107c478bd9Sstevel@tonic-gate gettext("invalid filename format (%c or %c)"), namep[14], 10117c478bd9Sstevel@tonic-gate namep[29]); 10127c478bd9Sstevel@tonic-gate error_str = errbuf; 10137c478bd9Sstevel@tonic-gate free(namep); 10147c478bd9Sstevel@tonic-gate return (ret); 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate namep[14] = '\0'; /* mark off start time */ 10177c478bd9Sstevel@tonic-gate namep[29] = '\0'; /* mark off finish time */ 10187c478bd9Sstevel@tonic-gate if (derive_date(namep, &tme)) { 10197c478bd9Sstevel@tonic-gate (void) strcat(errb, gettext("starting time-stamp invalid - ")); 10207c478bd9Sstevel@tonic-gate (void) strcat(errb, error_str); 10217c478bd9Sstevel@tonic-gate (void) strcpy(errbuf, errb); 10227c478bd9Sstevel@tonic-gate error_str = errbuf; 10237c478bd9Sstevel@tonic-gate free(namep); 10247c478bd9Sstevel@tonic-gate return (ret); 10257c478bd9Sstevel@tonic-gate } 10267c478bd9Sstevel@tonic-gate /* 10277c478bd9Sstevel@tonic-gate * Keep start time from filename. Use it to order files in 10287c478bd9Sstevel@tonic-gate * the file list. Later we will update this when we read 10297c478bd9Sstevel@tonic-gate * the first record from the file. 10307c478bd9Sstevel@tonic-gate */ 10317c478bd9Sstevel@tonic-gate fcb->fcb_start = tm_to_secs(&tme); 10327c478bd9Sstevel@tonic-gate 10337c478bd9Sstevel@tonic-gate if (strcmp(&namep[15], "not_terminated") == 0) { 10347c478bd9Sstevel@tonic-gate fcb->fcb_end = MAXLONG; /* forever */ 10357c478bd9Sstevel@tonic-gate /* 10367c478bd9Sstevel@tonic-gate * Only treat a 'not_terminated' file as such if 10377c478bd9Sstevel@tonic-gate * it is not on the command line. 10387c478bd9Sstevel@tonic-gate */ 10397c478bd9Sstevel@tonic-gate if (do_check == TRUE) 10407c478bd9Sstevel@tonic-gate fcb->fcb_flags |= FF_NOTTERM; 10417c478bd9Sstevel@tonic-gate } else if (derive_date(&namep[15], &tme)) { 10427c478bd9Sstevel@tonic-gate (void) strcat(errb, gettext("ending time-stamp invalid - ")); 10437c478bd9Sstevel@tonic-gate (void) strcat(errb, error_str); 10447c478bd9Sstevel@tonic-gate (void) strcpy(errbuf, errb); 10457c478bd9Sstevel@tonic-gate error_str = errbuf; 10467c478bd9Sstevel@tonic-gate free(namep); 10477c478bd9Sstevel@tonic-gate return (ret); 10487c478bd9Sstevel@tonic-gate } else { 10497c478bd9Sstevel@tonic-gate fcb->fcb_end = tm_to_secs(&tme); 10507c478bd9Sstevel@tonic-gate } 10517c478bd9Sstevel@tonic-gate fcb->fcb_name = slp; 10527c478bd9Sstevel@tonic-gate fcb->fcb_suffix = &slp[30]; 10537c478bd9Sstevel@tonic-gate free(namep); 10547c478bd9Sstevel@tonic-gate return (0); 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate 10587c478bd9Sstevel@tonic-gate /* 10597c478bd9Sstevel@tonic-gate * .func get_next_pcb - get a pcb to use. 10607c478bd9Sstevel@tonic-gate * .desc The pcb's in the array audit_pcbs are used to hold single file 10617c478bd9Sstevel@tonic-gate * groups in the form of a linked list. Each pcb holds files that 10627c478bd9Sstevel@tonic-gate * are tied together by a common suffix in the file name. Here we 10637c478bd9Sstevel@tonic-gate * get either 1. the existing pcb holding a specified sufix or 10647c478bd9Sstevel@tonic-gate * 2. a new pcb if we can't find an existing one. 10657c478bd9Sstevel@tonic-gate * .call pcb = get_next_pcb(suffix). 10667c478bd9Sstevel@tonic-gate * .arg suffix - ptr to suffix we are seeking. 10677c478bd9Sstevel@tonic-gate * .ret pcb - ptr to pcb that hold s the sought suffix. 10687c478bd9Sstevel@tonic-gate * .ret NULL- serious failure in memory allocation. Quit processing. 10697c478bd9Sstevel@tonic-gate */ 10707c478bd9Sstevel@tonic-gate audit_pcb_t * 10717c478bd9Sstevel@tonic-gate get_next_pcb(char *suffix) 10727c478bd9Sstevel@tonic-gate { 10737c478bd9Sstevel@tonic-gate int i = 0; 10747c478bd9Sstevel@tonic-gate int zerosize; 10757c478bd9Sstevel@tonic-gate unsigned int size; 10767c478bd9Sstevel@tonic-gate audit_pcb_t *pcb; 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate /* Search through (maybe) entire array. */ 10797c478bd9Sstevel@tonic-gate while (i < pcbsize) { 10807c478bd9Sstevel@tonic-gate pcb = &audit_pcbs[i++]; 10817c478bd9Sstevel@tonic-gate if (pcb->pcb_first == NULL) { 10827c478bd9Sstevel@tonic-gate proc_pcb(pcb, suffix, i); 10837c478bd9Sstevel@tonic-gate return (pcb); /* came to an unused one */ 10847c478bd9Sstevel@tonic-gate } 10857c478bd9Sstevel@tonic-gate if (suffix) { 10867c478bd9Sstevel@tonic-gate if (strcmp(pcb->pcb_suffix, suffix) == 0) 10877c478bd9Sstevel@tonic-gate return (pcb); /* matched one with suffix */ 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate /* 10917c478bd9Sstevel@tonic-gate * Uh-oh, the entire array is used and we haven't gotten one yet. 10927c478bd9Sstevel@tonic-gate * Allocate a bigger array. 10937c478bd9Sstevel@tonic-gate */ 10947c478bd9Sstevel@tonic-gate pcbsize += PCB_INC; 10957c478bd9Sstevel@tonic-gate size = pcbsize * sizeof (audit_pcb_t); 10967c478bd9Sstevel@tonic-gate zerosize = size - ((pcbsize - PCB_INC) * sizeof (audit_pcb_t)); 10977c478bd9Sstevel@tonic-gate if ((audit_pcbs = (audit_pcb_t *)realloc((char *)audit_pcbs, size)) == 10987c478bd9Sstevel@tonic-gate NULL) { 10997c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 11007c478bd9Sstevel@tonic-gate gettext("%s memory reallocation failed (%d bytes)"), ar, 11017c478bd9Sstevel@tonic-gate size); 11027c478bd9Sstevel@tonic-gate perror(errbuf); 11037c478bd9Sstevel@tonic-gate audit_stats(); /* give user statistics on usage */ 11047c478bd9Sstevel@tonic-gate return (NULL); /* really bad thing to have happen */ 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate /* 11077c478bd9Sstevel@tonic-gate * Don't know if realloc clears the new memory like calloc would. 11087c478bd9Sstevel@tonic-gate */ 11097c478bd9Sstevel@tonic-gate (void) memset((void *) & audit_pcbs[pcbsize-PCB_INC], 0, 11107c478bd9Sstevel@tonic-gate (size_t)zerosize); 11117c478bd9Sstevel@tonic-gate pcb = &audit_pcbs[pcbsize-PCB_INC]; /* allocate the first new one */ 11127c478bd9Sstevel@tonic-gate proc_pcb(pcb, suffix, pcbsize - PCB_INC); 11137c478bd9Sstevel@tonic-gate return (pcb); 11147c478bd9Sstevel@tonic-gate } 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate /* 11187c478bd9Sstevel@tonic-gate * .func proc_pcb - process pcb. 11197c478bd9Sstevel@tonic-gate * .desc Common pcb processing for above routine. 11207c478bd9Sstevel@tonic-gate * .call proc_pcb(pcb, suffix, i). 11217c478bd9Sstevel@tonic-gate * .arg pcb - ptr to pcb. 11227c478bd9Sstevel@tonic-gate * .arg suffix - prt to suffix tha t ties this group together. 11237c478bd9Sstevel@tonic-gate * .arg i - index into audit_pcbs[ ]. 11247c478bd9Sstevel@tonic-gate * .ret void. 11257c478bd9Sstevel@tonic-gate */ 11267c478bd9Sstevel@tonic-gate void 11277c478bd9Sstevel@tonic-gate proc_pcb(audit_pcb_t *pcb, char *suffix, int i) 11287c478bd9Sstevel@tonic-gate { 11297c478bd9Sstevel@tonic-gate if (suffix) 11307c478bd9Sstevel@tonic-gate pcb->pcb_suffix = suffix; 11317c478bd9Sstevel@tonic-gate pcbnum++; /* one more pcb in use */ 11327c478bd9Sstevel@tonic-gate pcb->pcb_size = AUDITBUFSIZE; 11337c478bd9Sstevel@tonic-gate pcb->pcb_rec = (char *)a_calloc(1, AUDITBUFSIZE); 11347c478bd9Sstevel@tonic-gate pcb->pcb_time = -1; 1135406d6273SPalle Lyckegaard pcb->pcb_flags |= PF_USEFILE; /* note this one controls files */ 11367c478bd9Sstevel@tonic-gate pcb->pcb_procno = i; /* save index into audit_pcbs [] for id */ 11377c478bd9Sstevel@tonic-gate } 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate 11407c478bd9Sstevel@tonic-gate /* 1141a13cf099Sgww * .func proc_label - process label range argument. 1142a13cf099Sgww * .desc Parse label range lower-bound[;upper-bound] 1143a13cf099Sgww * .call ret = proc_label(optstr). 11447c478bd9Sstevel@tonic-gate * .arg opstr - ptr to label range string 11457c478bd9Sstevel@tonic-gate * .ret 0 - no errors detected. 1146a13cf099Sgww * .ret -1 - errors detected (error_str set). 11477c478bd9Sstevel@tonic-gate */ 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate int 1150a13cf099Sgww proc_label(char *optstr) 11517c478bd9Sstevel@tonic-gate { 11527c478bd9Sstevel@tonic-gate char *p; 11537c478bd9Sstevel@tonic-gate int error; 11547c478bd9Sstevel@tonic-gate 1155924c9144Sgww if (flags & M_LABEL) { 1156924c9144Sgww error_str = gettext("'l' option specified multiple times"); 11577c478bd9Sstevel@tonic-gate return (-1); 11587c478bd9Sstevel@tonic-gate } 1159924c9144Sgww flags |= M_LABEL; 116045916cd2Sjpk 116145916cd2Sjpk if ((m_label = malloc(sizeof (m_range_t))) == NULL) { 116245916cd2Sjpk return (-1); 116345916cd2Sjpk } 116445916cd2Sjpk m_label->lower_bound = NULL; 116545916cd2Sjpk m_label->upper_bound = NULL; 116645916cd2Sjpk 116745916cd2Sjpk p = strchr(optstr, ';'); 11687c478bd9Sstevel@tonic-gate if (p == NULL) { 11697c478bd9Sstevel@tonic-gate /* exact label match, lower and upper range bounds the same */ 117045916cd2Sjpk if (str_to_label(optstr, &m_label->lower_bound, MAC_LABEL, 117145916cd2Sjpk L_NO_CORRECTION, &error) == -1) { 11727c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 11737c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), 11747c478bd9Sstevel@tonic-gate optstr, error); 11757c478bd9Sstevel@tonic-gate error_str = errbuf; 117645916cd2Sjpk goto errout; 11777c478bd9Sstevel@tonic-gate } 117845916cd2Sjpk m_label->upper_bound = m_label->lower_bound; 11797c478bd9Sstevel@tonic-gate return (0); 11807c478bd9Sstevel@tonic-gate } 11817c478bd9Sstevel@tonic-gate if (p == optstr) { 11827c478bd9Sstevel@tonic-gate /* lower bound is not specified .. default is admin_low */ 118345916cd2Sjpk if (str_to_label(ADMIN_LOW, &m_label->lower_bound, MAC_LABEL, 118445916cd2Sjpk L_NO_CORRECTION, &error) == -1) { 1185a13cf099Sgww goto errout; 11867c478bd9Sstevel@tonic-gate } 118745916cd2Sjpk 118845916cd2Sjpk p++; 118945916cd2Sjpk if (*p == '\0') { 119045916cd2Sjpk /* upper bound not specified .. default is admin_high */ 119145916cd2Sjpk if (str_to_label(ADMIN_HIGH, &m_label->upper_bound, 119245916cd2Sjpk MAC_LABEL, L_NO_CORRECTION, &error) == -1) { 1193a13cf099Sgww goto errout; 119445916cd2Sjpk } 119545916cd2Sjpk } else { 119645916cd2Sjpk if (str_to_label(p, &m_label->upper_bound, MAC_LABEL, 119745916cd2Sjpk L_NO_CORRECTION, &error) == -1) { 119845916cd2Sjpk (void) sprintf(errbuf, gettext( 119945916cd2Sjpk "invalid sensitivity label (%s) err %d"), 120045916cd2Sjpk p, error); 120145916cd2Sjpk error_str = errbuf; 120245916cd2Sjpk goto errout; 120345916cd2Sjpk } 120445916cd2Sjpk } 12057c478bd9Sstevel@tonic-gate return (0); 12067c478bd9Sstevel@tonic-gate } 12077c478bd9Sstevel@tonic-gate *p++ = '\0'; 120845916cd2Sjpk if (str_to_label(optstr, &m_label->lower_bound, MAC_LABEL, 120945916cd2Sjpk L_NO_CORRECTION, &error) == -1) { 12107c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 12117c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), optstr, 12127c478bd9Sstevel@tonic-gate error); 12137c478bd9Sstevel@tonic-gate error_str = errbuf; 121445916cd2Sjpk goto errout; 12157c478bd9Sstevel@tonic-gate } 121645916cd2Sjpk if (*p == '\0') { 12177c478bd9Sstevel@tonic-gate /* upper bound is not specified .. default is admin_high */ 121845916cd2Sjpk if (str_to_label(ADMIN_HIGH, &m_label->upper_bound, 121945916cd2Sjpk MAC_LABEL, L_NO_CORRECTION, &error) == -1) { 1220a13cf099Sgww goto errout; 122145916cd2Sjpk } 122245916cd2Sjpk } else { 122345916cd2Sjpk if (str_to_label(p, &m_label->upper_bound, MAC_LABEL, 122445916cd2Sjpk L_NO_CORRECTION, &error) == -1) { 12257c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 12267c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label (%s) err %d"), 12277c478bd9Sstevel@tonic-gate p, error); 12287c478bd9Sstevel@tonic-gate error_str = errbuf; 122945916cd2Sjpk goto errout; 12307c478bd9Sstevel@tonic-gate } 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate /* make sure that upper bound dominates the lower bound */ 123345916cd2Sjpk if (!bldominates(m_label->upper_bound, m_label->lower_bound)) { 123445916cd2Sjpk *--p = ';'; 12357c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 12367c478bd9Sstevel@tonic-gate gettext("invalid sensitivity label range (%s)"), optstr); 12377c478bd9Sstevel@tonic-gate error_str = errbuf; 123845916cd2Sjpk goto errout; 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate return (0); 124145916cd2Sjpk 124245916cd2Sjpk errout: 124345916cd2Sjpk m_label_free(m_label->upper_bound); 124445916cd2Sjpk m_label_free(m_label->lower_bound); 124545916cd2Sjpk free(m_label); 124645916cd2Sjpk 124745916cd2Sjpk return (-1); 12487c478bd9Sstevel@tonic-gate } 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate /* 12517c478bd9Sstevel@tonic-gate * proc_zonename - pick up zone name. 12527c478bd9Sstevel@tonic-gate * 12537c478bd9Sstevel@tonic-gate * all non-empty and not-too-long strings are valid since any name 12547c478bd9Sstevel@tonic-gate * may be valid. 12557c478bd9Sstevel@tonic-gate * 12567c478bd9Sstevel@tonic-gate * ret 0: non-empty string 12577c478bd9Sstevel@tonic-gate * ret -1: empty string or string is too long. 12587c478bd9Sstevel@tonic-gate */ 12597c478bd9Sstevel@tonic-gate static int 12607c478bd9Sstevel@tonic-gate proc_zonename(char *optstr) 12617c478bd9Sstevel@tonic-gate { 12627c478bd9Sstevel@tonic-gate size_t length = strlen(optstr); 12637c478bd9Sstevel@tonic-gate if ((length < 1) || (length > ZONENAME_MAX)) { 12647c478bd9Sstevel@tonic-gate (void) sprintf(errbuf, 12657c478bd9Sstevel@tonic-gate gettext("invalid zone name: %s"), optstr); 12667c478bd9Sstevel@tonic-gate error_str = errbuf; 12677c478bd9Sstevel@tonic-gate return (-1); 12687c478bd9Sstevel@tonic-gate } 12697c478bd9Sstevel@tonic-gate zonename = strdup(optstr); 12707c478bd9Sstevel@tonic-gate flags |= M_ZONENAME; 12717c478bd9Sstevel@tonic-gate return (0); 12727c478bd9Sstevel@tonic-gate } 1273103b2b15Sgww 1274103b2b15Sgww /* 1275103b2b15Sgww * proc_frmi - set up frmi for pattern matching. 1276103b2b15Sgww * Logic ripped off of scf_walk_fmri() 1277103b2b15Sgww * Thanks to the smf team. 1278103b2b15Sgww * 1279103b2b15Sgww * ret 0: OK 1280103b2b15Sgww * ret -1: error 1281103b2b15Sgww */ 1282103b2b15Sgww static int 1283103b2b15Sgww proc_fmri(char *optstr) 1284103b2b15Sgww { 1285103b2b15Sgww if (strpbrk(optstr, "*?[") != NULL) { 1286103b2b15Sgww /* have a pattern to glob for */ 1287103b2b15Sgww 1288103b2b15Sgww fmri.sp_type = PATTERN_GLOB; 1289103b2b15Sgww if (optstr[0] == '*' || 1290103b2b15Sgww (strlen(optstr) >= 4 && optstr[3] == ':')) { 1291103b2b15Sgww fmri.sp_arg = strdup(optstr); 1292103b2b15Sgww } else if ((fmri.sp_arg = malloc(strlen(optstr) + 6)) != NULL) { 1293103b2b15Sgww (void) snprintf(fmri.sp_arg, strlen(optstr) + 6, 1294103b2b15Sgww "svc:/%s", optstr); 1295103b2b15Sgww } 1296103b2b15Sgww } else { 1297103b2b15Sgww fmri.sp_type = PATTERN_PARTIAL; 1298103b2b15Sgww fmri.sp_arg = strdup(optstr); 1299103b2b15Sgww } 1300103b2b15Sgww if (fmri.sp_arg == NULL) 1301103b2b15Sgww return (-1); 1302103b2b15Sgww 1303103b2b15Sgww return (0); 1304103b2b15Sgww } 1305