diff --git a/docs/ausearch.8 b/docs/ausearch.8 index 24566a2ce..0155cf3b5 100644 --- a/docs/ausearch.8 +++ b/docs/ausearch.8 @@ -112,6 +112,9 @@ Flush output on every line. Most useful when stdout is connected to a pipe and t .BR \-m ,\ \-\-message \ \fImessage-type\fP\ |\ \fIcomma-sep-message-type-list\fP Search for an event matching the given \fImessage type\fP. (Message types are also known as record types.) You may also enter a \fIcomma separated list of message types\fP or multiple individual message types each with its own \fI-m\fP option. There is an \fBALL\fP message type that doesn't exist in the actual logs. It allows you to get all messages in the system. The list of valid messages types is long. The program will display the list whenever no message type is passed with this parameter. The message type can be either text or numeric. If you enter a list, there can be only commas and no spaces separating the list. .TP +.BR \-M ,\ \-\-message-exclude \ \fImessage-type\fP\ |\ \fIcomma-sep-message-type-list\fP +Filter out events matching the given \fImessage type\fP. (Message types are also known as record types.) You may also enter a \fIcomma separated list of message types\fP or multiple individual message types each with its own \fI-m\fP option. There is an \fBALL\fP message type that doesn't exist in the actual logs. It allows you to exclude all messages in the system. The list of valid messages types is long. The program will display the list whenever no message type is passed with this parameter. The message type can be either text or numeric. If you enter a list, there can be only commas and no spaces separating the list. This option is mutual exclusive with the option \fB\-m\fP. +.TP .BR \-n ,\ \-\-node Search for events originating from a specific machine. Multiple nodes are allowed, and if any nodes match, the event is matched. This search uses the node field in audit events. Also see the \-\-host command which search for events related to host information in the audit trail. .TP diff --git a/src/ausearch-match.c b/src/ausearch-match.c index ac7603dcd..6e7fd9e33 100644 --- a/src/ausearch-match.c +++ b/src/ausearch-match.c @@ -144,7 +144,7 @@ int match(llist *l) if (found) break; } while ((n = list_next(l))); - if (!found) + if (!(found ^ event_type_inverted)) return 0; } diff --git a/src/ausearch-options.c b/src/ausearch-options.c index 1c653648f..72f347d6f 100644 --- a/src/ausearch-options.c +++ b/src/ausearch-options.c @@ -50,6 +50,7 @@ report_t report_format = RPT_DEFAULT; unsigned int event_id = -1; gid_t event_gid = -1, event_egid = -1; ilist *event_type = NULL; +int event_type_inverted = -1; pid_t event_pid = -1, event_ppid = -1; success_t event_success = S_UNSET; auparse_esc_t escape_mode = AUPARSE_ESC_TTY; @@ -93,7 +94,8 @@ S_TIME_END, S_TIME_START, S_TERMINAL, S_ALL_UID, S_EFF_UID, S_UID, S_LOGINID, S_VERSION, S_EXACT_MATCH, S_EXECUTABLE, S_CONTEXT, S_SUBJECT, S_OBJECT, S_PPID, S_KEY, S_RAW, S_NODE, S_IN_LOGS, S_JUST_ONE, S_SESSION, S_EXIT, S_LINEBUFFERED, S_UUID, S_VMNAME, S_DEBUG, S_CHECKPOINT, S_ARCH, S_FORMAT, -S_EXTRA_TIME, S_EXTRA_LABELS, S_EXTRA_KEYS, S_EXTRA_OBJ2, S_ESCAPE, S_EOE_TMO }; +S_EXTRA_TIME, S_EXTRA_LABELS, S_EXTRA_KEYS, S_EXTRA_OBJ2, S_ESCAPE, S_EOE_TMO, +S_MESSAGE_TYPE_EXCLUDE }; static const struct nv_pair optiontab[] = { { S_EVENT, "-a" }, @@ -136,6 +138,8 @@ static const struct nv_pair optiontab[] = { { S_LINEBUFFERED, "--line-buffered" }, { S_MESSAGE_TYPE, "-m" }, { S_MESSAGE_TYPE, "--message" }, + { S_MESSAGE_TYPE_EXCLUDE, "-M" }, + { S_MESSAGE_TYPE_EXCLUDE, "--message-exclude" }, { S_NODE, "-n" }, { S_NODE, "--node" }, { S_OBJECT, "-o" }, @@ -222,6 +226,7 @@ static void usage(void) "\t-k,--key \t\tsearch based on key field\n" "\t-l, --line-buffered\t\tFlush output on every line\n" "\t-m,--message \tsearch based on message type\n" + "\t-M,--message-exclude \texclude based on message type\n" "\t-n,--node \t\tsearch based on machine's name\n" "\t-o,--object search based on context of object\n" "\t-p,--pid \t\tsearch based on process id\n" @@ -317,6 +322,8 @@ int check_params(int count, char *vars[]) return -1; } while (c < count && retval == 0) { + int option; + // Go ahead and point to the next argument if (c+1 < count) { if (vars[c+1][0] != '-') @@ -326,7 +333,8 @@ int check_params(int count, char *vars[]) } else optarg = NULL; - switch (audit_lookup_option(vars[c])) { + option = audit_lookup_option(vars[c]); + switch (option) { case S_EVENT: if (!optarg) { fprintf(stderr, @@ -607,12 +615,19 @@ int check_params(int count, char *vars[]) } break; case S_MESSAGE_TYPE: + case S_MESSAGE_TYPE_EXCLUDE: if (!optarg) { fprintf(stderr, "Argument is required for %s\n", vars[c]); retval = -1; + } else if ((option == S_MESSAGE_TYPE && event_type_inverted == 1) || + option == S_MESSAGE_TYPE_EXCLUDE && event_type_inverted == 0) { + fprintf(stderr, + "Option -m is mutual exclusive with option -M\n"); + retval = -1; } else { + event_type_inverted = (option == S_MESSAGE_TYPE_EXCLUDE); if (strcasecmp(optarg, "ALL") != 0) { retval = parse_msg(optarg); } diff --git a/src/ausearch-options.h b/src/ausearch-options.h index 1372762b4..07fc47f3d 100644 --- a/src/ausearch-options.h +++ b/src/ausearch-options.h @@ -41,6 +41,7 @@ extern int event_debug; extern pid_t event_ppid; extern uint32_t event_session_id; extern ilist *event_type; +extern int event_type_inverted; /* Data type to govern output format */ extern report_t report_format;