Imported Upstream version 2.4.3
[platform/upstream/audit.git] / tools / aulastlog / aulastlog.c
1 /*
2  * aulastlog.c - A lastlog program based on audit logs 
3  * Copyright (c) 2008-2009,2011 Red Hat Inc., Durham, North Carolina.
4  * All Rights Reserved.
5  *
6  * This software may be freely redistributed and/or modified under the
7  * terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2, or (at your option) any
9  * later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; see the file COPYING. If not, write to the
18  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * Authors:
21  *   Steve Grubb <sgrubb@redhat.com>
22  */
23
24 #include <stdio.h>
25 #include <locale.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <pwd.h>
29 #include "auparse.h"
30 #include "aulastlog-llist.h"
31
32 void usage(void)
33 {
34         fprintf(stderr, "usage: aulastlog [--stdin] [--user name]\n");
35 }
36
37 int main(int argc, char *argv[])
38 {
39         int i, use_stdin = 0;
40         char *user = NULL;
41         struct passwd *p;
42         auparse_state_t *au;
43         llist l;
44
45         setlocale (LC_ALL, "");
46         for (i=1; i<argc; i++) {
47                 if ((strcmp(argv[i], "--user") == 0) || 
48                                 (strcmp(argv[i], "-u") == 0)) {
49                         i++;
50                         if (i<argc)
51                                 user = argv[i];
52                         else {
53                                 usage();
54                                 return 1;
55                         }
56                 } else if (strcmp(argv[i], "--stdin") == 0) {
57                         use_stdin = 1;
58                 } else {
59                         usage();
60                         return 1;
61                 }
62         }
63
64         list_create(&l);
65
66         // Stuff linked lists with all users 
67         while ((p = getpwent()) != NULL) {
68                 lnode n;
69
70                 n.sec = 0;
71                 n.uid = p->pw_uid;
72                 n.name = p->pw_name;
73                 n.host = NULL;
74                 n.term = NULL;
75                 if (user == NULL)
76                         list_append(&l, &n);
77                 else if (strcmp(user, p->pw_name) == 0)
78                         list_append(&l, &n);
79         }
80         endpwent();
81
82         if (user && list_get_cnt(&l) == 0) {
83                 printf("Unknown User: %s\n", user);
84                 return 1;
85         }
86
87         // Search for successful user logins
88         if (use_stdin)
89                 au = auparse_init(AUSOURCE_FILE_POINTER, stdin);
90         else
91                 au = auparse_init(AUSOURCE_LOGS, NULL);
92         if (au == NULL) {
93                 printf("Error - %s\n", strerror(errno));
94                 goto error_exit_1;
95         }
96         if (ausearch_add_item(au, "type", "=", "USER_LOGIN",
97                                                  AUSEARCH_RULE_CLEAR)){
98                 printf("ausearch_add_item error - %s\n", strerror(errno));
99                 goto error_exit_2;
100         }
101         if (ausearch_add_item(au, "res", "=", "success",
102                                                  AUSEARCH_RULE_AND)){
103                 printf("ausearch_add_item error - %s\n", strerror(errno));
104                 goto error_exit_2;
105         }
106         if (ausearch_set_stop(au, AUSEARCH_STOP_RECORD)){
107                 printf("ausearch_set_stop error - %s\n", strerror(errno));
108                 goto error_exit_2;
109         }
110
111         // Now scan the logs and append events
112         while (ausearch_next_event(au) > 0) {
113                 const au_event_t *e = auparse_get_timestamp(au);
114                 if (auparse_find_field(au, "auid")) {
115                         uid_t u = auparse_get_field_int(au);
116                         list_first(&l);
117                         if (list_find_uid(&l, u)) {
118                                 const char *str;
119
120                                 list_update_login(&l, e->sec);
121                                 str = auparse_find_field(au, "hostname");
122                                 if (str) 
123                                         list_update_host(&l, str);
124                                 str = auparse_find_field(au, "terminal");
125                                 if (str)
126                                         list_update_term(&l, str);
127                         }
128                 }
129                 if (auparse_next_event(au) < 0)
130                         break;
131         }
132         auparse_destroy(au);
133
134         // Now output the report
135         printf( "Username         Port         From"
136                 "                       Latest\n");
137         list_first(&l);
138         do {
139                 char tmp[48];
140                 const char *c, *h, *t;
141                 lnode *cur = list_get_cur(&l);
142                 if (cur->sec == 0)
143                         c = "**Never logged in**";
144                 else {
145                         struct tm *btm;
146
147                         btm = localtime(&cur->sec);
148                         strftime(tmp, sizeof(tmp), "%x %T", btm);
149                         c = tmp;
150                 }
151                 h = cur->host;
152                 if (h == NULL)
153                         h = "";
154                 t = cur->term;
155                 if (t == NULL)
156                         t = "";
157                 printf("%-16s %-12.12s %-26.26s %s\n", cur->name, t, h, c);
158         } while (list_next(&l));
159         
160         list_clear(&l);
161         return 0;
162
163 error_exit_2:
164         auparse_destroy(au);
165 error_exit_1:
166         list_clear(&l);
167         return 1;
168 }
169