diff options
Diffstat (limited to 'framework/src/audit/tools/aulastlog')
-rw-r--r-- | framework/src/audit/tools/aulastlog/Makefile.am | 34 | ||||
-rw-r--r-- | framework/src/audit/tools/aulastlog/aulastlog-llist.c | 148 | ||||
-rw-r--r-- | framework/src/audit/tools/aulastlog/aulastlog-llist.h | 65 | ||||
-rw-r--r-- | framework/src/audit/tools/aulastlog/aulastlog.8 | 24 | ||||
-rw-r--r-- | framework/src/audit/tools/aulastlog/aulastlog.c | 169 |
5 files changed, 440 insertions, 0 deletions
diff --git a/framework/src/audit/tools/aulastlog/Makefile.am b/framework/src/audit/tools/aulastlog/Makefile.am new file mode 100644 index 00000000..5c2403a9 --- /dev/null +++ b/framework/src/audit/tools/aulastlog/Makefile.am @@ -0,0 +1,34 @@ +# 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 new file mode 100644 index 00000000..25242b00 --- /dev/null +++ b/framework/src/audit/tools/aulastlog/aulastlog-llist.c @@ -0,0 +1,148 @@ +/* +* 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 new file mode 100644 index 00000000..ea965425 --- /dev/null +++ b/framework/src/audit/tools/aulastlog/aulastlog-llist.h @@ -0,0 +1,65 @@ +/* +* 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 new file mode 100644 index 00000000..b8b44c4f --- /dev/null +++ b/framework/src/audit/tools/aulastlog/aulastlog.8 @@ -0,0 +1,24 @@ +.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 new file mode 100644 index 00000000..c51b1efb --- /dev/null +++ b/framework/src/audit/tools/aulastlog/aulastlog.c @@ -0,0 +1,169 @@ +/* + * 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; +} + |