Imported Upstream version 2.4.3
[platform/upstream/audit.git] / src / aureport-options.c
1 /* aureport-options.c - parse commandline options and configure aureport
2  * Copyright 2005-08,2010-11,2014 Red Hat Inc., Durham, North Carolina.
3  * Copyright (c) 2011 IBM Corp.
4  * All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Authors:
21  *     Steve Grubb <sgrubb@redhat.com>
22  *     Marcelo Henrique Cerri <mhcerri@br.ibm.com>
23  */
24
25 #include "config.h"
26 #include <string.h>
27 #include <ctype.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <pwd.h>
32 #include <grp.h>
33 #include <time.h>
34 #include "aureport-options.h"
35 #include "ausearch-time.h"
36 #include "libaudit.h"
37
38
39 /* Global vars that will be accessed by the main program */
40 char *user_file = NULL;
41 int force_logs = 0;
42 int no_config = 0;
43
44 /* These are for compatibility with parser */
45 unsigned int event_id = -1;
46 uid_t event_uid = -1, event_loginuid = -2, event_euid = -1;
47 gid_t event_gid = -1, event_egid = -1;
48 slist *event_node_list = NULL;
49 const char *event_key = NULL;
50 const char *event_filename = NULL;
51 const char *event_exe = NULL;
52 const char *event_comm = NULL;
53 const char *event_hostname = NULL;
54 const char *event_terminal = NULL;
55 const char *event_subject = NULL;
56 const char *event_object = NULL;
57 const char *event_uuid = NULL;
58 const char *event_vmname = NULL;
59 long long event_exit = 0;
60 int event_exit_is_set = 0;
61 int event_ppid = -1, event_session_id = -2;
62 int event_debug = 0, event_machine = -1;
63
64 /* These are used by aureport */
65 const char *dummy = "dummy";
66 report_type_t report_type = RPT_UNSET;
67 report_det_t report_detail = D_UNSET;
68 report_t report_format = RPT_DEFAULT;
69 failed_t event_failed = F_BOTH;
70 conf_act_t event_conf_act = C_NEITHER;
71 success_t event_success = S_SUCCESS;
72 int event_pid = 0;
73
74 struct nv_pair {
75     int        value;
76     const char *name;
77 };
78
79 enum {  R_INFILE, R_TIME_END, R_TIME_START, R_VERSION, R_SUMMARY, R_LOG_TIMES,
80         R_CONFIGS, R_LOGINS, R_USERS, R_TERMINALS, R_HOSTS, R_EXES, R_FILES,
81         R_AVCS, R_SYSCALLS, R_PIDS, R_EVENTS, R_ACCT_MODS,  
82         R_INTERPRET, R_HELP, R_ANOMALY, R_RESPONSE, R_SUMMARY_DET, R_CRYPTO,
83         R_MAC, R_FAILED, R_SUCCESS, R_ADD, R_DEL, R_AUTH, R_NODE, R_IN_LOGS,
84         R_KEYS, R_TTY, R_NO_CONFIG, R_COMM, R_VIRT, R_INTEG };
85
86 static struct nv_pair optiontab[] = {
87         { R_AUTH, "-au" },
88         { R_AUTH, "--auth" },
89         { R_AVCS, "-a" },
90         { R_AVCS, "--avc" },
91         { R_ADD, "--add" },
92         { R_CONFIGS, "-c" },
93         { R_COMM, "--comm" },
94         { R_CONFIGS, "--config" },
95         { R_CRYPTO, "-cr" },
96         { R_CRYPTO, "--crypto" },
97         { R_DEL, "--delete" },
98         { R_EVENTS, "-e" },
99         { R_EVENTS, "--event" },
100         { R_FILES, "-f" },
101         { R_FILES, "--file" },
102         { R_FAILED, "--failed" },
103         { R_HOSTS, "-h" },
104         { R_HOSTS, "--host" },
105         { R_HELP, "--help" },
106         { R_INTERPRET, "-i" },
107         { R_INTERPRET, "--interpret" },
108         { R_INFILE, "-if" },
109         { R_INFILE, "--input" },
110         { R_IN_LOGS, "--input-logs" },
111         { R_INTEG, "--integrity" },
112         { R_KEYS, "-k" },
113         { R_KEYS, "--key" },
114         { R_LOGINS, "-l" },
115         { R_LOGINS, "--login" },
116         { R_ACCT_MODS, "-m" },
117         { R_ACCT_MODS, "--mods" },
118         { R_MAC, "-ma" },
119         { R_MAC, "--mac" },
120         { R_NODE, "--node" },
121         { R_NO_CONFIG, "-nc" },
122         { R_NO_CONFIG, "--no-config" },
123         { R_ANOMALY, "-n" },
124         { R_ANOMALY, "--anomaly" },
125         { R_PIDS, "-p" },
126         { R_PIDS, "--pid" },
127         { R_RESPONSE, "-r" },
128         { R_RESPONSE, "--response" },
129         { R_SYSCALLS, "-s" },
130         { R_SYSCALLS, "--syscall" },
131         { R_SUCCESS, "--success" },
132         { R_SUMMARY_DET, "--summary" },
133         { R_LOG_TIMES, "-t" },
134         { R_LOG_TIMES, "--log" },
135         { R_TIME_END, "-te"},
136         { R_TIME_END, "--end"},
137         { R_TERMINALS, "-tm"}, // don't like this
138         { R_TERMINALS, "--terminal"}, // don't like this
139         { R_TIME_START, "-ts" },
140         { R_TTY, "--tty" },
141         { R_TIME_START, "--start" },
142         { R_USERS, "-u" },
143         { R_USERS, "--user" },
144         { R_VERSION, "-v" },
145         { R_VERSION, "--version" },
146         { R_EXES, "-x" },
147         { R_EXES, "--executable" },
148         { R_VIRT, "--virt" }
149 };
150 #define OPTION_NAMES (sizeof(optiontab)/sizeof(optiontab[0]))
151
152
153 static int audit_lookup_option(const char *name)
154 {
155         int i;
156
157         for (i = 0; i < OPTION_NAMES; i++)
158                 if (!strcmp(optiontab[i].name, name))
159                         return optiontab[i].value;
160         return -1;
161 }
162
163 static void usage(void)
164 {
165         printf("usage: aureport [options]\n"
166         "\t-a,--avc\t\t\tAvc report\n"
167         "\t-au,--auth\t\t\tAuthentication report\n"
168         "\t--comm\t\t\t\tCommands run report\n"
169         "\t-c,--config\t\t\tConfig change report\n"
170         "\t-cr,--crypto\t\t\tCrypto report\n"
171         "\t-e,--event\t\t\tEvent report\n"
172         "\t-f,--file\t\t\tFile name report\n"
173         "\t--failed\t\t\tonly failed events in report\n"
174         "\t-h,--host\t\t\tRemote Host name report\n"
175         "\t--help\t\t\t\thelp\n"
176         "\t-i,--interpret\t\t\tInterpretive mode\n"
177         "\t-if,--input <Input File name>\tuse this file as input\n"
178         "\t--input-logs\t\t\tUse the logs even if stdin is a pipe\n"
179         "\t--integrity\t\t\tIntegrity event report\n"
180         "\t-l,--login\t\t\tLogin report\n"
181         "\t-k,--key\t\t\tKey report\n"
182         "\t-m,--mods\t\t\tModification to accounts report\n"
183         "\t-ma,--mac\t\t\tMandatory Access Control (MAC) report\n"
184         "\t-n,--anomaly\t\t\taNomaly report\n"
185         "\t-nc,--no-config\t\t\tDon't include config events\n"
186         "\t--node <node name>\t\tOnly events from a specific node\n"
187         "\t-p,--pid\t\t\tPid report\n"
188         "\t-r,--response\t\t\tResponse to anomaly report\n"
189         "\t-s,--syscall\t\t\tSyscall report\n"
190         "\t--success\t\t\tonly success events in report\n"
191         "\t--summary\t\t\tsorted totals for main object in report\n"
192         "\t-t,--log\t\t\tLog time range report\n"
193         "\t-te,--end [end date] [end time]\tending date & time for reports\n"
194         "\t-tm,--terminal\t\t\tTerMinal name report\n"
195         "\t-ts,--start [start date] [start time]\tstarting data & time for reports\n"
196         "\t--tty\t\t\t\tReport about tty keystrokes\n"
197         "\t-u,--user\t\t\tUser name report\n"
198         "\t-v,--version\t\t\tVersion\n"
199         "\t--virt\t\t\t\tVirtualization report\n"
200         "\t-x,--executable\t\t\teXecutable name report\n"
201         "\tIf no report is given, the summary report will be displayed\n"
202         );
203 }
204
205 static int set_report(report_type_t r)
206 {
207         if (report_type == RPT_UNSET) {
208                 report_type = r;
209                 return 0;
210         } else {
211                 fprintf(stderr, "Error - only one report can be specified");
212                 return 1;
213         }
214 }
215
216 static int set_detail(report_det_t d)
217 {
218         if (report_detail == D_UNSET) {
219                 report_detail = d;
220                 return 0;
221         } else if (d == D_SUM) {
222                 report_detail = d;
223                 return 0;
224         } else {
225                 return 1;
226         }
227 }
228
229 /*
230  * This function examines the commandline parameters and sets various
231  * search options. It returns a 0 on success and < 0 on failure
232  */
233 int check_params(int count, char *vars[])
234 {
235         int c = 1;
236         int retval = 0;
237         const char *optarg;
238
239         while (c < count && retval == 0) {
240                 // Go ahead and point to the next argument
241                 if (c+1 < count) {
242                         if (vars[c+1][0] != '-')
243                                 optarg = vars[c+1];
244                         else
245                                 optarg = NULL;
246                 } else
247                         optarg = NULL;
248
249                 switch (audit_lookup_option(vars[c])) {
250                 case R_INFILE:
251                         if (!optarg) {
252                                 fprintf(stderr, 
253                                         "Argument is required for %s\n",
254                                         vars[c]);
255                                 retval = -1;
256                         } else {
257                                 user_file = strdup(optarg);
258                                 if (user_file == NULL)
259                                         retval = -1;
260                                 c++;
261                         }
262                         break;
263                 case R_LOG_TIMES:
264                         if (set_report(RPT_TIME))
265                                 retval = -1;
266                         else
267                                 set_detail(D_DETAILED);
268                         break;
269                 case R_AVCS:
270                         if (set_report(RPT_AVC))
271                                 retval = -1;
272                         else { 
273                                 set_detail(D_DETAILED);
274                                 event_comm = dummy;
275                                 event_subject = dummy;
276                                 event_object = dummy;
277                         }
278                         break;
279                 case R_AUTH:
280                         if (set_report(RPT_AUTH))
281                                 retval = -1;
282                         else {
283                                 set_detail(D_DETAILED);
284                                 event_exe = dummy;
285                                 event_hostname = dummy;
286                                 event_terminal = dummy;
287                                 event_uid = 1;
288                         }
289                         break;
290                 case R_MAC:
291                         if (set_report(RPT_MAC))
292                                 retval = -1;
293                         else { 
294                                 set_detail(D_DETAILED);
295                                 event_loginuid = 1;
296                         }
297                         break;
298                 case R_INTEG:
299                         if (set_report(RPT_INTEG))
300                                 retval = -1;
301                         else { 
302                                 set_detail(D_DETAILED);
303                                 event_loginuid = 1;
304                         }
305                         break;
306                 case R_VIRT:
307                         if (set_report(RPT_VIRT))
308                                 retval = -1;
309                         else { 
310                                 set_detail(D_DETAILED);
311                         }
312                         break;
313                 case R_CONFIGS:
314                         if (set_report(RPT_CONFIG))
315                                 retval = -1;
316                         else { 
317                                 set_detail(D_DETAILED);
318                                 event_loginuid = 1;
319                         }
320                         break;
321                 case R_CRYPTO:
322                         if (set_report(RPT_CRYPTO))
323                                 retval = -1;
324                         else { 
325                                 set_detail(D_DETAILED);
326                                 event_loginuid = 1;
327                         }
328                         break;
329                 case R_LOGINS:
330                         if (set_report(RPT_LOGIN))
331                                 retval = -1;
332                         else {
333                                 set_detail(D_DETAILED);
334                                 event_exe = dummy;
335                                 event_hostname = dummy;
336                                 event_terminal = dummy;
337                                 event_loginuid = 1;
338                         }
339                         break;
340                 case R_ACCT_MODS:
341                         if (set_report(RPT_ACCT_MOD))
342                                 retval = -1;
343                         else { 
344                                 set_detail(D_DETAILED);
345                                 event_exe = dummy;
346                                 event_hostname = dummy;
347                                 event_terminal = dummy;
348                                 event_loginuid = 1;
349                         }
350                         break;
351                 case R_EVENTS:
352                         if (set_report(RPT_EVENT))
353                                 retval = -1;
354                         else {
355 //                              if (!optarg) {
356                                         set_detail(D_DETAILED);
357                                         event_loginuid = 1;
358 //                              } else {
359 //                                      UNIMPLEMENTED;
360 //                                      set_detail(D_SPECIFIC);
361 //                                      if (isdigit(optarg[0])) {
362 //                                              errno = 0;
363 //                                              event_id = strtoul(optarg,
364 //                                                      NULL, 10);
365 //                                              if (errno) {
366 //                                                      fprintf(stderr,
367 //                                      "Illegal value for audit event ID");
368 //                                                      retval = -1;
369 //                                              }
370 //                                              c++;
371 //                                      } else {
372 //                                              fprintf(stderr,
373 //                      "Audit event id must be a numeric value, was %s\n",
374 //                                              optarg);
375 //                                              retval = -1;
376 //                                      }
377 //                              }
378                         }
379                         break;
380                 case R_FILES:
381                         if (set_report(RPT_FILE))
382                                 retval = -1;
383                         else {
384                                 if (!optarg) {
385                                         set_detail(D_DETAILED);
386                                         event_filename = dummy;
387                                         event_exe = dummy;
388                                         event_loginuid = 1;
389                                 } else {
390                                         UNIMPLEMENTED;
391                                 }
392                         }
393                         break;
394                 case R_HOSTS:
395                         if (set_report(RPT_HOST))
396                                 retval = -1;
397                         else {
398                                 if (!optarg) {
399                                         set_detail(D_DETAILED);
400                                         event_hostname = dummy;
401                                         event_loginuid = 1;
402                                 } else {
403                                         UNIMPLEMENTED;
404                                 }
405                         }
406                         break;
407                 case R_INTERPRET:
408                         report_format = RPT_INTERP;
409                         if (optarg) {
410                                 fprintf(stderr,
411                                         "Argument is NOT required for %s\n",
412                                         vars[c]);
413                                 retval = -1;
414                         }
415                         break;
416                 case R_PIDS:
417                         if (set_report(RPT_PID))
418                                 retval = -1;
419                         else {
420                                 if (!optarg) {
421                                         set_detail(D_DETAILED);
422                                         event_exe = dummy;
423                                         event_loginuid = 1;
424                                 } else {
425                                         UNIMPLEMENTED;
426                                 }
427                         }
428                         break;
429                 case R_SYSCALLS:
430                         if (set_report(RPT_SYSCALL))
431                                 retval = -1;
432                         else {
433                                 if (!optarg) {
434                                         set_detail(D_DETAILED);
435                                         event_comm = dummy;
436                                         event_loginuid = 1;
437                                 } else {
438                                         UNIMPLEMENTED;
439                                 }
440                         }
441                         break;
442                 case R_TERMINALS:
443                         if (set_report(RPT_TERM))
444                                 retval = -1;
445                         else {
446                                 if (!optarg) {
447                                         set_detail(D_DETAILED);
448                                         event_terminal = dummy;
449                                         event_hostname = dummy;
450                                         event_exe = dummy;
451                                         event_loginuid = 1;
452                                 } else {
453                                         UNIMPLEMENTED;
454                                 }
455                         }
456                         break;
457                 case R_USERS:
458                         if (set_report(RPT_USER))
459                                 retval = -1;
460                         else {
461                                 if (!optarg) {
462                                         set_detail(D_DETAILED);
463                                         event_terminal = dummy;
464                                         event_hostname = dummy;
465                                         event_exe = dummy;
466                                         event_uid = 1;
467                                         event_loginuid = 1;
468                                 } else {
469                                         UNIMPLEMENTED;
470                                 }
471                         }
472                         break;
473                 case R_EXES:
474                         if (set_report(RPT_EXE))
475                                 retval = -1;
476                         else {
477                                 if (!optarg) {
478                                         set_detail(D_DETAILED);
479                                         event_terminal = dummy;
480                                         event_hostname = dummy;
481                                         event_exe = dummy;
482                                         event_loginuid = 1;
483                                 } else {
484                                         UNIMPLEMENTED;
485                                 }
486                         }
487                         break;
488                 case R_COMM:
489                         if (set_report(RPT_COMM))
490                                 retval = -1;
491                         else {
492                                 if (!optarg) {
493                                         set_detail(D_DETAILED);
494                                         event_terminal = dummy;
495                                         event_hostname = dummy;
496                                         event_comm = dummy;
497                                         event_loginuid = 1;
498                                 } else {
499                                         UNIMPLEMENTED;
500                                 }
501                         }
502                         break;
503                 case R_ANOMALY:
504                         if (set_report(RPT_ANOMALY))
505                                 retval = -1;
506                         else {
507                                 if (!optarg) {
508                                         set_detail(D_DETAILED);
509                                         event_terminal = dummy;
510                                         event_hostname = dummy;
511                                         event_exe = dummy;
512                                         event_comm = dummy;
513                                         event_loginuid = 1;
514                                 } else {
515                                         UNIMPLEMENTED;
516                                 }
517                         }
518                         break;
519                 case R_RESPONSE:
520                         if (set_report(RPT_RESPONSE))
521                                 retval = -1;
522                         else {
523                                 if (!optarg) {
524                                         set_detail(D_DETAILED);
525                                 } else {
526                                         UNIMPLEMENTED;
527                                 }
528                         }
529                         break;
530                 case R_KEYS:
531                         if (set_report(RPT_KEY))
532                                 retval = -1;
533                         else {
534                                 if (!optarg) {
535                                         set_detail(D_DETAILED);
536                                         event_exe = dummy;
537                                         event_key = dummy;
538                                         event_loginuid = 1;
539                                 } else {
540                                         UNIMPLEMENTED;
541                                 }
542                         }
543                         break;
544                 case R_TTY:
545                         if (set_report(RPT_TTY))
546                                 retval = -1;
547                         else {
548                                 set_detail(D_DETAILED);
549                                 event_session_id = 1;
550                                 event_loginuid = 1;
551                                 event_terminal = dummy;
552                                 event_comm = dummy;
553                         }
554                         break;
555                 case R_TIME_END:
556                         if (optarg) {
557                                 if ( (c+2 < count) && vars[c+2] && 
558                                         (vars[c+2][0] != '-') ) {
559                                 /* Have both date and time - check order*/
560                                         if (strchr(optarg, ':')) {
561                                                 if (ausearch_time_end(vars[c+2],
562                                                                  optarg) != 0) 
563                                                         retval = -1;
564                                         } else {
565                                                 if (ausearch_time_end(optarg, 
566                                                                 vars[c+2]) != 0)
567                                                         retval = -1;
568                                         }
569                                         c++;                    
570                                 } else {
571                                         // Check against recognized words
572                                         int t = lookup_time(optarg);
573                                         if (t >= 0) {
574                                                 if (ausearch_time_end(optarg,
575                                                                 NULL) != 0)
576                                                         retval = -1;
577                                         } else if ( (strchr(optarg, ':')) == NULL) {
578                                                 /* Only have date */
579                                                 if (ausearch_time_end(optarg,
580                                                                 NULL) != 0)
581                                                         retval = -1;
582                                         } else {
583                                                 /* Only have time */
584                                                 if (ausearch_time_end(NULL,
585                                                                 optarg) != 0)
586                                                         retval = -1;
587                                         }
588                                 }
589                                 c++;                    
590                                 break;
591                         }
592                         fprintf(stderr,
593                                 "%s requires either date and/or time\n",
594                                 vars[c]);
595                         retval = -1;
596                         break;
597                 case R_TIME_START:
598                         if (optarg) {
599                                 if ( (c+2 < count) && vars[c+2] && 
600                                         (vars[c+2][0] != '-') ) {
601                                 /* Have both date and time - check order */
602                                         if (strchr(optarg, ':')) {
603                                                 if (ausearch_time_start(
604                                                         vars[c+2], optarg) != 0)
605                                                         retval = -1;
606                                         } else {
607                                                 if (ausearch_time_start(optarg, 
608                                                                 vars[c+2]) != 0)
609                                                         retval = -1;
610                                         }
611                                         c++;
612                                 } else {
613                                         // Check against recognized words
614                                         int t = lookup_time(optarg);
615                                         if (t >= 0) {
616                                                 if (ausearch_time_start(optarg,
617                                                         "00:00:00") != 0)
618                                                         retval = -1;
619                                         } else if ( strchr(optarg, ':') == NULL) {
620                                                 /* Only have date */
621                                                 if (ausearch_time_start(optarg,
622                                                         "00:00:00") != 0)
623                                                         retval = -1;
624                                         } else {
625                                                 /* Only have time */
626                                                 if (ausearch_time_start(NULL,
627                                                                 optarg) != 0)
628                                                         retval = -1;
629                                         }
630                                 }
631                                 c++;
632                                 break;
633                         }
634                         fprintf(stderr, 
635                                 "%s requires either date and/or time\n",
636                                 vars[c]);
637                         retval = -1;
638                         break;
639                 case R_NODE:
640                         if (!optarg) {
641                                 fprintf(stderr,
642                                         "Argument is required for %s\n",
643                                         vars[c]);
644                                 retval = -1;
645                         } else {
646                                 snode sn;
647                                 c++;
648
649                                 if (!event_node_list) {
650                                         event_node_list = malloc(sizeof (slist));
651                                         if (!event_node_list) {
652                                                 retval = -1;
653                                                 break;
654                                         }
655                                         slist_create(event_node_list);
656                                 }
657                                 
658                                 sn.str = strdup(optarg);
659                                 sn.key = NULL;
660                                 sn.hits=0;
661                                 slist_append(event_node_list, &sn);
662                         }
663                         break;
664                 case R_SUMMARY_DET:
665                         set_detail(D_SUM);
666                         break;
667                 case R_FAILED:
668                         event_failed = F_FAILED;
669                         break;
670                 case R_SUCCESS:
671                         event_failed = F_SUCCESS;
672                         break;
673                 case R_ADD:
674                         event_conf_act = C_ADD;
675                         break;
676                 case R_DEL:
677                         event_conf_act = C_DEL;
678                         break;
679                 case R_IN_LOGS:
680                         force_logs = 1;
681                         break;
682                 case R_NO_CONFIG:
683                         no_config = 1;
684                         break;
685                 case R_VERSION:
686                         printf("aureport version %s\n", VERSION);
687                         exit(0);
688                         break;
689                 case R_HELP:
690                         usage();
691                         exit(0);
692                         break;
693                 default:
694                         fprintf(stderr, "%s is an unsupported option\n", 
695                                 vars[c]);
696                         retval = -1;
697                         break;
698                 }
699                 c++;
700         }
701
702         if (retval >= 0) {
703                 if (report_type == RPT_UNSET) {
704                         if (set_report(RPT_SUMMARY))
705                                 retval = -1;
706                         else {
707                                 set_detail(D_SUM);
708                                 event_filename = dummy;
709                                 event_hostname = dummy;
710                                 event_terminal = dummy;
711                                 event_exe = dummy;
712                                 event_comm = dummy;
713                                 event_key = dummy;
714                                 event_loginuid = 1;
715                         }
716                 }
717         } else
718                 usage();
719
720         return retval;
721 }
722