Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.


  24  */
  25 
  26 /*
  27  * Command line option processing for auditreduce.
  28  * The entry point is process_options(), which is called by main().
  29  * Process_options() is the only function visible outside this module.
  30  */
  31 
  32 #include <locale.h>
  33 #include <sys/zone.h>     /* for max zonename length */
  34 #include "auditr.h"
  35 
  36 /*
  37  * Object entry.
  38  * Maps object strings specified on the command line to a flag
  39  * used when searching by object type.
  40  */
  41 
  42 struct obj_ent {
  43         char    *obj_str; /* string specified on the command line */


  52 static obj_ent_t obj_tbl[] = {
  53                         { "file", OBJ_PATH },
  54                         { "filegroup", OBJ_FGROUP },
  55                         { "fileowner", OBJ_FOWNER },
  56                         { "fmri", OBJ_FMRI },
  57                         { "lp", OBJ_LP   },
  58                         { "msgqid", OBJ_MSG  },
  59                         { "msgqgroup", OBJ_MSGGROUP },
  60                         { "msgqowner", OBJ_MSGOWNER },
  61                         { "path", OBJ_PATH },
  62                         { "pid", OBJ_PROC },
  63                         { "procgroup", OBJ_PGROUP },
  64                         { "procowner", OBJ_POWNER },
  65                         { "semid", OBJ_SEM  },
  66                         { "semgroup", OBJ_SEMGROUP  },
  67                         { "semowner", OBJ_SEMOWNER  },
  68                         { "shmid", OBJ_SHM  },
  69                         { "shmgroup", OBJ_SHMGROUP  },
  70                         { "shmowner", OBJ_SHMOWNER  },
  71                         { "sock", OBJ_SOCK },
  72                         { "user", OBJ_USER } };

  73 
  74 extern int      derive_date(char *, struct tm *);
  75 extern int      parse_time(char *, int);
  76 extern char     *re_comp2(char *);
  77 extern time_t   tm_to_secs(struct tm *);
  78 
  79 static int      a_isnum(char *, int);
  80 static int      check_file(audit_fcb_t *, int);
  81 static int      gather_dir(char *);
  82 static audit_pcb_t *get_next_pcb(char *);
  83 static obj_ent_t *obj_lkup(char *);
  84 static int      proc_class(char *);
  85 static int      proc_date(char *, int);
  86 static int      proc_file(char *, int);
  87 static int      process_fileopt(int, char *argv[], int);
  88 static int      proc_group(char *, gid_t *);
  89 static int      proc_id(char *, int);
  90 static int      proc_object(char *);
  91 static void     proc_pcb(audit_pcb_t *, char *, int);
  92 static int      proc_label(char *);
  93 static int      proc_subject(char *);
  94 static int      proc_sid(char *);
  95 static int      proc_type(char *);
  96 static int      proc_user(char *, uid_t *);
  97 static int      proc_zonename(char *);
  98 static int      proc_fmri(char *);

  99 
 100 /*
 101  * .func        process_options - process command line options.
 102  * .desc        Process the user's command line options. These are of two types:
 103  *      single letter flags that are denoted by '-', and filenames. Some
 104  *      of the flags have arguments. Getopt() is used to get the flags.
 105  *      When this is done it calls process_fileopt() to handle any filenames
 106  *      that were there.
 107  * .call        ret = process_options(argc, argv).
 108  * .arg argc    - the original value.
 109  * .arg argv    - the original value.
 110  * .ret 0       - no errors detected.
 111  * .ret -1      - command line error detected (message already printed).
 112  */
 113 int
 114 process_options(int argc, char **argv)
 115 {
 116         int     opt;
 117         int     error = FALSE;
 118         int     error_combo = FALSE;
 119         extern int      optind;         /* in getopt() */
 120         extern char     *optarg;        /* in getopt() - holds arg to flag */
 121 
 122         static char     *options = "ACD:M:NQR:S:VO:"
 123             "a:b:c:d:e:g:j:l:m:o:r:s:t:u:z:";
 124 
 125         error_str = gettext("general error");
 126 

 127         zonename = NULL;
 128         /*
 129          * Big switch to process the flags.
 130          * Start_over: is for handling the '-' for standard input. Getopt()
 131          * doesn't recognize it.
 132          */
 133 start_over:
 134         while ((opt = getopt(argc, argv, options)) != EOF) {
 135                 switch (opt) {
 136                 case 'A':               /* all records from the files */
 137                         f_all = TRUE;
 138                         break;
 139                 case 'C':               /* process only completed files */
 140                         f_complete = TRUE;
 141                         break;
 142                 case 'D':               /* delete the files when done */
 143                         /* force 'A' 'C' 'O' to be active */
 144                         f_all = f_complete = TRUE;
 145                         f_outfile = optarg;
 146                         f_delete = TRUE;


 393         case OBJ_SHM:
 394         case OBJ_PROC:
 395                 obj_id = atol(obj_val);
 396                 return (0);
 397         case OBJ_FGROUP:
 398         case OBJ_MSGGROUP:
 399         case OBJ_SEMGROUP:
 400         case OBJ_SHMGROUP:
 401         case OBJ_PGROUP:
 402                 return (proc_group(obj_val, &obj_group));
 403         case OBJ_FOWNER:
 404         case OBJ_MSGOWNER:
 405         case OBJ_SEMOWNER:
 406         case OBJ_SHMOWNER:
 407         case OBJ_POWNER:
 408                 return (proc_user(obj_val, &obj_owner));
 409         case OBJ_FMRI:
 410                 return (proc_fmri(obj_val));
 411         case OBJ_USER:
 412                 return (proc_user(obj_val, &obj_user));


 413         case OBJ_LP: /* lp objects have not yet been defined */
 414         default: /* impossible */
 415                 (void) sprintf(errbuf, gettext("invalid object type (%s)"),
 416                     obj_str);
 417                 error_str = errbuf;
 418                 return (-1);
 419         } /* switch */
 420         /*NOTREACHED*/
 421 }
 422 
 423 
 424 obj_ent_t *
 425 obj_lkup(char *obj_str)
 426 {
 427         int     i;
 428 
 429         for (i = 0; i < sizeof (obj_tbl) / sizeof (obj_ent_t); i++)
 430                 if (strcmp(obj_str, obj_tbl[i].obj_str) == 0)
 431                         return (&obj_tbl[i]);
 432 


1275         if (strpbrk(optstr, "*?[") != NULL) {
1276                 /* have a pattern to glob for */
1277 
1278                 fmri.sp_type = PATTERN_GLOB;
1279                 if (optstr[0] == '*' ||
1280                     (strlen(optstr) >= 4 && optstr[3] == ':')) {
1281                         fmri.sp_arg = strdup(optstr);
1282                 } else if ((fmri.sp_arg = malloc(strlen(optstr) + 6)) != NULL) {
1283                         (void) snprintf(fmri.sp_arg, strlen(optstr) + 6,
1284                             "svc:/%s", optstr);
1285                 }
1286         } else {
1287                 fmri.sp_type = PATTERN_PARTIAL;
1288                 fmri.sp_arg = strdup(optstr);
1289         }
1290         if (fmri.sp_arg == NULL)
1291                 return (-1);
1292 
1293         return (0);
1294 }























   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 /*
  29  * Command line option processing for auditreduce.
  30  * The entry point is process_options(), which is called by main().
  31  * Process_options() is the only function visible outside this module.
  32  */
  33 
  34 #include <locale.h>
  35 #include <sys/zone.h>     /* for max zonename length */
  36 #include "auditr.h"
  37 
  38 /*
  39  * Object entry.
  40  * Maps object strings specified on the command line to a flag
  41  * used when searching by object type.
  42  */
  43 
  44 struct obj_ent {
  45         char    *obj_str; /* string specified on the command line */


  54 static obj_ent_t obj_tbl[] = {
  55                         { "file", OBJ_PATH },
  56                         { "filegroup", OBJ_FGROUP },
  57                         { "fileowner", OBJ_FOWNER },
  58                         { "fmri", OBJ_FMRI },
  59                         { "lp", OBJ_LP   },
  60                         { "msgqid", OBJ_MSG  },
  61                         { "msgqgroup", OBJ_MSGGROUP },
  62                         { "msgqowner", OBJ_MSGOWNER },
  63                         { "path", OBJ_PATH },
  64                         { "pid", OBJ_PROC },
  65                         { "procgroup", OBJ_PGROUP },
  66                         { "procowner", OBJ_POWNER },
  67                         { "semid", OBJ_SEM  },
  68                         { "semgroup", OBJ_SEMGROUP  },
  69                         { "semowner", OBJ_SEMOWNER  },
  70                         { "shmid", OBJ_SHM  },
  71                         { "shmgroup", OBJ_SHMGROUP  },
  72                         { "shmowner", OBJ_SHMOWNER  },
  73                         { "sock", OBJ_SOCK },
  74                         { "user", OBJ_USER },
  75                         { "wsid", OBJ_WSID } };
  76 
  77 extern int      derive_date(char *, struct tm *);
  78 extern int      parse_time(char *, int);
  79 extern char     *re_comp2(char *);
  80 extern time_t   tm_to_secs(struct tm *);
  81 
  82 static int      a_isnum(char *, int);
  83 static int      check_file(audit_fcb_t *, int);
  84 static int      gather_dir(char *);
  85 static audit_pcb_t *get_next_pcb(char *);
  86 static obj_ent_t *obj_lkup(char *);
  87 static int      proc_class(char *);
  88 static int      proc_date(char *, int);
  89 static int      proc_file(char *, int);
  90 static int      process_fileopt(int, char *argv[], int);
  91 static int      proc_group(char *, gid_t *);
  92 static int      proc_id(char *, int);
  93 static int      proc_object(char *);
  94 static void     proc_pcb(audit_pcb_t *, char *, int);
  95 static int      proc_label(char *);
  96 static int      proc_subject(char *);
  97 static int      proc_sid(char *);
  98 static int      proc_type(char *);
  99 static int      proc_user(char *, uid_t *);
 100 static int      proc_zonename(char *);
 101 static int      proc_fmri(char *);
 102 static int      proc_wsid(char *);
 103 
 104 /*
 105  * .func        process_options - process command line options.
 106  * .desc        Process the user's command line options. These are of two types:
 107  *      single letter flags that are denoted by '-', and filenames. Some
 108  *      of the flags have arguments. Getopt() is used to get the flags.
 109  *      When this is done it calls process_fileopt() to handle any filenames
 110  *      that were there.
 111  * .call        ret = process_options(argc, argv).
 112  * .arg argc    - the original value.
 113  * .arg argv    - the original value.
 114  * .ret 0       - no errors detected.
 115  * .ret -1      - command line error detected (message already printed).
 116  */
 117 int
 118 process_options(int argc, char **argv)
 119 {
 120         int     opt;
 121         int     error = FALSE;
 122         int     error_combo = FALSE;
 123         extern int      optind;         /* in getopt() */
 124         extern char     *optarg;        /* in getopt() - holds arg to flag */
 125 
 126         static char     *options = "ACD:M:NQR:S:VO:"
 127             "a:b:c:d:e:g:j:l:m:o:r:s:t:u:z:";
 128 
 129         error_str = gettext("general error");
 130 
 131         wsid = NULL;
 132         zonename = NULL;
 133         /*
 134          * Big switch to process the flags.
 135          * Start_over: is for handling the '-' for standard input. Getopt()
 136          * doesn't recognize it.
 137          */
 138 start_over:
 139         while ((opt = getopt(argc, argv, options)) != EOF) {
 140                 switch (opt) {
 141                 case 'A':               /* all records from the files */
 142                         f_all = TRUE;
 143                         break;
 144                 case 'C':               /* process only completed files */
 145                         f_complete = TRUE;
 146                         break;
 147                 case 'D':               /* delete the files when done */
 148                         /* force 'A' 'C' 'O' to be active */
 149                         f_all = f_complete = TRUE;
 150                         f_outfile = optarg;
 151                         f_delete = TRUE;


 398         case OBJ_SHM:
 399         case OBJ_PROC:
 400                 obj_id = atol(obj_val);
 401                 return (0);
 402         case OBJ_FGROUP:
 403         case OBJ_MSGGROUP:
 404         case OBJ_SEMGROUP:
 405         case OBJ_SHMGROUP:
 406         case OBJ_PGROUP:
 407                 return (proc_group(obj_val, &obj_group));
 408         case OBJ_FOWNER:
 409         case OBJ_MSGOWNER:
 410         case OBJ_SEMOWNER:
 411         case OBJ_SHMOWNER:
 412         case OBJ_POWNER:
 413                 return (proc_user(obj_val, &obj_owner));
 414         case OBJ_FMRI:
 415                 return (proc_fmri(obj_val));
 416         case OBJ_USER:
 417                 return (proc_user(obj_val, &obj_user));
 418         case OBJ_WSID:
 419                 return (proc_wsid(obj_val));
 420         case OBJ_LP: /* lp objects have not yet been defined */
 421         default: /* impossible */
 422                 (void) sprintf(errbuf, gettext("invalid object type (%s)"),
 423                     obj_str);
 424                 error_str = errbuf;
 425                 return (-1);
 426         } /* switch */
 427         /*NOTREACHED*/
 428 }
 429 
 430 
 431 obj_ent_t *
 432 obj_lkup(char *obj_str)
 433 {
 434         int     i;
 435 
 436         for (i = 0; i < sizeof (obj_tbl) / sizeof (obj_ent_t); i++)
 437                 if (strcmp(obj_str, obj_tbl[i].obj_str) == 0)
 438                         return (&obj_tbl[i]);
 439 


1282         if (strpbrk(optstr, "*?[") != NULL) {
1283                 /* have a pattern to glob for */
1284 
1285                 fmri.sp_type = PATTERN_GLOB;
1286                 if (optstr[0] == '*' ||
1287                     (strlen(optstr) >= 4 && optstr[3] == ':')) {
1288                         fmri.sp_arg = strdup(optstr);
1289                 } else if ((fmri.sp_arg = malloc(strlen(optstr) + 6)) != NULL) {
1290                         (void) snprintf(fmri.sp_arg, strlen(optstr) + 6,
1291                             "svc:/%s", optstr);
1292                 }
1293         } else {
1294                 fmri.sp_type = PATTERN_PARTIAL;
1295                 fmri.sp_arg = strdup(optstr);
1296         }
1297         if (fmri.sp_arg == NULL)
1298                 return (-1);
1299 
1300         return (0);
1301 }
1302 
1303 /*
1304  * proc_wsid - pick up Windows SID.
1305  *
1306  * ret 0:       non-empty string
1307  * ret -1:      empty string or string is too long.
1308  */
1309 static int
1310 proc_wsid(char *optstr)
1311 {
1312         size_t  length = strlen(optstr);
1313         if ((length < 1) || (length > 256) ||
1314             strncmp(optstr, "S-1-", 4) != 0) { /* SMB_SID_STRSZ */
1315                 (void) snprintf(errbuf, ERRBUF_SZ,
1316                     gettext("bad Windows SID: %s"), optstr);
1317                 error_str = errbuf;
1318                 return (-1);
1319         }
1320         wsid = strdup(optstr);
1321         return (0);
1322 }