diff options
Diffstat (limited to 'framework/src/audit/tools')
19 files changed, 0 insertions, 3541 deletions
diff --git a/framework/src/audit/tools/Makefile.am b/framework/src/audit/tools/Makefile.am deleted file mode 100644 index 15ba254f..00000000 --- a/framework/src/audit/tools/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# Makefile.am -- -# Copyright 2008 Red Hat Inc., Durham, North Carolina. -# All Rights Reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Authors: -# Steve Grubb <sgrubb@redhat.com> -# - -CONFIG_CLEAN_FILES = *.loT *.rej *.orig - -SUBDIRS = aulast aulastlog ausyscall auvirt - diff --git a/framework/src/audit/tools/aulast/Makefile.am b/framework/src/audit/tools/aulast/Makefile.am deleted file mode 100644 index b20987f9..00000000 --- a/framework/src/audit/tools/aulast/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile.am -- -# Copyright 2008,2010,2015 Red Hat Inc., Durham, North Carolina. -# All Rights Reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Authors: -# Steve Grubb <sgrubb@redhat.com> -# - -CONFIG_CLEAN_FILES = *.loT *.rej *.orig -AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = $(man_MANS) -AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/auparse -LIBS = -L${top_builddir}/auparse -lauparse -AM_CFLAGS = -D_GNU_SOURCE -bin_PROGRAMS = aulast -noinst_HEADERS = aulast-llist.h -man_MANS = aulast.8 - -aulast_SOURCES = aulast.c aulast-llist.c - diff --git a/framework/src/audit/tools/aulast/aulast-llist.c b/framework/src/audit/tools/aulast/aulast-llist.c deleted file mode 100644 index be05e976..00000000 --- a/framework/src/audit/tools/aulast/aulast-llist.c +++ /dev/null @@ -1,196 +0,0 @@ -/* -* aulast-llist.c - Minimal linked list library -* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina. -* All Rights Reserved. -* -* This software may be freely redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2, or (at your option) any -* later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; see the file COPYING. If not, write to the -* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -* Authors: -* Steve Grubb <sgrubb@redhat.com> -*/ - -#include <stdlib.h> -#include <string.h> -#include "aulast-llist.h" - -void list_create(llist *l) -{ - l->head = NULL; - l->cur = NULL; -} - -lnode *list_next(llist *l) -{ - if (l->cur == NULL) - return NULL; - l->cur = l->cur->next; - return l->cur; -} - -static void list_append(llist *l, lnode *node) -{ - node->next = NULL; - - // if we are at top, fix this up - if (l->head == NULL) - l->head = node; - else if (l->cur) { - // Make sure we are at the end - while (l->cur->next) - l->cur = l->cur->next; - - l->cur->next = node; - } - - // make newnode current - l->cur = node; -} - -void list_clear(llist* l) -{ - lnode* nextnode; - register lnode* current; - - current = l->head; - while (current) { - nextnode=current->next; - free((void *)current->name); - free((void *)current->term); - free((void *)current->host); - free(current); - current=nextnode; - } - l->head = NULL; - l->cur = NULL; -} - -int list_create_session(llist *l, uid_t auid, int pid, int session, - unsigned long serial) -{ - lnode *n = malloc(sizeof(lnode)); - if (n == NULL) - return 0; - n->session = session; - n->start = 0; - n->end = 0; - n->auid = auid; - n->pid = pid; - n->result = -1; - n->name = NULL; - n->term = NULL; - n->host = NULL; - n->status = LOG_IN; - n->loginuid_proof = serial; - n->user_login_proof = 0; - n->user_end_proof = 0; - list_append(l, n); - return 1; -} - -int list_update_start(llist* l, time_t start, const char *host, - const char *term, int res, unsigned long serial) -{ - register lnode* cur; - if (l == NULL) - return 0; - - cur=list_get_cur(l); - cur->start = start; - cur->status = SESSION_START; - if (term) - cur->term = strdup(term); - if (host) - cur->host = strdup(host); - cur->result = res; - cur->user_login_proof = serial; - return 1; -} - -int list_update_logout(llist* l, time_t t, unsigned long serial) -{ - register lnode* cur; - if (l == NULL) - return 0; - - cur=list_get_cur(l); - cur->end = t; - cur->status = LOG_OUT; - cur->user_end_proof = serial; - return 1; -} - -lnode *list_delete_cur(llist *l) -{ - register lnode *cur, *prev; - - prev = cur = l->head; /* start at the beginning */ - while (cur) { - if (cur == l->cur) { - if (cur == prev && cur == l->head) { - l->head = cur->next; - l->cur = cur->next; - free((void *)cur->name); - free((void *)cur->term); - free((void *)cur->host); - free(cur); - prev = NULL; - } else { - prev->next = cur->next; - free((void *)cur->name); - free((void *)cur->term); - free((void *)cur->host); - free(cur); - l->cur = prev; - } - return prev; - } else { - prev = cur; - cur = cur->next; - } - } - return NULL; -} - -lnode *list_find_auid(llist *l, uid_t auid, int pid, unsigned int session) -{ - register lnode* cur; - - cur = l->head; /* start at the beginning */ - while (cur) { - if (cur->pid == pid && cur->auid == auid && - cur->session == session) { - l->cur = cur; - return cur; - } else - cur = cur->next; - } - return NULL; -} - -lnode *list_find_session(llist *l, unsigned int session) -{ - register lnode* cur; - - cur = l->head; /* start at the beginning */ - while (cur) { - if (cur->session == session) { - l->cur = cur; - return cur; - } else - cur = cur->next; - } - return NULL; -} - diff --git a/framework/src/audit/tools/aulast/aulast-llist.h b/framework/src/audit/tools/aulast/aulast-llist.h deleted file mode 100644 index a56cace2..00000000 --- a/framework/src/audit/tools/aulast/aulast-llist.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -* aulast-llist.h - Header file for aulastlog-llist.c -* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina. -* All Rights Reserved. -* -* This software may be freely redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2, or (at your option) any -* later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; see the file COPYING. If not, write to the -* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -* Authors: -* Steve Grubb <sgrubb@redhat.com> -*/ - -#ifndef AULASTLIST_HEADER -#define AULASTLIST_HEADER - -#include <sys/types.h> - - -typedef enum { LOG_IN, SESSION_START, LOG_OUT, DOWN, CRASH, GONE } status_t; - -/* This is the node of the linked list. message & item are the only elements - * at this time. Any data elements that are per item goes here. */ -typedef struct _lnode{ - unsigned int session; // The kernel login session id - time_t start; // first time uid logged in - time_t end; // last time uid logged in - uid_t auid; // user ID - int pid; // pid of program logging in - const char *name; // user name - const char *term; // terminal name - const char *host; // host where logging in from - int result; // login results - status_t status; // Current status of this session - unsigned long loginuid_proof; // audit serial number for loginuid change - unsigned long user_login_proof; // audit serial number for user login event - unsigned long user_end_proof; // audit serial number for user log out event - struct _lnode* next; // Next node pointer -} lnode; - -/* This is the linked list head. Only data elements that are 1 per - * event goes here. */ -typedef struct { - lnode *head; // List head - lnode *cur; // Pointer to current node -} llist; - -void list_create(llist *l); -static inline void list_first(llist *l) { l->cur = l->head; } -lnode *list_next(llist *l); -static inline lnode *list_get_cur(llist *l) { return l->cur; } -void list_clear(llist* l); -int list_create_session(llist* l, uid_t auid, int pid, int session, - unsigned long serial); -int list_update_start(llist* l, time_t start, const char *host, - const char *term, int res, unsigned long serial); -int list_update_logout(llist* l, time_t t, unsigned long serial); -lnode *list_delete_cur(llist *l); - -/* Given a uid, find that record. */ -lnode *list_find_auid(llist *l, uid_t auid, int pid, unsigned int session); -lnode *list_find_session(llist *l, unsigned int session); - -#endif - diff --git a/framework/src/audit/tools/aulast/aulast.8 b/framework/src/audit/tools/aulast/aulast.8 deleted file mode 100644 index 25705f95..00000000 --- a/framework/src/audit/tools/aulast/aulast.8 +++ /dev/null @@ -1,47 +0,0 @@ -.TH AULAST: "8" "Nov 2008" "Red Hat" "System Administration Utilities" -.SH NAME -aulast \- a program similar to last -.SH SYNOPSIS -.B aulast [ options ] [ user ] [ tty ] - -.SH DESCRIPTION -\fBaulast\fP is a program that prints out a listing of the last logged in users similarly to the program \fBlast\fP and \fBlastb\fP. Aulast searches back through the audit logs or the given audit log file and displays a list of all users logged in (and out) based on the range of time in the audit logs. Names of users and tty’s can be given, in which case aulast will show only those entries matching the arguments. Names of ttys can be abbreviated, thus aulast 0 is the same as last tty0. - -The pseudo user reboot logs in each time the system is rebooted. Thus last reboot will show a log of all reboots since the log file was created. - -The main difference that a user will notice is that \fBaulast\fP print events from oldest to newest, while \fBlast\fP prints records from newest to oldest. Also, the audit system is not notified each time a tty or pty is allocated, so you may not see quite as many records indicating users and their tty's. - -.SH OPTIONS -.TP -.B \-\-bad -Report on the bad logins. - -.TP -.B \-\-extract -Write raw audit records used to create the displayed report into a file aulast.log in the current working directory. - -.TP -.BI \-f file -Use the file instead of the audit logs for input. - -.TP -.B \-\-proof -Print out the audit event serial numbers used to determine the preceding line of the report. A Serial number of 0 is a place holder and not an actual event serial number. The serial numbers can be used to examine the actual audit records in more detail. Also an ausearch query is printed that will let you find the audit records associated with that session. - -.TP -.B \-\-stdin -Take audit records from stdin. - -.SH "EXAMPLES" -.nf -To see this month's logins -.B ausearch \-\-start this-month \-\-raw | aulast \-\-stdin - -.SH "SEE ALSO" -.BR last (1), -.BR lastb (1), -.BR ausearch (8), -.BR aureport (8). - -.SH AUTHOR -Steve Grubb diff --git a/framework/src/audit/tools/aulast/aulast.c b/framework/src/audit/tools/aulast/aulast.c deleted file mode 100644 index 00ae055a..00000000 --- a/framework/src/audit/tools/aulast/aulast.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * aulast.c - A last program based on audit logs - * Copyright (c) 2008-2009,2011 Red Hat Inc., Durham, North Carolina. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Authors: - * Steve Grubb <sgrubb@redhat.com> - */ - -#include "config.h" -#include <stdio.h> -#include <locale.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <pwd.h> -#include <stdlib.h> -#include "libaudit.h" -#include "auparse.h" -#include "aulast-llist.h" - - -static llist l; -static FILE *f = NULL; -static char *kernel = NULL; - -/* command line params */ -static int cuid = -1, bad = 0, proof = 0, debug = 0; -static char *cterm = NULL; - -void usage(void) -{ - fprintf(stderr, - "usage: aulast [--stdin] [--proof] [--extract] [-f file] [user name] [tty]\n"); -} - -/* This outputs a line of text reporting the login/out times */ -static void report_session(lnode* cur) -{ - int notime = 0; - - // Don't list failed logins - if (cur == NULL) - return; - - if (cur->result != bad) - return; - - if (cur->name) { - // This is a reboot record - printf("%-8.8s ", cur->name); - if (cur->end == 0) { - cur->end = time(NULL); - notime = 1; - } - } else { - struct passwd *p = getpwuid(cur->auid); - if (p) - printf("%-8.8s ", p->pw_name); - else - printf("%-8.u ", cur->auid); - } - if (strncmp("/dev/", cur->term, 5) == 0) - printf("%-12.12s ", cur->term+5); - else - printf("%-12.12s ", cur->term); - printf("%-16.16s ", cur->host ? cur->host : "?"); - printf("%-16.16s ", ctime(&cur->start)); - switch(cur->status) - { - case SESSION_START: - printf(" still logged in\n"); - break; - case DOWN: - printf("- down\n"); - break; - case CRASH: - printf("- crash\n"); - break; - case GONE: - printf(" gone - no logout\n"); - break; - case LOG_OUT: { - time_t secs; - int mins, hours, days; - if (notime) - printf("- %-7.5s", " "); - else - printf("- %-7.5s", ctime(&cur->end) + 11); - secs = cur->end - cur->start; - mins = (secs / 60) % 60; - hours = (secs / 3600) % 24; - days = secs / 86400; - if (days) - printf("(%d+%02d:%02d)\n", days, hours, mins); - else - printf("(%02d:%02d)\n", hours, mins); - } - break; - default: - printf("\n"); - break; - } - if (proof) { - char start[32], end[32]; - struct tm *btm; - - if (cur->loginuid_proof == 0 && cur->result == 1) // Bad login - printf(" audit event proof serial number:" - " %lu\n", cur->user_login_proof); - else - printf(" audit event proof serial numbers:" - " %lu, %lu, %lu\n", cur->loginuid_proof, - cur->user_login_proof, cur->user_end_proof); - printf(" Session data can be found with this search:\n"); - btm = localtime(&cur->start); - strftime(start, sizeof(start), "%x %T", btm); - if (cur->end != 0) { - btm = localtime(&cur->end); - strftime(end, sizeof(end), "%x %T", btm); - printf(" ausearch --start %s --end %s", - start, end); - } else { - printf(" ausearch --start %s", start); - } - if (cur->name == NULL) - printf(" --session %d", cur->session); - if (cur->loginuid_proof == 0 && cur->result == 1) // Bad login - printf(" -a %lu", cur->user_login_proof); - printf("\n\n"); - } -} - -static void extract_record(auparse_state_t *au) -{ - if (f == NULL) - return; - - fprintf(f, "%s\n", auparse_get_record_text(au)); -} - -static void create_new_session(auparse_state_t *au) -{ - const char *tpid, *tses, *tauid; - int pid = -1, auid = -1, ses = -1; - lnode *cur; - - // Get pid - tpid = auparse_find_field(au, "pid"); - if (tpid) - pid = auparse_get_field_int(au); - - // Get second auid field - tauid = auparse_find_field(au, "old-auid"); - if (tauid) - tauid = auparse_find_field(au, "auid"); - else { // kernel 3.13 or older - auparse_first_record(au); - auparse_find_field(au, "auid"); - auparse_next_field(au); - tauid = auparse_find_field(au, "auid"); - } - if (tauid) - auid = auparse_get_field_int(au); - - // Get second ses field - tses = auparse_find_field(au, "old-ses"); - if (tses) - tses = auparse_find_field(au, "ses"); - else { // kernel 3.13 or older - auparse_first_record(au); - auparse_find_field(au, "ses"); - auparse_next_field(au); - tses = auparse_find_field(au, "ses"); - } - if (tses) - ses = auparse_get_field_int(au); - - // Check that they are valid - if (pid == -1 || auid ==-1 || ses == -1) { - if (debug) - fprintf(stderr, "Bad login for event: %lu\n", - auparse_get_serial(au)); - return; - } - - // See if this session is already open - //cur = list_find_auid(&l, auid, pid, ses); - cur = list_find_session(&l, ses); - if (cur) { - // This means we have an open session close it out - cur->status = GONE; - cur->end = auparse_get_time(au); - report_session(cur); - list_delete_cur(&l); - } - - // If this is supposed to be limited to a specific - // uid and we don't have that record, skip creating it - if (cuid != -1 && cuid != auid) { - if (debug) - fprintf(stderr, - "login reporting limited to %d for event: %lu\n", - cuid, auparse_get_serial(au)); - return; - } - - list_create_session(&l, auid, pid, ses, auparse_get_serial(au)); -} - -static void update_session_login(auparse_state_t *au) -{ - const char *tpid, *tses, *tuid, *tacct=NULL, *host, *term, *tres; - int pid = -1, uid = -1, ses = -1, result = -1; - time_t start; - lnode *cur; - - // Get pid - tpid = auparse_find_field(au, "pid"); - if (tpid) - pid = auparse_get_field_int(au); - - // Get ses field - skipping first uid - tses = auparse_find_field(au, "ses"); - if (tses) - ses = auparse_get_field_int(au); - - // Get second uid field - we should be positioned past the first one - // gdm sends uid, everything else sends id, we try acct as last resort - tuid = auparse_find_field(au, "uid"); - if (tuid) - uid = auparse_get_field_int(au); - else { - auparse_first_record(au); - tuid = auparse_find_field(au, "id"); - if (tuid) - uid = auparse_get_field_int(au); - else { - auparse_first_record(au); - tuid = auparse_find_field(au, "acct"); - if (tuid) { - const char *tacct = auparse_interpret_field(au); - struct passwd *pw = getpwnam (tacct); - if (pw != NULL) - uid = pw->pw_uid; - } else - auparse_first_record(au); - } - } - - start = auparse_get_time(au); - - host = auparse_find_field(au, "hostname"); - if (host && strcmp(host, "?") == 0) - host = auparse_find_field(au, "addr"); - - term = auparse_find_field(au, "terminal"); - if (term == NULL) - term = "?"; - tres = auparse_find_field(au, "res"); - if (tres) - tres = auparse_interpret_field(au); - if (tres) { - if (strcmp(tres, "success") == 0) - result = 0; - else - result = 1; - } - // We only get tacct when its a bad login - if (result == 1) { - auparse_first_record(au); - tacct = auparse_find_field(au, "acct"); - if (tacct) - tacct = auparse_interpret_field(au); - } else { - // Check that they are valid - if (pid == -1 || uid ==-1 || ses == -1) { - if (debug) - fprintf(stderr, - "Bad user login for event: %lu\n", - auparse_get_serial(au)); - return; - } - } - - // See if this session is already open - if (result == 0) - cur = list_find_auid(&l, uid, pid, ses); - else - cur = NULL; - if (cur) { - // If we are limited to a specific terminal and - // we find out the session is not associated with - // the terminal of interest, delete the current node - if (cterm && strstr(term, cterm) == NULL) { - list_delete_cur(&l); - if (debug) - fprintf(stderr, - "User login limited to %s for event: %lu\n", - cterm, auparse_get_serial(au)); - return; - } - - // This means we have an open session - update it - list_update_start(&l, start, host, term, result, - auparse_get_serial(au)); - - // If the results were failed, we can close it out - /* FIXME: result cannot be true. This is dead code. - if (result) { - report_session(cur); - list_delete_cur(&l); - } */ - } else if (bad == 1 && result == 1) { - // If it were a bad login and we are wanting bad logins - // create the record and report it. - lnode n; - - n.start = start; - n.end = start; - n.auid = uid; - n.name = tacct; - n.term = term; - n.host = host; - n.result = result; - n.status = LOG_OUT; - n.loginuid_proof = 0; - n.user_login_proof = auparse_get_serial(au); - n.user_end_proof = 0; - report_session(&n); - } else if (debug) - printf("Session not found or updated\n"); -} - -static void update_session_logout(auparse_state_t *au) -{ - const char *tses, *tauid, *tpid; - int pid = -1, auid = -1, ses = -1; - lnode *cur; - - // Get pid field - tpid = auparse_find_field(au, "pid"); - if (tpid) - pid = auparse_get_field_int(au); - - // Get auid field - tauid = auparse_find_field(au, "auid"); - if (tauid) - auid = auparse_get_field_int(au); - - // Get ses field - tses = auparse_find_field(au, "ses"); - if (tses) - ses = auparse_get_field_int(au); - - // Check that they are valid - if (pid == -1 || auid ==-1 || ses == -1) { - if (debug) - fprintf(stderr, "Bad user logout for event: %lu\n", - auparse_get_serial(au)); - return; - } - - // See if this session is already open - cur = list_find_auid(&l, auid, pid, ses); - if (cur) { - // if time never got updated, this must be a cron or su - // session...so we will just delete it. - if (cur->start) { - // This means we have an open session close it out - time_t end = auparse_get_time(au); - list_update_logout(&l, end, auparse_get_serial(au)); - report_session(cur); - } else if (debug) - fprintf(stderr, "start time error for event: %lu\n", - auparse_get_serial(au)); - list_delete_cur(&l); - } -} - -static void process_bootup(auparse_state_t *au) -{ - lnode *cur; - int start; - - // See if we have unclosed boot up and make into CRASH record - list_first(&l); - cur = list_get_cur(&l); - while (cur) { - if (cur->name) { - cur->user_end_proof = auparse_get_serial(au); - cur->status = CRASH; - cur->end = auparse_get_time(au); - report_session(cur); - } - cur = list_next(&l); - } - - // Logout and process anyone still left in the machine - list_first(&l); - cur = list_get_cur(&l); - while (cur) { - if (cur->status != CRASH) { - cur->user_end_proof = auparse_get_serial(au); - cur->status = DOWN; - cur->end = auparse_get_time(au); - report_session(cur); - } - cur = list_next(&l); - } - - // Since this is a boot message, all old entries should be gone - list_clear(&l); - list_create(&l); - - // make reboot record - user:reboot, tty:system boot, host: kernel - start = auparse_get_time(au); - list_create_session(&l, 0, 0, 0, auparse_get_serial(au)); - cur = list_get_cur(&l); - cur->start = start; - cur->name = strdup("reboot"); - cur->term = strdup("system boot"); - if (kernel) - cur->host = strdup(kernel); - cur->result = 0; -} - -static void process_kernel(auparse_state_t *au) -{ - const char *kernel_str = auparse_find_field(au, "kernel"); - if (kernel_str == NULL) - return; - - free(kernel); - kernel = strdup(kernel_str); -} - -static void process_shutdown(auparse_state_t *au) -{ - lnode *cur; - - // Find reboot record - list_first(&l); - cur = list_get_cur(&l); - while (cur) { - if (cur->name) { - // Found it - close it out and display it - time_t end = auparse_get_time(au); - list_update_logout(&l, end, auparse_get_serial(au)); - report_session(cur); - list_delete_cur(&l); - return; - } - cur = list_next(&l); - } -} - -int main(int argc, char *argv[]) -{ - int i, use_stdin = 0; - char *user = NULL, *file = NULL; - struct passwd *p; - auparse_state_t *au; - - setlocale (LC_ALL, ""); - for (i=1; i<argc; i++) { - if (argv[i][0] != '-') { - //take input and lookup as if it were a user name - //if that fails assume its a tty - if (user == NULL) { - p = getpwnam(argv[i]); - if (p) { - cuid = p->pw_uid; - user = argv[i]; - continue; - } - } - if (cterm == NULL) { - cterm = argv[i]; - } else { - usage(); - return 1; - } - } else { - if (strcmp(argv[i], "-f") == 0) { - if (use_stdin == 0) { - i++; - file = argv[i]; - } else { - fprintf(stderr,"stdin already given\n"); - return 1; - } - } else if (strcmp(argv[i], "--bad") == 0) { - bad = 1; - } else if (strcmp(argv[i], "--proof") == 0) { - proof = 1; - } else if (strcmp(argv[i], "--extract") == 0) { - f = fopen("aulast.log", "wt"); - } else if (strcmp(argv[i], "--stdin") == 0) { - if (file == NULL) - use_stdin = 1; - else { - fprintf(stderr, "file already given\n"); - return 1; - } - } else if (strcmp(argv[i], "--debug") == 0) { - debug = 1; - } else { - usage(); - return 1; - } - } - } - list_create(&l); - - // Search for successful user logins - if (file) - au = auparse_init(AUSOURCE_FILE, file); - else if (use_stdin) - au = auparse_init(AUSOURCE_FILE_POINTER, stdin); - else { - if (getuid()) { - fprintf(stderr, "You probably need to be root for this to work\n"); - } - au = auparse_init(AUSOURCE_LOGS, NULL); - } - if (au == NULL) { - fprintf(stderr, "Error - %s\n", strerror(errno)); - goto error_exit_1; - } - - // The theory: iterate though events - // 1) when LOGIN is found, create a new session node - // 2) if that session number exists, close out the old one - // 3) when USER_LOGIN is found, update session node - // 4) When USER_END is found update session node and close it out - // 5) When BOOT record found make new record and check for previous - // 6) If previous boot found, set status to crash and logout everyone - // 7) When SHUTDOWN found, close out reboot record - - while (auparse_next_event(au) > 0) { - // We will take advantage of the fact that all events - // of interest are one record long - int type = auparse_get_type(au); - if (type < 0) - continue; - switch (type) - { - case AUDIT_LOGIN: - create_new_session(au); - extract_record(au); - break; - case AUDIT_USER_LOGIN: - update_session_login(au); - extract_record(au); - break; - case AUDIT_USER_END: - update_session_logout(au); - extract_record(au); - break; - case AUDIT_SYSTEM_BOOT: - process_bootup(au); - extract_record(au); - break; - case AUDIT_SYSTEM_SHUTDOWN: - process_shutdown(au); - extract_record(au); - break; - case AUDIT_DAEMON_START: - process_kernel(au); - extract_record(au); - break; - } - } - auparse_destroy(au); - - // Now output the leftovers - list_first(&l); - do { - lnode *cur = list_get_cur(&l); - report_session(cur); - } while (list_next(&l)); - - free(kernel); - list_clear(&l); - if (f) - fclose(f); - return 0; - -error_exit_1: - list_clear(&l); - if (f) - fclose(f); - return 1; -} - diff --git a/framework/src/audit/tools/aulastlog/Makefile.am b/framework/src/audit/tools/aulastlog/Makefile.am deleted file mode 100644 index 5c2403a9..00000000 --- a/framework/src/audit/tools/aulastlog/Makefile.am +++ /dev/null @@ -1,34 +0,0 @@ -# Makefile.am -- -# Copyright 2008,2010,2015 Red Hat Inc., Durham, North Carolina. -# All Rights Reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Authors: -# Steve Grubb <sgrubb@redhat.com> -# - -CONFIG_CLEAN_FILES = *.loT *.rej *.orig -AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = $(man_MANS) -AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/auparse -LIBS = -L${top_builddir}/auparse -lauparse -AM_CFLAGS = -D_GNU_SOURCE -bin_PROGRAMS = aulastlog -noinst_HEADERS = aulastlog-llist.h -man_MANS = aulastlog.8 - -aulastlog_SOURCES = aulastlog.c aulastlog-llist.c - diff --git a/framework/src/audit/tools/aulastlog/aulastlog-llist.c b/framework/src/audit/tools/aulastlog/aulastlog-llist.c deleted file mode 100644 index 25242b00..00000000 --- a/framework/src/audit/tools/aulastlog/aulastlog-llist.c +++ /dev/null @@ -1,148 +0,0 @@ -/* -* aulastlog-llist.c - Minimal linked list library -* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina. -* All Rights Reserved. -* -* This software may be freely redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2, or (at your option) any -* later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; see the file COPYING. If not, write to the -* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -* Authors: -* Steve Grubb <sgrubb@redhat.com> -*/ - -#include <stdlib.h> -#include <string.h> -#include "aulastlog-llist.h" - -void list_create(llist *l) -{ - l->head = NULL; - l->cur = NULL; - l->cnt = 0; -} - -lnode *list_next(llist *l) -{ - if (l->cur == NULL) - return NULL; - l->cur = l->cur->next; - return l->cur; -} - -void list_append(llist *l, lnode *node) -{ - lnode* newnode; - - newnode = malloc(sizeof(lnode)); - - newnode->sec = node->sec; - newnode->uid = node->uid; - newnode->name = strdup(node->name); - if (node->host) - newnode->host = strdup(node->host); - else - newnode->host = NULL; - if (node->term) - newnode->term = strdup(node->term); - else - newnode->term = NULL; - newnode->item = l->cnt; - newnode->next = NULL; - - // if we are at top, fix this up - if (l->head == NULL) - l->head = newnode; - else // Otherwise add pointer to newnode - l->cur->next = newnode; - - // make newnode current - l->cur = newnode; - l->cnt++; -} - -void list_clear(llist* l) -{ - lnode* nextnode; - register lnode* current; - - current = l->head; - while (current) { - nextnode=current->next; - free(current->name); - free(current->host); - free(current->term); - free(current); - current=nextnode; - } - l->head = NULL; - l->cur = NULL; - l->cnt = 0; -} - -int list_update_login(llist* l, time_t t) -{ - register lnode* cur; - if (l == NULL) - return 0; - - cur=list_get_cur(l); - cur->sec = t; - return 1; -} - -int list_update_host(llist* l, const char *h) -{ - register lnode* cur; - if (l == NULL) - return 0; - - cur=list_get_cur(l); - if (h) { - free(cur->host); - cur->host = strdup(h); - } else - cur->host = NULL; - return 1; -} - -int list_update_term(llist* l, const char *t) -{ - register lnode* cur; - if (l == NULL) - return 0; - - cur=list_get_cur(l); - if (t) { - free(cur->term); - cur->term = strdup(t); - } else - cur->term = NULL; - return 1; -} - -lnode *list_find_uid(llist *l, uid_t uid) -{ - register lnode* window; - - window = l->head; /* start at the beginning */ - while (window) { - if (window->uid == uid) { - l->cur = window; - return window; - } else - window = window->next; - } - return NULL; -} - diff --git a/framework/src/audit/tools/aulastlog/aulastlog-llist.h b/framework/src/audit/tools/aulastlog/aulastlog-llist.h deleted file mode 100644 index ea965425..00000000 --- a/framework/src/audit/tools/aulastlog/aulastlog-llist.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* aulastlog-llist.h - Header file for aulastlog-llist.c -* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina. -* All Rights Reserved. -* -* This software may be freely redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free -* Software Foundation; either version 2, or (at your option) any -* later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; see the file COPYING. If not, write to the -* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -* -* Authors: -* Steve Grubb <sgrubb@redhat.com> -*/ - -#ifndef AULASTLIST_HEADER -#define AULASTLIST_HEADER - -#include <sys/types.h> - - -/* This is the node of the linked list. message & item are the only elements - * at this time. Any data elements that are per item goes here. */ -typedef struct _lnode{ - time_t sec; // last time uid logged in - uid_t uid; // user ID - char *name; // users name - char *host; // host where logging in from - char *term; // terminal name - unsigned int item; // Which item of the same event - struct _lnode* next; // Next node pointer -} lnode; - -/* This is the linked list head. Only data elements that are 1 per - * event goes here. */ -typedef struct { - lnode *head; // List head - lnode *cur; // Pointer to current node - unsigned int cnt; // How many items in this list -} llist; - -void list_create(llist *l); -static inline void list_first(llist *l) { l->cur = l->head; } -lnode *list_next(llist *l); -static inline lnode *list_get_cur(llist *l) { return l->cur; } -static inline unsigned int list_get_cnt(llist *l) { return l->cnt; } -void list_append(llist *l, lnode *node); -void list_clear(llist* l); -int list_update_login(llist* l, time_t t); -int list_update_host(llist* l, const char *h); -int list_update_term(llist* l, const char *t); - -/* Given a uid, find that record. */ -lnode *list_find_uid(llist *l, uid_t uid); - -#endif - diff --git a/framework/src/audit/tools/aulastlog/aulastlog.8 b/framework/src/audit/tools/aulastlog/aulastlog.8 deleted file mode 100644 index b8b44c4f..00000000 --- a/framework/src/audit/tools/aulastlog/aulastlog.8 +++ /dev/null @@ -1,24 +0,0 @@ -.TH AULASTLOG: "8" "Feb 2009" "Red Hat" "System Administration Utilities" -.SH NAME -aulastlog \- a program similar to lastlog -.SH SYNOPSIS -.B aulastlog [ options ] -.SH DESCRIPTION -\fBaulastlog\fP is a program that prints out the last login for all users of a machine similar to the way lastlog does. The login-name, port, and last login time will be printed. - -If the user has never logged in, the message \fB** Never logged in**\fP will be displayed instead of the port and time. - -.SH OPTIONS -.TP -.B \-u, \-\-user -Print the lastlog record for user with specified LOGIN only. -.TP -.B \-\-stdin -Use stdin as the source of audit records. -.SH "SEE ALSO" -.BR lastlog (8), -.BR ausearch (8), -.BR aureport (8). - -.SH AUTHOR -Steve Grubb diff --git a/framework/src/audit/tools/aulastlog/aulastlog.c b/framework/src/audit/tools/aulastlog/aulastlog.c deleted file mode 100644 index c51b1efb..00000000 --- a/framework/src/audit/tools/aulastlog/aulastlog.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * aulastlog.c - A lastlog program based on audit logs - * Copyright (c) 2008-2009,2011 Red Hat Inc., Durham, North Carolina. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Authors: - * Steve Grubb <sgrubb@redhat.com> - */ - -#include <stdio.h> -#include <locale.h> -#include <string.h> -#include <errno.h> -#include <pwd.h> -#include "auparse.h" -#include "aulastlog-llist.h" - -void usage(void) -{ - fprintf(stderr, "usage: aulastlog [--stdin] [--user name]\n"); -} - -int main(int argc, char *argv[]) -{ - int i, use_stdin = 0; - char *user = NULL; - struct passwd *p; - auparse_state_t *au; - llist l; - - setlocale (LC_ALL, ""); - for (i=1; i<argc; i++) { - if ((strcmp(argv[i], "--user") == 0) || - (strcmp(argv[i], "-u") == 0)) { - i++; - if (i<argc) - user = argv[i]; - else { - usage(); - return 1; - } - } else if (strcmp(argv[i], "--stdin") == 0) { - use_stdin = 1; - } else { - usage(); - return 1; - } - } - - list_create(&l); - - // Stuff linked lists with all users - while ((p = getpwent()) != NULL) { - lnode n; - - n.sec = 0; - n.uid = p->pw_uid; - n.name = p->pw_name; - n.host = NULL; - n.term = NULL; - if (user == NULL) - list_append(&l, &n); - else if (strcmp(user, p->pw_name) == 0) - list_append(&l, &n); - } - endpwent(); - - if (user && list_get_cnt(&l) == 0) { - printf("Unknown User: %s\n", user); - return 1; - } - - // Search for successful user logins - if (use_stdin) - au = auparse_init(AUSOURCE_FILE_POINTER, stdin); - else - au = auparse_init(AUSOURCE_LOGS, NULL); - if (au == NULL) { - printf("Error - %s\n", strerror(errno)); - goto error_exit_1; - } - if (ausearch_add_item(au, "type", "=", "USER_LOGIN", - AUSEARCH_RULE_CLEAR)){ - printf("ausearch_add_item error - %s\n", strerror(errno)); - goto error_exit_2; - } - if (ausearch_add_item(au, "res", "=", "success", - AUSEARCH_RULE_AND)){ - printf("ausearch_add_item error - %s\n", strerror(errno)); - goto error_exit_2; - } - if (ausearch_set_stop(au, AUSEARCH_STOP_RECORD)){ - printf("ausearch_set_stop error - %s\n", strerror(errno)); - goto error_exit_2; - } - - // Now scan the logs and append events - while (ausearch_next_event(au) > 0) { - const au_event_t *e = auparse_get_timestamp(au); - if (auparse_find_field(au, "auid")) { - uid_t u = auparse_get_field_int(au); - list_first(&l); - if (list_find_uid(&l, u)) { - const char *str; - - list_update_login(&l, e->sec); - str = auparse_find_field(au, "hostname"); - if (str) - list_update_host(&l, str); - str = auparse_find_field(au, "terminal"); - if (str) - list_update_term(&l, str); - } - } - if (auparse_next_event(au) < 0) - break; - } - auparse_destroy(au); - - // Now output the report - printf( "Username Port From" - " Latest\n"); - list_first(&l); - do { - char tmp[48]; - const char *c, *h, *t; - lnode *cur = list_get_cur(&l); - if (cur->sec == 0) - c = "**Never logged in**"; - else { - struct tm *btm; - - btm = localtime(&cur->sec); - strftime(tmp, sizeof(tmp), "%x %T", btm); - c = tmp; - } - h = cur->host; - if (h == NULL) - h = ""; - t = cur->term; - if (t == NULL) - t = ""; - printf("%-16s %-12.12s %-26.26s %s\n", cur->name, t, h, c); - } while (list_next(&l)); - - list_clear(&l); - return 0; - -error_exit_2: - auparse_destroy(au); -error_exit_1: - list_clear(&l); - return 1; -} - diff --git a/framework/src/audit/tools/ausyscall/Makefile.am b/framework/src/audit/tools/ausyscall/Makefile.am deleted file mode 100644 index 6ad983e5..00000000 --- a/framework/src/audit/tools/ausyscall/Makefile.am +++ /dev/null @@ -1,32 +0,0 @@ -# Makefile.am -- -# Copyright 2008,2015 Red Hat Inc., Durham, North Carolina. -# All Rights Reserved. -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Authors: -# Steve Grubb <sgrubb@redhat.com> -# - -CONFIG_CLEAN_FILES = *.loT *.rej *.orig -AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = $(man_MANS) -AM_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/lib -LIBS = -L${top_builddir}/lib -laudit -bin_PROGRAMS = ausyscall -man_MANS = ausyscall.8 - -ausyscall_SOURCES = ausyscall.c -ausyscall_CFLAGS = -g -D_GNU_SOURCE diff --git a/framework/src/audit/tools/ausyscall/ausyscall.8 b/framework/src/audit/tools/ausyscall/ausyscall.8 deleted file mode 100644 index 16f9196e..00000000 --- a/framework/src/audit/tools/ausyscall/ausyscall.8 +++ /dev/null @@ -1,34 +0,0 @@ -.TH AUSYSCALL: "8" "Nov 2008" "Red Hat" "System Administration Utilities" -.SH NAME -ausyscall \- a program that allows mapping syscall names and numbers -.SH SYNOPSIS -.B ausyscall [arch] name | number | \-\-dump | \-\-exact -.SH DESCRIPTION -\fBausyscall\fP is a program that prints out the mapping from syscall name to number and reverse for the given arch. The arch can be anything returned by `uname \-m`. If arch is not given, the program will take a guess based on the running image. You may give the syscall name or number and it will find the opposite. You can also dump the whole table with the \-\-dump option. By default a syscall name lookup will be a substring match meaning that it will try to match all occurrences of the given name with syscalls. So giving a name of chown will match both fchown and chown as any other syscall with chown in its name. If this behavior is not desired, pass the \-\-exact flag and it will do an exact string match. - -This program can be used to verify syscall numbers on a biarch platform for rule optimization. For example, suppose you had an auditctl rule: - -.B \-a always, exit \-S open \-F exit=\-EPERM \-k fail\-open - -If you wanted to verify that both 32 and 64 bit programs would be audited, run "ausyscall i386 open" and then "ausyscall x86_64 open". Look at the returned numbers. If they are different, you will have to write two auditctl rules to get complete coverage. - -.nf -.B \-a always,exit \-F arch=b32 \-S open \-F exit=\-EPERM \-k fail\-open -.B \-a always,exit \-F arch=b64 \-S open \-F exit=\-EPERM \-k fail\-open -.fi - -For more information about a specific syscall, use the man program and pass the number 2 as an argument to make sure that you get the syscall information rather than a shell script program or glibc function call of the same name. For example, if you wanted to learn about the open syscall, type: man 2 open. -.SH OPTIONS -.TP -.B \-\-dump -Print all syscalls for the given arch -.TP -.B \-\-exact -Instead of doing a partial word match, match the given syscall name exactly. - -.SH "SEE ALSO" -.BR ausearch (8), -.BR auditctl (8). - -.SH AUTHOR -Steve Grubb diff --git a/framework/src/audit/tools/ausyscall/ausyscall.c b/framework/src/audit/tools/ausyscall/ausyscall.c deleted file mode 100644 index 361afd99..00000000 --- a/framework/src/audit/tools/ausyscall/ausyscall.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * ausysvcall.c - A program that lets you map syscall names and numbers - * Copyright (c) 2008 Red Hat Inc., Durham, North Carolina. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Authors: - * Steve Grubb <sgrubb@redhat.com> - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> -#include "libaudit.h" - -#define LAST_SYSCALL 1400 // IA64 is in the 1300's right now - -void usage(void) -{ - fprintf(stderr, "usage: ausyscall [arch] name | number | --dump | --exact\n"); - exit(1); -} - -int main(int argc, char *argv[]) -{ - int i, rc; - int machine=-1, syscall_num=-1, dump=0, exact=0; - const char *name = NULL; - - if (argc > 4) { - fputs("Too many arguments\n", stderr); - usage(); - } else if (argc < 2) - usage(); - - for (i=1; i<argc; i++) { - if (isdigit(argv[i][0])) { - if (syscall_num != -1) { - fputs("Two syscall numbers not allowed\n", - stderr); - usage(); - } - syscall_num = strtol(argv[i], 0, 10); - } else if ((rc = audit_name_to_machine(argv[i])) != -1) { - if (machine != -1) { - fputs("Two machine types not allowed\n",stderr); - usage(); - } - machine = rc; - } else if (strcmp("--dump", argv[i]) == 0) { - dump=1; - } else if (strcmp("--exact", argv[i]) == 0) { - exact=1; -#ifndef WITH_ALPHA - } else if (strcmp("alpha", argv[i]) == 0) { - fputs("Alpha processor support is not enabled\n", - stderr); - exit(1); -#endif -#ifndef WITH_ARM - } else if (strcmp("arm", argv[i]) == 0) { - fputs("Arm eabi processor support is not enabled\n", - stderr); - exit(1); -#endif -#ifndef WITH_AARCH64 - } else if (strcmp("aarch64", argv[i]) == 0) { - fputs("Aarch64 processor support is not enabled\n", - stderr); - exit(1); -#endif - } else { - if (name != NULL) { - fputs("Two syscall names not allowed\n",stderr); - usage(); - } - name = argv[i]; - } - } - if (machine == -1) - machine = audit_detect_machine(); - if (machine == -1) { - fprintf(stderr, "Unable to detect machine type\n"); - return 1; - } - - if (dump) { - printf("Using %s syscall table:\n", - audit_machine_to_name(machine)); - for (i=0; i<8192; i++) { - name = audit_syscall_to_name(i, machine); - if (name) - printf("%d\t%s\n", i, name); - } - return 0; - } - - if (name) { - if (exact) { - rc = audit_name_to_syscall(name, machine); - if (rc < 0) { - fprintf(stderr, - "Unknown syscall %s using %s lookup table\n", - name, audit_machine_to_name(machine)); - return 1; - } else - printf("%d\n", rc); - } else { - int found = 0; - for (i=0; i< LAST_SYSCALL; i++) { - const char *n = audit_syscall_to_name(i, machine); - if (n && strcasestr(n, name)) { - found = 1; - printf("%-18s %d\n", n, i); - } - } - if (!found) { - fprintf(stderr, - "Unknown syscall %s using %s lookup table\n", - name, audit_machine_to_name(machine)); - return 1; - } - } - } else if (syscall_num != -1) { - name = audit_syscall_to_name(syscall_num, machine); - if (name == NULL) { - fprintf(stderr, - "Unknown syscall %d using %s lookup table\n", - syscall_num, audit_machine_to_name(machine)); - return 1; - } else - printf("%s\n", name); - } else { - fputs("Error - either a syscall name or number must " - "be given with an optional arch\n", stderr); - return 1; - } - - return 0; -} - diff --git a/framework/src/audit/tools/auvirt/Makefile.am b/framework/src/audit/tools/auvirt/Makefile.am deleted file mode 100644 index 5f6490a4..00000000 --- a/framework/src/audit/tools/auvirt/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -# -# Makefile.am -- -# Copyright (c) 2011 IBM Corp. -# Copyright (C) 2015 Red Hat, Inc. -# All Rights Reserved. -# -# This software may be freely redistributed and/or modified under the -# terms of the GNU General Public License as published by the Free -# Software Foundation; either version 2, or (at your option) any -# later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; see the file COPYING. If not, write to the -# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -# Authors: -# Marcelo Henrique Cerri <mhcerri@br.ibm.com> -# - -CONFIG_CLEAN_FILES = *.loT *.rej *.orig -AUTOMAKE_OPTIONS = no-dependencies -EXTRA_DIST = $(man_MANS) -AM_CPPFLAGS = -I${top_srcdir} \ - -I${top_srcdir}/lib \ - -I${top_srcdir}/auparse \ - -I${top_srcdir}/src -LIBS = -L${top_builddir}/auparse -lauparse -AM_CFLAGS = -D_GNU_SOURCE -bin_PROGRAMS = auvirt -noinst_HEADERS = auvirt-list.h -man_MANS = auvirt.8 - -auvirt_SOURCES = auvirt.c \ - auvirt-list.c \ - ${top_srcdir}/src/ausearch-time.c diff --git a/framework/src/audit/tools/auvirt/auvirt-list.c b/framework/src/audit/tools/auvirt/auvirt-list.c deleted file mode 100644 index 75021889..00000000 --- a/framework/src/audit/tools/auvirt/auvirt-list.c +++ /dev/null @@ -1,105 +0,0 @@ -#include "auvirt-list.h" -#include <stdlib.h> - -list_t *list_init(list_t *list, list_free_data_fn *free_data_fn) -{ - if (list == NULL) - return NULL; - list->head = list->tail = NULL; - list->free_data_fn = free_data_fn; - return list; -} - -list_t *list_new(list_free_data_fn *free_data_fn) -{ - return list_init(malloc(sizeof(list_t)), free_data_fn); -} - -void list_free_node(list_node_t *node, list_free_data_fn *free_data_fn) -{ - if (node) { - if (free_data_fn) - free_data_fn(node->data); - free(node); - } -} - -void list_free_(list_t *list, list_free_data_fn *free_data_fn) -{ - if (list != NULL) { - list_node_t *it = list->head; - while (it && it->next) { - it = it->next; - list_free_node(it->prev, free_data_fn); - } - list_free_node(it, free_data_fn); - free(list); - } -} - -void list_free(list_t *list) -{ - if (list) - list_free_(list, list->free_data_fn); -} - -list_node_t *list_insert_after(list_t *list, list_node_t *it, - void *data) -{ - list_node_t *node = NULL; - if (list == NULL) - return NULL; - - /* allocate node */ - node = malloc(sizeof(list_node_t)); - if (node == NULL) - return NULL; - node->data = data; - - /* insert the new node after it */ - node->prev = it; - if (it) { - node->next = it->next; - it->next = node; - } - else - node->next = list->head; - if (node->next) - node->next->prev = node; - - /* update list's head and tail */ - if (it == list->tail) - list->tail = node; - if (it == NULL) - list->head = node; - - return node; -} - -list_node_t *list_append(list_t *list, void *data) -{ - return list_insert_after(list, list->tail, data); -} - -int list_remove_(list_t *list, list_node_t *it, - list_free_data_fn *free_data_fn) -{ - if (list == NULL || it == NULL) - return 1; - if (list->head == it) - list->head = it->next; - if (list->tail == it) - list->tail = it->prev; - if (it->next) - it->next->prev = it->prev; - if (it->prev) - it->prev->next = it->next; - list_free_node(it, free_data_fn); - return 0; -} - -int list_remove(list_t *list, list_node_t *it) -{ - return list_remove_(list, it, list->free_data_fn); -} - diff --git a/framework/src/audit/tools/auvirt/auvirt-list.h b/framework/src/audit/tools/auvirt/auvirt-list.h deleted file mode 100644 index fb587468..00000000 --- a/framework/src/audit/tools/auvirt/auvirt-list.h +++ /dev/null @@ -1,31 +0,0 @@ - -#ifndef AUVIRT_LIST_HEADER -#define AUVIRT_LIST_HEADER - -typedef void (list_free_data_fn)(void *data); - -typedef struct list_node_t { - void *data; - struct list_node_t *prev; - struct list_node_t *next; -} list_node_t; - -typedef struct list_t { - list_node_t *head; - list_node_t *tail; - list_free_data_fn *free_data_fn; -} list_t; - -list_t *list_init(list_t *list, list_free_data_fn *free_data_fn); -list_t *list_new(list_free_data_fn *free_data_fn); -void list_free_(list_t *list, list_free_data_fn *free_data_fn); -void list_free(list_t *list); -list_node_t *list_insert_after(list_t *list, list_node_t *it, - void *data); -list_node_t *list_append(list_t *list, void *data); -int list_remove_(list_t *list, list_node_t *it, - list_free_data_fn *free_data_fn); -int list_remove(list_t *list, list_node_t *it); - -#endif - diff --git a/framework/src/audit/tools/auvirt/auvirt.8 b/framework/src/audit/tools/auvirt/auvirt.8 deleted file mode 100644 index 96123f45..00000000 --- a/framework/src/audit/tools/auvirt/auvirt.8 +++ /dev/null @@ -1,121 +0,0 @@ -.TH AUVIRT 8 "Dec 2011" "IBM Corp" "System Administration Utilities" -.SH NAME -auvirt - a program that shows data related to virtual machines - -.SH SYNOPSIS -.B auvirt -[ \fIOPTIONS\fP ] - -.SH DESCRIPTION -\fBauvirt\fP shows a list of guest sessions found in the audit logs. If a guest -is specified, only the events related to that guest is considered. To specify a -guest, both UUID or VM name can be given. - -For each guest session the tool prints a record with the domain name, the user -that started the guest, the time when the guest was started and the time when -the guest was stoped. - -If the option "\-\-all\-events" is given a more detailed output is shown. In this -mode other records are shown for guest's stops, resource -assignments, host shutdowns and AVC and anomaly events. The first field -indicates the event type and can have the following values: start, stop, -res, avc, anom and down (for host shutdowns). - -Resource assignments have the additional fields: resource type, reason and -resource. And AVC records have the following additional fields: operation, -result, command and target. - -By default, auvirt reads records from the system audit log file. But -\fB--stdin\fP and \fB--file\fP options can be specified to change this -behavior. - -.SH OPTIONS -.TP -\fB--all-events\fP -Show records for all virtualization related events. -.TP -\fB--debug\fP -Print debug messages to standard output. -.TP -\fB-f\fP, \fB--file\fP \fIfile\fP -Read records from the given \fIfile\fP instead from the system audit log file. -.TP -\fB-h\fP, \fB--help\fP -Print help message and exit. -.TP -\fB--proof\fP -Add after each event a line containing all the identifiers of the audit records -used to calculate the event. Each identifier consists of unix time, -milliseconds and serial number. -.TP -\fB--show-uuid\fP -Add the guest's UUID to each record. -.TP -\fB--stdin\fP -Read records from the standard input instead from the system audit log file. -This option cannot be specified with \fB--file\fP. -.TP -\fB--summary\fP -Print a summary with information about the events found. The summary contains -the considered range of time, the number of guest starts and stops, the number -of resource assignments, the number of AVC and anomaly events, the number of -host shutdowns and the number of failed operations. -.TP -.BR \-te ,\ \-\-end \ [\fIend-date\fP]\ [\fIend-time\fP] -Search for events with time stamps equal to or before the given end time. The -format of end time depends on your locale. If the date is omitted, -.B today -is assumed. If the time is omitted, -.B now -is assumed. Use 24 hour clock time rather than AM or PM to specify time. -An example date using the en_US.utf8 locale is 09/03/2009. An example of time -is 18:00:00. The date format accepted is influenced by the LC_TIME -environmental variable. - -You may also use the word: \fBnow\fP, \fBrecent\fP, \fBtoday\fP, -\fByesterday\fP, \fBthis\-week\fP, \fBweek\-ago\fP, \fBthis\-month\fP, -\fBthis\-year\fP. \fBToday\fP means starting now. \fBRecent\fP is 10 minutes -ago. \fBYesterday\fP is 1 second after midnight the previous day. -\fBThis\-week\fP means starting 1 second after midnight on day 0 of the week -determined by your locale (see \fBlocaltime\fP). \fBThis\-month\fP means 1 -second after midnight on day 1 of the month. \fBThis\-year\fP means the 1 -second after midnight on the first day of the first month. -.TP -.BR \-ts ,\ \-\-start \ [\fIstart-date\fP]\ [\fIstart-time\fP] -Search for events with time stamps equal to or after the given end time. The -format of end time depends on your locale. If the date is omitted, -.B today -is assumed. If the time is omitted, -.B midnight -is assumed. Use 24 hour clock time rather than AM or PM to specify time. An -example date using the en_US.utf8 locale is 09/03/2009. An example of time is -18:00:00. The date format accepted is influenced by the LC_TIME environmental -variable. - -You may also use the word: \fBnow\fP, \fBrecent\fP, \fBtoday\fP, -\fByesterday\fP, \fBthis\-week\fP, \fBthis\-month\fP, \fBthis\-year\fP. -\fBToday\fP means starting at 1 second after midnight. \fBRecent\fP is 10 -minutes ago. \fBYesterday\fP is 1 second after midnight the previous day. -\fBThis\-week\fP means starting 1 second after midnight on day 0 of the week -determined by your locale (see \fBlocaltime\fP). \fBThis\-month\fP means 1 -second after midnight on day 1 of the month. \fBThis\-year\fP means the 1 -second after midnight on the first day of the first month. -.TP -\fB-u\fP, \fB--uuid\fP \ \fIUUID\fP -Only show events related to the guest with the given UUID. -.TP -\fB-v\fP, \fB--vm\fP \ \fIname\fP -Only show events related to the guest with the given name. - -.SH EXAMPLES -To see all the records in this month for a guest - -\fBauvirt \-\-start this\-month \-\-vm GuestVmName \-\-all\-events\fP - -.SH SEE ALSO -.BR aulast (8), -.BR ausearch (8), -.BR aureport (8). - -.SH AUTHOR -Marcelo Cerri diff --git a/framework/src/audit/tools/auvirt/auvirt.c b/framework/src/audit/tools/auvirt/auvirt.c deleted file mode 100644 index 655c4541..00000000 --- a/framework/src/audit/tools/auvirt/auvirt.c +++ /dev/null @@ -1,1595 +0,0 @@ -/* - * auvirt.c - A tool to extract data related to virtualization. - * Copyright (c) 2011 IBM Corp. - * All Rights Reserved. - * - * This software may be freely redistributed and/or modified under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Authors: - * Marcelo Henrique Cerri <mhcerri@br.ibm.com> - */ - -#include "config.h" -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <ctype.h> -#include <locale.h> -#include <string.h> -#include <regex.h> -#include <time.h> -#include <sys/types.h> -#include <pwd.h> -#include <unistd.h> -#include "auparse.h" -#include "libaudit.h" -#include "ausearch-time.h" -#include "auvirt-list.h" - -/* Command line parameters */ -static int help_flag = 0; -static int stdin_flag = 0; -static int summary_flag = 0; -static int all_events_flag = 0; -static int uuid_flag = 0; -static int proof_flag = 0; -static const char *vm = NULL; -static const char *uuid = NULL; -static const char *file = NULL; -static int debug = 0; -/* - * The start time and end time given in the command line is stored respectively - * in the variables start_time and end_time that are declared/defined in the - * files ausearch-time.h and ausearch-time.c. These files are reused from the - * ausearch tool source code: - * - * time_t start_time = 0; - * time_t end_time = 0; - */ - -/* List of events */ -enum event_type { - ET_NONE = 0, ET_START, ET_STOP, ET_MACHINE_ID, ET_AVC, ET_RES, ET_ANOM, - ET_DOWN -}; -struct record_id { - time_t time; - unsigned int milli; - unsigned long serial; -}; -struct event { - enum event_type type; - time_t start; - time_t end; - uid_t uid; - char *uuid; - char *name; - int success; - pid_t pid; - /* Fields specific for resource events: */ - char *reason; - char *res_type; - char *res; - /* Fields specific for cgroup resources */ - char *cgroup_class; - char *cgroup_detail; - char *cgroup_acl; - /* Fields specific for machine id events: */ - char *seclevel; - /* Fields specific for avc events: */ - char *avc_result; - char *avc_operation; - char *target; - char *comm; - char *context; - /* Fields to print proof information: */ - struct record_id proof[4]; -}; -list_t *events = NULL; - - -/* Auxiliary functions to allocate and to free events. */ -struct event *event_alloc(void) -{ - struct event *event = malloc(sizeof(struct event)); - if (event) { - /* The new event is initialized with values that represents - * unset values: -1 for uid and pid and 0 (or NULL) for numbers - * and pointers. For example, event->end = 0 represents an - * unfinished event. - */ - memset(event, 0, sizeof(struct event)); - event->uid = -1; - event->pid = -1; - } - return event; -} - -void event_free(struct event *event) -{ - if (event) { - free(event->uuid); - free(event->name); - free(event->reason); - free(event->res_type); - free(event->res); - free(event->avc_result); - free(event->avc_operation); - free(event->seclevel); - free(event->target); - free(event->comm); - free(event->cgroup_class); - free(event->cgroup_detail); - free(event->cgroup_acl); - free(event->context); - free(event); - } -} - -inline char *copy_str(const char *str) -{ - return (str) ? strdup(str) : NULL; -} - -void usage(FILE *output) -{ - fprintf(output, "usage: auvirt [--stdin] [--all-events] [--summary] " - "[--start start-date [start-time]] " - "[--end end-date [end-time]] [--file file-name] " - "[--show-uuid] [--proof] " - "[--uuid uuid] [--vm vm-name]\n"); -} - -/* Parse and check command line arguments */ -int parse_args(int argc, char **argv) -{ - /* Based on http://www.ietf.org/rfc/rfc4122.txt */ - const char *uuid_pattern = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-" - "[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"; - int i, rc = 0; - regex_t uuid_regex; - - if (regcomp(&uuid_regex, uuid_pattern, REG_EXTENDED)) { - fprintf(stderr, "Failed to initialize program.\n"); - return 1; - } - - for (i = 1; i < argc; i++) { - const char *opt = argv[i]; - if (opt[0] != '-') { - fprintf(stderr, "Argument not expected: %s\n", opt); - goto error; - } else if (strcmp("--vm", opt) == 0 || - strcmp("-v", opt) == 0) { - if ((i + 1) >= argc || argv[i + 1][0] == '-') { - fprintf(stderr, "\"%s\" option requires " - "an argument.\n", opt); - goto error; - } - vm = argv[++i]; - } else if (strcmp("--uuid", opt) == 0 || - strcmp("-u", opt) == 0) { - if ((i + 1) >= argc || argv[i + 1][0] == '-') { - fprintf(stderr, "\"%s\" option requires " - "an argument.\n", opt); - goto error; - } - if (regexec(&uuid_regex, argv[i + 1], 0, NULL, 0)) { - fprintf(stderr, "Invalid uuid: %s\n", - argv[i + 1]); - goto error; - } - uuid = argv[++i]; - } else if (strcmp("--all-events", opt) == 0 || - strcmp("-a", opt) == 0) { - all_events_flag = 1; - } else if (strcmp("--summary", opt) == 0 || - strcmp("-s", opt) == 0) { - summary_flag = 1; - } else if (strcmp("--file", opt) == 0 || - strcmp("-f", opt) == 0) { - if ((i + 1) >= argc || argv[i + 1][0] == '-') { - fprintf(stderr, "\"%s\" option requires " - "an argument.\n", opt); - goto error; - } - file = argv[++i]; - } else if (strcmp("--show-uuid", opt) == 0) { - uuid_flag = 1; - } else if (strcmp("--stdin", opt) == 0) { - stdin_flag = 1; - } else if (strcmp("--proof", opt) == 0) { - proof_flag = 1; - } else if (strcmp("--help", opt) == 0 || - strcmp("-h", opt) == 0) { - help_flag = 1; - goto exit; - } else if (strcmp("--start", opt) == 0 || - strcmp("-ts", opt) == 0) { - const char *date, *time = NULL; - if ((i + 1) >= argc || argv[i + 1][0] == '-') { - fprintf(stderr, "\"%s\" option requires at " - "least one argument.\n", opt); - goto error; - } - date = argv[++i]; - if ((i + 1) < argc && argv[i + 1][0] != '-') - time = argv[++i]; - /* This will set start_time */ - if(ausearch_time_start(date, time)) - goto error; - } else if (strcmp("--end", opt) == 0 || - strcmp("-te", opt) == 0) { - const char *date, *time = NULL; - if ((i + 1) >= argc || argv[i + 1][0] == '-') { - fprintf(stderr, "\"%s\" option requires at " - "least one argument.\n", opt); - goto error; - } - date = argv[++i]; - if ((i + 1) < argc && argv[i + 1][0] != '-') - time = argv[++i]; - /* This will set end_time */ - if (ausearch_time_end(date, time)) - goto error; - } else if (strcmp("--debug", opt) == 0) { - debug = 1; - } else { - fprintf(stderr, "Unknown option \"%s\".\n", opt); - goto error; - } - } - - /* Validate conflicting options */ - if (stdin_flag && file) { - fprintf(stderr, "\"--sdtin\" and \"--file\" options " - "must not be specified together.\n"); - goto error; - } - - if (debug) { - fprintf(stderr, "help_flag='%i'\n", help_flag); - fprintf(stderr, "stdin_flag='%i'\n", stdin_flag); - fprintf(stderr, "all_events_flag='%i'\n", all_events_flag); - fprintf(stderr, "summary_flag='%i'\n", summary_flag); - fprintf(stderr, "uuid='%s'\n", uuid ? uuid : "(null)"); - fprintf(stderr, "vm='%s'\n", vm ? vm : "(null)"); - fprintf(stderr, "file='%s'\n", file ? file : "(null)"); - fprintf(stderr, "start_time='%-.16s'\n", (start_time == 0L) ? - "" : ctime(&start_time)); - fprintf(stderr, "end_time='%-.16s'\n", (end_time == 0L) ? - "" : ctime(&end_time)); - } - -exit: - regfree(&uuid_regex); - return rc; -error: - rc = 1; - goto exit; -} - -/* Initialize an auparse_state_t with the correct log source. */ -auparse_state_t *init_auparse(void) -{ - auparse_state_t *au = NULL; - if (stdin_flag) { - au = auparse_init(AUSOURCE_FILE_POINTER, stdin); - } else if (file) { - au = auparse_init(AUSOURCE_FILE, file); - } else { - if (getuid()) { - fprintf(stderr, "You probably need to be root for " - "this to work\n"); - } - au = auparse_init(AUSOURCE_LOGS, NULL); - } - if (au == NULL) { - fprintf(stderr, "Error: %s\n", strerror(errno)); - } - return au; -} - -/* Create a criteria to search for the virtualization related records */ -int create_search_criteria(auparse_state_t *au) -{ - char *error = NULL; - char expr[1024]; - snprintf(expr, sizeof(expr), - "(\\record_type >= %d && \\record_type <= %d)", - AUDIT_FIRST_VIRT_MSG, AUDIT_LAST_VIRT_MSG); - if (ausearch_add_expression(au, expr, &error, AUSEARCH_RULE_CLEAR)) { - fprintf(stderr, "Criteria error: %s\n", error); - free(error); - return 1; - } - if (uuid) { - if (ausearch_add_item(au, "uuid", "=", uuid, - AUSEARCH_RULE_AND)) { - fprintf(stderr, "Criteria error: uuid\n"); - return 1; - } - } - if (vm) { - if (ausearch_add_interpreted_item(au, "vm", "=", vm, - AUSEARCH_RULE_AND)) { - fprintf(stderr, "Criteria error: id\n"); - return 1; - } - } - if (all_events_flag || summary_flag) { - if (ausearch_add_item(au, "type", "=", "AVC", - AUSEARCH_RULE_OR)) { - fprintf(stderr, "Criteria error: AVC\n"); - return 1; - } - if (ausearch_add_item(au, "type", "=", "SYSTEM_SHUTDOWN", - AUSEARCH_RULE_OR)) { - fprintf(stderr, "Criteria error: shutdown\n"); - return 1; - } - snprintf(expr, sizeof(expr), - "(\\record_type >= %d && \\record_type <= %d) ||" - "(\\record_type >= %d && \\record_type <= %d)", - AUDIT_FIRST_ANOM_MSG, AUDIT_LAST_ANOM_MSG, - AUDIT_FIRST_KERN_ANOM_MSG, AUDIT_LAST_KERN_ANOM_MSG); - if (ausearch_add_expression(au, expr, &error, - AUSEARCH_RULE_OR)) { - fprintf(stderr, "Criteria error: %s\n", error); - free(error); - return 1; - } - } - if (start_time) { - if (ausearch_add_timestamp_item(au, ">=", start_time, 0, - AUSEARCH_RULE_AND)) { - fprintf(stderr, "Criteria error: start_time\n"); - return 1; - } - } - if (end_time) { - if (ausearch_add_timestamp_item(au, "<=", end_time, 0, - AUSEARCH_RULE_AND)) { - fprintf(stderr, "Criteria error: end_time\n"); - return 1; - } - } - return 0; -} - -/* Extract the most common fields from virtualization-related records. */ -int extract_virt_fields(auparse_state_t *au, const char **p_uuid, - uid_t *p_uid, time_t *p_time, const char **p_name, - int *p_suc) -{ - const char *field; - auparse_first_record(au); - /* Order matters */ - if (p_uid) { - if (!auparse_find_field(au, field = "uid")) - goto error; - *p_uid = auparse_get_field_int(au); - } - if (p_name) { - if (!auparse_find_field(au, field = "vm")) - goto error; - *p_name = auparse_interpret_field(au); - } - if (p_uuid) { - if (!auparse_find_field(au, field = "uuid")) - goto error; - *p_uuid = auparse_get_field_str(au); - } - if (p_suc) { - const char *res = auparse_find_field(au, field = "res"); - if (res == NULL) - goto error; - *p_suc = (strcmp("success", res) == 0) ? 1 : 0; - } - if (p_time) { - *p_time = auparse_get_time(au); - } - return 0; - -error: - if (debug) { - fprintf(stderr, "Failed to get field \"%s\" for record " - "%ld.%03u:%lu\n", field ? field : "", - auparse_get_time(au), - auparse_get_milli(au), - auparse_get_serial(au)); - } - return 1; -} - -/* Return label and categories from a security context. */ -const char *get_seclevel(const char *seclabel) -{ - /* - * system_u:system_r:svirt_t:s0:c107,c434 - * \____ _____/ - * ' - * level + cat - */ - int c = 0; - for (;seclabel && *seclabel; seclabel++) { - if (*seclabel == ':') - c += 1; - if (c == 3) - return seclabel + 1; - } - return NULL; -} - -int add_proof(struct event *event, auparse_state_t *au) -{ - if (!proof_flag) - return 0; - - size_t i, proof_len = sizeof(event->proof)/sizeof(event->proof[0]); - for (i = 0; i < proof_len; i++) { - if (event->proof[i].time == 0) - break; - } - if (i == proof_len) { - if (debug) - fprintf(stderr, "Failed to add proof.\n"); - return 1; - } - - event->proof[i].time = auparse_get_time(au); - event->proof[i].milli = auparse_get_milli(au); - event->proof[i].serial = auparse_get_serial(au); - return 0; -} - -/* - * machine_id records are used to get the selinux context associated to a - * guest. - */ -int process_machine_id_event(auparse_state_t *au) -{ - uid_t uid; - time_t time; - const char *seclevel, *uuid, *name; - struct event *event; - int success; - - seclevel = get_seclevel(auparse_find_field(au, "vm-ctx")); - if (seclevel == NULL) { - if (debug) - fprintf(stderr, "Security context not found for " - "MACHINE_ID event.\n"); - } - - if (extract_virt_fields(au, &uuid, &uid, &time, &name, &success)) - return 0; - - event = event_alloc(); - if (event == NULL) - return 1; - event->type = ET_MACHINE_ID; - event->uuid = copy_str(uuid); - event->name = copy_str(name); - event->success = success; - event->seclevel = copy_str(seclevel); - event->uid = uid; - event->start = time; - add_proof(event, au); - if (list_append(events, event) == NULL) { - event_free(event); - return 1; - } - return 0; -} - -int add_start_guest_event(auparse_state_t *au) -{ - struct event *start; - uid_t uid; - time_t time; - const char *uuid, *name; - int success; - list_node_t *it; - - /* Just skip this record if it failed to get some of the fields */ - if (extract_virt_fields(au, &uuid, &uid, &time, &name, &success)) - return 0; - - /* On failure, loop backwards to update all the resources associated to - * the last session of this guest. When a machine_id or a stop event is - * found the loop can be broken because a machine_id is created at the - * beginning of a session and a stop event indicates a previous - * session. - */ - if (!success) { - for (it = events->tail; it; it = it->prev) { - struct event *event = it->data; - if (event->success && event->uuid && - strcmp(uuid, event->uuid) == 0) { - if (event->type == ET_STOP || - event->type == ET_MACHINE_ID) { - /* An old session found. */ - break; - } else if (event->type == ET_RES && - event->end == 0) { - event->end = time; - add_proof(event, au); - } - } - } - } - - start = event_alloc(); - if (start == NULL) - return 1; - start->type = ET_START; - start->uuid = copy_str(uuid); - start->name = copy_str(name); - start->success = success; - start->uid = uid; - start->start = time; - auparse_first_record(au); - if (auparse_find_field(au, "vm-pid")) - start->pid = auparse_get_field_int(au); - add_proof(start, au); - if (list_append(events, start) == NULL) { - event_free(start); - return 1; - } - return 0; -} - -int add_stop_guest_event(auparse_state_t *au) -{ - list_node_t *it; - struct event *stop, *start = NULL, *event = NULL; - uid_t uid; - time_t time; - const char *uuid, *name; - int success; - - /* Just skip this record if it failed to get some of the fields */ - if (extract_virt_fields(au, &uuid, &uid, &time, &name, &success)) - return 0; - - /* Loop backwards to find the last start event for the uuid and - * update all resource records related to that guest session. - */ - for (it = events->tail; it; it = it->prev) { - event = it->data; - if (event->success && event->uuid && - strcmp(uuid, event->uuid) == 0) { - if (event->type == ET_START) { - /* If an old session is found it's no longer - * necessary to update the resource records. - */ - if (event->end || start) - break; - /* This is the start event related to the - * current session. */ - start = event; - } else if (event->type == ET_STOP || - event->type == ET_MACHINE_ID) { - /* Old session found. */ - break; - } else if (event->type == ET_RES && event->end == 0) { - /* Update the resource assignments. */ - event->end = time; - add_proof(event, au); - } - } - } - if (start == NULL) { - if (debug) { - fprintf(stderr, "Couldn't find the correlated start " - "record to the stop event.\n"); - } - return 0; - } - - /* Create a new stop event */ - stop = event_alloc(); - if (stop == NULL) - return 1; - stop->type = ET_STOP; - stop->uuid = copy_str(uuid); - stop->name = copy_str(name); - stop->success = success; - stop->uid = uid; - stop->start = time; - auparse_first_record(au); - if (auparse_find_field(au, "vm-pid")) - stop->pid = auparse_get_field_int(au); - add_proof(stop, au); - if (list_append(events, stop) == NULL) { - event_free(stop); - return 1; - } - - /* Update the correlated start event. */ - if (success) { - start->end = time; - add_proof(start, au); - } - return 0; -} - -int process_control_event(auparse_state_t *au) -{ - const char *op; - - op = auparse_find_field(au, "op"); - if (op == NULL) { - if (debug) - fprintf(stderr, "Invalid op field.\n"); - return 0; - } - - if (strcmp("start", op) == 0) { - if (add_start_guest_event(au)) - return 1; - } else if (strcmp("stop", op) == 0) { - if (add_stop_guest_event(au)) - return 1; - } else if (debug) { - fprintf(stderr, "Unknown op: %s\n", op); - } - return 0; -} - -inline int is_resource(const char *res) -{ - if (res == NULL || - res[0] == '\0' || - strcmp("0", res) == 0 || - strcmp("?", res) == 0) - return 0; - return 1; -} - -int add_resource(auparse_state_t *au, const char *uuid, uid_t uid, time_t time, - const char *name, int success, const char *reason, - const char *res_type, const char *res) -{ - if (!is_resource(res)) - return 0; - - struct event *event = event_alloc(); - if (event == NULL) - return 1; - event->type = ET_RES; - event->uuid = copy_str(uuid); - event->name = copy_str(name); - event->success = success; - event->reason = copy_str(reason); - event->res_type = copy_str(res_type); - event->res = copy_str(res); - event->uid = uid; - event->start = time; - add_proof(event, au); - - /* Get cgroup specific fields. */ - if (strcmp("cgroup", res_type) == 0) { - event->cgroup_class = copy_str(auparse_find_field(au, "class")); - if (event->cgroup_class) { - const char *detail = NULL; - if (strcmp("path", event->cgroup_class) == 0) { - if (auparse_find_field(au, "path")) - detail = auparse_interpret_field(au); - } else if (strcmp("major", event->cgroup_class) == 0) { - detail = auparse_find_field(au, "category"); - } - event->cgroup_detail = copy_str(detail); - } - event->cgroup_acl = copy_str(auparse_find_field(au, "acl")); - } - - if (list_append(events, event) == NULL) { - event_free(event); - return 1; - } - return 0; -} - -int update_resource(auparse_state_t *au, const char *uuid, uid_t uid, - time_t time, const char *name, int success, const char *reason, - const char *res_type, const char *res) -{ - if (!is_resource(res) || !success) - return 0; - - list_node_t *it; - struct event *start = NULL; - - /* Find the last start event for the uuid */ - for (it = events->tail; it; it = it->prev) { - start = it->data; - if (start->type == ET_RES && - start->success && - start->uuid && - strcmp(uuid, start->uuid) == 0 && - strcmp(res_type, start->res_type) == 0 && - strcmp(res, start->res) == 0) - break; - } - if (it == NULL) { - if (debug) { - fprintf(stderr, "Couldn't find the correlated resource" - " record to update for %s.\n", res_type); - } - return 0; - } - - start->end = time; - add_proof(start, au); - return 0; -} - -int process_resource_event(auparse_state_t *au) -{ - uid_t uid; - time_t time; - const char *res_type, *uuid, *name; - char field[64]; - const char *reason; - int success; - - /* Just skip this record if it failed to get some of the fields */ - if (extract_virt_fields(au, &uuid, &uid, &time, &name, &success)) - return 0; - - /* Get the resource type */ - auparse_first_record(au); - res_type = auparse_find_field(au, "resrc"); - reason = auparse_find_field(au, "reason"); - if (res_type == NULL) { - if (debug) - fprintf(stderr, "Invalid resrc field.\n"); - return 0; - } - - /* Resource records with these types have old and new values. New - * values indicate resources assignments and are added to the event - * list. Old values are used to update the end time of a resource - * assignment. - */ - int rc = 0; - if (strcmp("disk", res_type) == 0 || - strcmp("vcpu", res_type) == 0 || - strcmp("mem", res_type) == 0 || - strcmp("rng", res_type) == 0 || - strcmp("net", res_type) == 0) { - const char *res = NULL; - /* Resource removed */ - snprintf(field, sizeof(field), "old-%s", res_type); - if(auparse_find_field(au, field)) - res = auparse_interpret_field(au); - if (res == NULL && debug) { - fprintf(stderr, "Failed to get %s field.\n", field); - } else { - rc += update_resource(au, uuid, uid, time, name, - success, reason, res_type, res); - } - - /* Resource added */ - res = NULL; - snprintf(field, sizeof(field), "new-%s", res_type); - if (auparse_find_field(au, field)) - res = auparse_interpret_field(au); - if (res == NULL && debug) { - fprintf(stderr, "Failed to get %s field.\n", field); - } else { - rc += add_resource(au, uuid, uid, time, name, success, - reason, res_type, res); - } - } else if (strcmp("cgroup", res_type) == 0) { - auparse_first_record(au); - const char *cgroup = NULL; - if (auparse_find_field(au, "cgroup")) - cgroup = auparse_interpret_field(au); - rc += add_resource(au, uuid, uid, time, name, success, reason, - res_type, cgroup); - } else if (debug) { - fprintf(stderr, "Found an unknown resource: %s.\n", - res_type); - } - return rc; -} - -/* Search for the last machine_id record with the given seclevel */ -struct event *get_machine_id_by_seclevel(const char *seclevel) -{ - struct event *machine_id = NULL; - list_node_t *it; - - for (it = events->tail; it; it = it->prev) { - struct event *event = it->data; - if (event->type == ET_MACHINE_ID && - event->seclevel != NULL && - strcmp(event->seclevel, seclevel) == 0) { - machine_id = event; - break; - } - } - - return machine_id; -} - -int process_avc_selinux_context(auparse_state_t *au, const char *context) -{ - const char *seclevel; - struct event *machine_id, *avc; - uid_t uid; - time_t time; - - seclevel = get_seclevel(auparse_find_field(au, context)); - if (seclevel == NULL) { - if (debug) { - fprintf(stderr, "Security context not found " - "for AVC event.\n"); - } - return 0; - } - - if (extract_virt_fields(au, NULL, &uid, &time, NULL, NULL)) - return 0; - - machine_id = get_machine_id_by_seclevel(seclevel); - if (machine_id == NULL) { - if (debug) { - fprintf(stderr, "Couldn't get the security " - "level from the AVC event.\n"); - } - return 0; - } - - avc = event_alloc(); - if (avc == NULL) - return 1; - avc->type = ET_AVC; - - /* Guest info */ - avc->uuid = copy_str(machine_id->uuid); - avc->name = copy_str(machine_id->name); - memcpy(avc->proof, machine_id->proof, sizeof(avc->proof)); - - /* AVC info */ - avc->start = time; - avc->uid = uid; - avc->seclevel = copy_str(seclevel); - auparse_first_record(au); - avc->avc_result = copy_str(auparse_find_field(au, "seresult")); - avc->avc_operation = copy_str(auparse_find_field(au, "seperms")); - if (auparse_find_field(au, "comm")) - avc->comm = copy_str(auparse_interpret_field(au)); - if (auparse_find_field(au, "name")) - avc->target = copy_str(auparse_interpret_field(au)); - - /* get the context related to the permission that was denied. */ - if (avc->avc_operation) { - const char *ctx = NULL; - if (strcmp("relabelfrom", avc->avc_operation) == 0) { - ctx = auparse_find_field(au, "scontext"); - } else if (strcmp("relabelto", avc->avc_operation) == 0) { - ctx = auparse_find_field(au, "tcontext"); - } - avc->context = copy_str(ctx); - } - - add_proof(avc, au); - if (list_append(events, avc) == NULL) { - event_free(avc); - return 1; - } - return 0; -} - -/* AVC records are correlated to guest through the selinux context. */ -int process_avc_selinux(auparse_state_t *au) -{ - const char **context; - const char *contexts[] = { "tcontext", "scontext", NULL }; - - for (context = contexts; context && *context; context++) { - if (process_avc_selinux_context(au, *context)) - return 1; - } - return 0; -} - -#ifdef WITH_APPARMOR -int process_avc_apparmor_source(auparse_state_t *au) -{ - uid_t uid = -1; - time_t time = 0; - struct event *avc; - const char *target; - - /* Get the target object. */ - if (auparse_find_field(au, "name") == NULL) { - if (debug) { - auparse_first_record(au); - fprintf(stderr, "Couldn't get the resource name from " - "the AVC record: %s\n", - auparse_get_record_text(au)); - } - return 0; - } - target = auparse_interpret_field(au); - - /* Loop backwards to find a guest session with the target object - * assigned to. */ - struct list_node_t *it; - struct event *res = NULL; - for (it = events->tail; it; it = it->prev) { - struct event *event = it->data; - if (event->success) { - if (event->type == ET_DOWN) { - /* It's just possible to find a matching guest - * session in the current host session. - */ - break; - } else if (event->type == ET_RES && - event->end == 0 && - event->res != NULL && - strcmp(target, event->res) == 0) { - res = event; - break; - } - } - } - - /* Check if a resource event was found. */ - if (res == NULL) { - if (debug) { - fprintf(stderr, "Target object not found for AVC " - "event.\n"); - } - return 0; - } - - if (extract_virt_fields(au, NULL, &uid, &time, NULL, NULL)) - return 0; - - avc = event_alloc(); - if (avc == NULL) - return 1; - avc->type = ET_AVC; - - /* Guest info */ - avc->uuid = copy_str(res->uuid); - avc->name = copy_str(res->name); - memcpy(avc->proof, res->proof, sizeof(avc->proof)); - - /* AVC info */ - avc->start = time; - avc->uid = uid; - auparse_first_record(au); - if (auparse_find_field(au, "apparmor")) { - int i; - avc->avc_result = copy_str(auparse_interpret_field(au)); - for (i = 0; avc->avc_result && avc->avc_result[i]; i++) { - avc->avc_result[i] = tolower(avc->avc_result[i]); - } - } - if (auparse_find_field(au, "operation")) - avc->avc_operation = copy_str(auparse_interpret_field(au)); - avc->target = copy_str(target); - if (auparse_find_field(au, "comm")) - avc->comm = copy_str(auparse_interpret_field(au)); - - add_proof(avc, au); - if (list_append(events, avc) == NULL) { - event_free(avc); - return 1; - } - return 0; -} - -int process_avc_apparmor_target(auparse_state_t *au) -{ - uid_t uid; - time_t time; - const char *profile; - struct event *avc; - - /* Get profile associated with the AVC record */ - if (auparse_find_field(au, "profile") == NULL) { - if (debug) { - auparse_first_record(au); - fprintf(stderr, "AppArmor profile not found for AVC " - "record: %s\n", - auparse_get_record_text(au)); - } - return 0; - } - profile = auparse_interpret_field(au); - - /* Break path to get just the basename */ - const char *basename = profile + strlen(profile); - while (basename != profile && *basename != '/') - basename--; - if (*basename == '/') - basename++; - - /* Check if it is an apparmor profile generated by libvirt and get the - * guest UUID from it */ - const char *prefix = "libvirt-"; - if (strncmp(prefix, basename, strlen(prefix)) != 0) { - if (debug) { - fprintf(stderr, "Found a profile which is not " - "generated by libvirt: %s\n", profile); - } - return 0; - } - - /* Try to find a valid guest session */ - const char *uuid = basename + strlen(prefix); - struct list_node_t *it; - struct event *machine_id = NULL; - for (it = events->tail; it; it = it->prev) { - struct event *event = it->data; - if (event->success) { - if (event->uuid != NULL && - strcmp(event->uuid, uuid) == 0) { - /* machine_id is used here instead of the start - * event because it is generated before any - * other event when a guest is started. So, - * it's possible to correlate AVC events that - * occurs during a guest start. - */ - if (event->type == ET_MACHINE_ID) { - machine_id = event; - break; - } else if (event->type == ET_STOP) { - break; - } - } else if (event->type == ET_DOWN) { - break; - } - } - } - if (machine_id == NULL) { - if (debug) { - fprintf(stderr, "Found an AVC record for an unknown " - "guest.\n"); - } - return 0; - } - - if (extract_virt_fields(au, NULL, &uid, &time, NULL, NULL)) - return 0; - - avc = event_alloc(); - if (avc == NULL) - return 1; - avc->type = ET_AVC; - - /* Guest info */ - avc->uuid = copy_str(machine_id->uuid); - avc->name = copy_str(machine_id->name); - memcpy(avc->proof, machine_id->proof, sizeof(avc->proof)); - - /* AVC info */ - avc->start = time; - avc->uid = uid; - auparse_first_record(au); - if (auparse_find_field(au, "apparmor")) { - int i; - avc->avc_result = copy_str(auparse_interpret_field(au)); - for (i = 0; avc->avc_result && avc->avc_result[i]; i++) { - avc->avc_result[i] = tolower(avc->avc_result[i]); - } - } - if (auparse_find_field(au, "operation")) - avc->avc_operation = copy_str(auparse_interpret_field(au)); - if (auparse_find_field(au, "name")) - avc->target = copy_str(auparse_interpret_field(au)); - if (auparse_find_field(au, "comm")) - avc->comm = copy_str(auparse_interpret_field(au)); - - add_proof(avc, au); - if (list_append(events, avc) == NULL) { - event_free(avc); - return 1; - } - return 0; -} - -/* AVC records are correlated to guest through the apparmor path name. */ -int process_avc_apparmor(auparse_state_t *au) -{ - if (process_avc_apparmor_target(au)) - return 1; - auparse_first_record(au); - return process_avc_apparmor_source(au); -} -#endif - -int process_avc(auparse_state_t *au) -{ - /* Check if it is a SELinux AVC record */ - if (auparse_find_field(au, "tcontext")) { - auparse_first_record(au); - return process_avc_selinux(au); - } - -#ifdef WITH_APPARMOR - /* Check if it is an AppArmor AVC record */ - auparse_first_record(au); - if (auparse_find_field(au, "apparmor")) { - auparse_first_record(au); - return process_avc_apparmor(au); - } -#endif - return 0; -} - -/* This function tries to correlate an anomaly record to a guest using the qemu - * pid or the selinux context. */ -int process_anom(auparse_state_t *au) -{ - uid_t uid; - time_t time; - pid_t pid = -1; - list_node_t *it; - struct event *anom, *start = NULL; - - /* An anomaly record is correlated to a guest by the process id */ - if (auparse_find_field(au, "pid")) { - pid = auparse_get_field_int(au); - } else { - if (debug) { - fprintf(stderr, "Found an anomaly record " - "without pid.\n"); - } - } - - /* Loop backwards to find a running guest with the same pid. */ - if (pid >= 0) { - for (it = events->tail; it; it = it->next) { - struct event *event = it->data; - if (event->pid == pid && event->success) { - if (event->type == ET_STOP) { - break; - } else if (event->type == ET_START) { - if (event->end == 0) - start = event; - break; - } - } - } - } - - /* Try to match using selinux context */ - if (start == NULL) { - const char *seclevel; - struct event *machine_id; - - seclevel = get_seclevel(auparse_find_field(au, "subj")); - if (seclevel == NULL) { - if (debug) { - auparse_first_record(au); - const char *text = auparse_get_record_text(au); - fprintf(stderr, "Security context not found " - "for anomaly event: %s\n", - text ? text : ""); - } - return 0; - } - machine_id = get_machine_id_by_seclevel(seclevel); - if (machine_id == NULL) { - if (debug) { - fprintf(stderr, "Couldn't get the security " - "level from the anomaly event.\n"); - } - return 0; - } - - for (it = events->tail; it; it = it->next) { - struct event *event = it->data; - if (event->success && machine_id->uuid && event->uuid && - strcmp(machine_id->uuid, event->uuid) == 0) { - if (event->type == ET_STOP) { - break; - } else if (event->type == ET_START) { - if (event->end == 0) - start = event; - break; - } - } - } - } - - if (start == NULL) { - if (debug) { - const char *text = auparse_get_record_text(au); - fprintf(stderr, "Guest not found for " - "anomaly record: %s.\n", - text ? text : ""); - } - return 0; - } - - if (extract_virt_fields(au, NULL, &uid, &time, NULL, NULL)) - return 0; - - anom = event_alloc(); - if (anom == NULL) - return 1; - anom->type = ET_ANOM; - anom->uuid = copy_str(start->uuid); - anom->name = copy_str(start->name); - anom->uid = uid; - anom->start = time; - anom->pid = pid; - memcpy(anom->proof, start->proof, sizeof(anom->proof)); - add_proof(anom, au); - if (list_append(events, anom) == NULL) { - event_free(anom); - return 1; - } - return 0; -} - -int process_shutdown(auparse_state_t *au) -{ - uid_t uid = -1; - time_t time = 0; - struct event *down; - list_node_t *it; - int success = 0; - - if (extract_virt_fields(au, NULL, &uid, &time, NULL, &success)) - return 0; - - for (it = events->tail; it; it = it->prev) { - struct event *event = it->data; - if (event->success) { - if (event->type == ET_START || event->type == ET_RES) { - if (event->end == 0) { - event->end = time; - add_proof(event, au); - } - } else if (event->type == ET_DOWN) { - break; - } - } - } - - down = event_alloc(); - if (down == NULL) - return 1; - down->type = ET_DOWN; - down->uid = uid; - down->start = time; - down->success = success; - add_proof(down, au); - if (list_append(events, down) == NULL) { - event_free(down); - return 1; - } - return 0; -} - -/* Convert record type to a string */ -const char *get_rec_type(struct event *e) -{ - static char buf[64]; - if (e == NULL) - return ""; - - switch (e->type) { - case ET_START: - return "start"; - case ET_STOP: - return "stop"; - case ET_RES: - return "res"; - case ET_AVC: - return "avc"; - case ET_ANOM: - return "anom"; - case ET_DOWN: - return "down"; - } - - snprintf(buf, sizeof(buf), "%d", e->type); - return buf; -} - -/* Convert uid to a string */ -const char *get_username(struct event *e) -{ - static char s[256]; - if (!e || (int)e->uid == -1) { - s[0] = '?'; - s[1] = '\0'; - } else { - struct passwd *passwd = getpwuid(e->uid); - if (passwd == NULL || passwd->pw_name == NULL) { - snprintf(s, sizeof(s), "%d", e->uid); - } else { - snprintf(s, sizeof(s), "%s", passwd->pw_name); - } - } - return s; -} - -/* Convert a time period to string */ -const char *get_time_period(struct event *event) -{ - size_t i = 0; - static char buf[128]; - - i += sprintf(buf + i, "%-16.16s", ctime(&event->start)); - if (event->end) { - time_t secs = event->end - event->start; - int mins, hours, days; - i += sprintf(buf + i, " - %-7.5s", ctime(&event->end) + 11); - mins = (secs / 60) % 60; - hours = (secs / 3600) % 24; - days = secs / 86400; - if (days) { - i += sprintf(buf + i, "(%d+%02d:%02d)", days, hours, - mins); - } else { - i += sprintf(buf + i, "(%02d:%02d)", hours, mins); - } - } else { - if (!event->success && - event->type != ET_AVC && - event->type != ET_ANOM) { - i += sprintf(buf + i, " - failed"); - } - } - return buf; -} - -void print_event(struct event *event) -{ - /* Auxiliary macro to convert NULL to "" */ - #define N(str) ((str) ? str : "") - - /* machine id records are used just to get information about - * the guests. */ - if (event->type == ET_MACHINE_ID) - return; - /* If "--all-events" is not given, only the start event is shown. */ - if (!all_events_flag && event->type != ET_START) - return; - /* The type of event is shown only when all records are shown */ - if (all_events_flag) - printf("%-5.5s ", get_rec_type(event)); - - /* Print common fields */ - printf("%-25.25s", N(event->name)); - if (uuid_flag) - printf("\t%-36.36s", N(event->uuid)); - printf("\t%-11.11s\t%-35.35s", get_username(event), - get_time_period(event)); - - /* Print type specific fields */ - if (event->type == ET_RES) { - printf("\t%-12.12s", N(event->res_type)); - printf("\t%-10.10s", N(event->reason)); - if (strcmp("cgroup", event->res_type) != 0) { - printf("\t%s", N(event->res)); - } else { - printf("\t%s\t%s\t%s", N(event->cgroup_class), - N(event->cgroup_acl), - N(event->cgroup_detail)); - } - } else if (event->type == ET_MACHINE_ID) { - printf("\t%s", N(event->seclevel)); - } else if (event->type == ET_AVC) { - printf("\t%-12.12s", N(event->avc_operation)); - printf("\t%-10.10s", N(event->avc_result)); - printf("\t%s\t%s\t%s", N(event->comm), N(event->target), - N(event->context)); - } - printf("\n"); - - /* Print proof */ - if (proof_flag) { - int first = 1; - int i, len = sizeof(event->proof)/sizeof(event->proof[0]); - printf(" Proof:"); - for (i = 0; i < len; i++) { - if (event->proof[i].time) { - printf("%s %ld.%03u:%lu", - (first) ? "" : ",", - event->proof[i].time, - event->proof[i].milli, - event->proof[i].serial); - first = 0; - } - } - printf("\n\n"); - } -} - -/* Print all events */ -void print_events(void) -{ - list_node_t *it; - for (it = events->head; it; it = it->next) { - struct event *event = it->data; - if (event) - print_event(event); - } -} - -/* Count and print summary */ -void print_summary(void) -{ - /* Summary numbers */ - time_t start_time = 0, end_time = 0; - long start = 0, stop = 0, res = 0, avc = 0, anom = 0, - shutdown = 0, failure = 0; - char start_buf[32], end_buf[32]; - - /* Calculate summary */ - list_node_t *it; - for (it = events->head; it; it = it->next) { - struct event *event = it->data; - if (event->success == 0 && - (event->type == ET_START || - event->type == ET_STOP || - event->type == ET_RES)) { - failure++; - } else { - switch (event->type) { - case ET_START: - start++; - break; - case ET_STOP: - stop++; - break; - case ET_RES: - res++; - break; - case ET_AVC: - avc++; - break; - case ET_ANOM: - anom++; - break; - case ET_DOWN: - shutdown++; - break; - } - } - - /* Calculate time range */ - if (event->start) { - if (start_time == 0 || event->start < start_time) { - start_time = event->start; - } - if (end_time == 0 || event->start > end_time) { - end_time = event->start; - } - } - if (event->end) { - if (start_time == 0 || event->end < start_time) { - start_time = event->end; - } - if (end_time == 0 || event->end > end_time) { - end_time = event->end; - } - } - - } - - if (start_time) - ctime_r(&start_time, start_buf); - else - strcpy(start_buf, "undef"); - if (end_time) - ctime_r(&end_time, end_buf); - else - strcpy(end_buf, "undef"); - - /* Print summary */ - printf("Range of time for report: %-.16s - %-.16s\n", - start_buf, end_buf); - printf("Number of guest starts: %ld\n", start); - printf("Number of guest stops: %ld\n", stop); - printf("Number of resource assignments: %ld\n", res); - printf("Number of related AVCs: %ld\n", avc); - printf("Number of related anomalies: %ld\n", anom); - printf("Number of host shutdowns: %ld\n", shutdown); - printf("Number of failed operations: %ld\n", failure); -} - -int main(int argc, char **argv) -{ - int rc = 0; - auparse_state_t *au = NULL; - - setlocale(LC_ALL, ""); - if (parse_args(argc, argv)) - goto error; - if (help_flag) { - usage(stdout); - goto exit; - } - - /* Initialize event list*/ - events = list_new((list_free_data_fn*) event_free); - if (events == NULL) - goto unexpected_error; - - /* Initialize auparse */ - au = init_auparse(); - if (au == NULL) - goto error; - if (create_search_criteria(au)) - goto error; - - while (ausearch_next_event(au) > 0) { - int err = 0; - - switch(auparse_get_type(au)) { - case AUDIT_VIRT_MACHINE_ID: - err = process_machine_id_event(au); - break; - case AUDIT_VIRT_CONTROL: - err = process_control_event(au); - break; - case AUDIT_VIRT_RESOURCE: - err = process_resource_event(au); - break; - case AUDIT_AVC: - err = process_avc(au); - break; - case AUDIT_FIRST_ANOM_MSG ... AUDIT_LAST_ANOM_MSG: - case AUDIT_FIRST_KERN_ANOM_MSG ... AUDIT_LAST_KERN_ANOM_MSG: - err = process_anom(au); - break; - case AUDIT_SYSTEM_SHUTDOWN: - err = process_shutdown(au); - break; - } - if (err) { - goto unexpected_error; - } - auparse_next_event(au); - } - - /* Show results */ - if (summary_flag) { - print_summary(); - } else { - print_events(); - } - - /* success */ - goto exit; - -unexpected_error: - fprintf(stderr, "Unexpected error\n"); -error: - rc = 1; -exit: - if (au) - auparse_destroy(au); - list_free(events); - if (debug) - fprintf(stdout, "Exit code: %d\n", rc); - return rc; -} - |