"Fossies" - the Fresh Open Source Software Archive 
Member "chkrootkit-0.57/chklastlog.c" (16 Jun 2022, 7853 Bytes) of package /linux/misc/chkrootkit-0.57.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "chklastlog.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 Copyright (c) DFN-CERT, Univ. of Hamburg 1994
3
4 Univ. Hamburg, Dept. of Computer Science
5 DFN-CERT
6 Vogt-Koelln-Strasse 30
7 22527 Hamburg
8 Germany
9
10 02/20/97 - Minimal changes for Linux/FreeBSD port.
11 02/25/97 - Another little bit change
12 12/26/98 - New Red Hat compatibility
13 Nelson Murilo, nelson@pangeia.com.br
14 01/05/00 - Performance patches
15 09/07/00 - Ports for Solaris
16 Andre Gustavo de Carvalho Albuquerque
17 12/15/00 - Add -f & -l options
18 Nelson Murilo, nelson@pangeia.com.br
19 01/09/01 - Many fixes
20 Nelson Murilo, nelson@pangeia.com.br
21 01/20/01 - More little fixes
22 Nelson Murilo, nelson@pangeia.com.br
23 24/01/01 - Segfault in some systems fixed, Thanks to Manfred Bartz
24 02/06/01 - Beter system detection & fix bug in OBSD, Thanks to Rudolf Leitgeb
25 09/19/01 - Another Segfault in some systems fixed, Thanks to Andreas Tirok
26 06/26/02 - Fix problem with maximum uid number - Thanks to Gerard van Wageningen
27 07/02/02 - Minor fixes - Nelson Murilo, nelson@pangeia.com.br
28 05/05/14 - Minor fixes - Klaus Steding-jessen
29 */
30
31 #if defined(SOLARIS2) || defined(__linux__)
32 #define HAVE_LASTLOG_H 1
33 #else
34 #undef HAVE_LASTLOG_H
35 #endif
36 #if __FreeBSD__ > 9
37 int main () { return 0; }
38 #else
39 #include <stdio.h>
40 #ifdef __linux__
41 #include <stdlib.h>
42 #endif
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <string.h>
46 #include <signal.h>
47 #include <pwd.h>
48 #include <sys/types.h>
49 #include <utmp.h>
50 #if (HAVE_LASTLOG_H)
51 #include <lastlog.h>
52 #endif
53 #include <sys/file.h>
54 #ifdef SOLARIS2
55 #include <fcntl.h>
56 #endif
57
58 #ifdef __FreeBSD__
59 #define WTMP_FILENAME "/var/log/wtmp"
60 #define LASTLOG_FILENAME "/var/log/lastlog"
61 #endif
62 #ifdef __OpenBSD__
63 #include <stdlib.h>
64 #define WTMP_FILENAME "/var/log/wtmp"
65 #define LASTLOG_FILENAME "/var/log/lastlog"
66 #endif
67 #ifndef WTMP_FILENAME
68 #define WTMP_FILENAME "/var/adm/wtmp"
69 #endif
70 #ifndef LASTLOG_FILENAME
71 #define LASTLOG_FILENAME "/var/adm/lastlog"
72 #endif
73
74 #define TRUE 1L
75 #define FALSE 0L
76
77 long total_wtmp_bytes_read=0;
78 size_t wtmp_file_size;
79 uid_t *uid;
80 void read_status();
81
82 struct s_localpwd {
83 int numentries;
84 uid_t *uid;
85 char **uname;
86 };
87
88 #ifndef SOLARIS2
89 int nonuser(struct utmp utmp_ent);
90 #endif
91 struct s_localpwd *read_pwd();
92 void free_results(struct s_localpwd *);
93 uid_t *localgetpwnam(struct s_localpwd *, char *);
94 int getslot(struct s_localpwd *, uid_t);
95
96 #define MAX_ID 99999
97
98 int main(int argc, char*argv[]) {
99 int fh_wtmp;
100 int fh_lastlog;
101 struct lastlog lastlog_ent;
102 struct utmp utmp_ent;
103 long userid[MAX_ID];
104 long i, slot;
105 int status = 0;
106 long wtmp_bytes_read;
107 struct stat wtmp_stat;
108 struct s_localpwd *localpwd;
109 uid_t *uid;
110 char wtmpfile[128], lastlogfile[128];
111
112 memcpy(wtmpfile, WTMP_FILENAME, 127);
113 memcpy(lastlogfile, LASTLOG_FILENAME, 127);
114
115 while (--argc && ++argv) /* poor man getopt */
116 {
117 if (!memcmp("-f", *argv, 2))
118 {
119 if (!--argc)
120 break;
121 ++argv;
122 memcpy(wtmpfile, *argv, 127);
123 }
124 else if (!memcmp("-l", *argv, 2))
125 {
126 if (!--argc)
127 break;
128 ++argv;
129 memcpy(lastlogfile, *argv, 127);
130 }
131 }
132
133 signal(SIGALRM, read_status);
134 alarm(5);
135 for (i=0; i<MAX_ID; i++)
136 userid[i]=FALSE;
137
138 if ((fh_lastlog=open(lastlogfile,O_RDONLY)) < 0) {
139 fprintf(stderr, "unable to open lastlog-file %s\n", lastlogfile);
140 return(1);
141 }
142
143 if ((fh_wtmp=open(wtmpfile,O_RDONLY)) < 0) {
144 fprintf(stderr, "unable to open wtmp-file %s\n", wtmpfile);
145 close(fh_lastlog);
146 return(2);
147 }
148 if (fstat(fh_wtmp,&wtmp_stat)) {
149 perror("chklastlog::main: ");
150 close(fh_lastlog);
151 close(fh_wtmp);
152 return(3);
153 }
154 wtmp_file_size = wtmp_stat.st_size;
155
156 localpwd = read_pwd();
157
158 while ((wtmp_bytes_read = read (fh_wtmp, &utmp_ent, sizeof (struct utmp))) >0) {
159 if (wtmp_bytes_read < sizeof(struct utmp))
160 {
161 fprintf(stderr, "wtmp entry may be corrupted");
162 break;
163 }
164 total_wtmp_bytes_read+=wtmp_bytes_read;
165 if ( !nonuser(utmp_ent) && strncmp(utmp_ent.ut_line, "ftp", 3) &&
166 (uid=localgetpwnam(localpwd,utmp_ent.ut_name)) != NULL )
167 {
168 if (*uid > MAX_ID)
169 {
170 fprintf(stderr, "MAX_ID is %u and current uid is %u, please check\n\r", MAX_ID, *uid );
171 exit (1);
172
173 }
174 if (!userid[*uid])
175 {
176 lseek(fh_lastlog, (long)*uid * sizeof (struct lastlog), 0);
177 if ((wtmp_bytes_read = read(fh_lastlog, &lastlog_ent, sizeof (struct lastlog))) > 0)
178 {
179 if (wtmp_bytes_read < sizeof(struct lastlog))
180 {
181 fprintf(stderr, "lastlog entry may be corrupted");
182 break;
183 }
184 if (lastlog_ent.ll_time == 0)
185 {
186 if (-1 != (slot = getslot(localpwd, *uid)))
187 printf("user %s deleted or never logged from lastlog!\n",
188 NULL != localpwd->uname[slot] ?
189 (char*)localpwd->uname[slot] : "(null)");
190 else
191 printf("deleted user uid(%d) not in passwd\n", *uid);
192 ++status;
193 }
194 userid[*uid]=TRUE;
195 }
196 }
197 }
198 }
199 #if 0
200 printf("\n");
201 #endif
202 free_results(localpwd);
203 close(fh_wtmp);
204 close(fh_lastlog);
205 return(status);
206 }
207
208 #ifndef SOLARIS2
209 /* minimal funcionality of nonuser() */
210 int nonuser(struct utmp utmp_ent)
211 {
212 return (!memcmp(utmp_ent.ut_name, "shutdown", sizeof ("shutdown")));
213 }
214 #endif
215
216 void read_status() {
217 double remaining_time;
218 static long last_total_bytes_read=0;
219 int diff;
220
221 diff = total_wtmp_bytes_read-last_total_bytes_read;
222 if (diff == 0) diff = 1;
223 remaining_time=(wtmp_file_size-total_wtmp_bytes_read)*5/(diff);
224 last_total_bytes_read=total_wtmp_bytes_read;
225
226 printf("Remaining time: %6.2f seconds\n", remaining_time);
227 /*
228 signal(SIGALRM,read_status);
229
230 alarm(5);
231 */
232 }
233
234 struct s_localpwd *read_pwd() {
235 struct passwd *pwdent;
236 int numentries=0,i=0;
237 struct s_localpwd *localpwd;
238
239 setpwent();
240 while ((pwdent = getpwent())) {
241 numentries++;
242 }
243 endpwent();
244 localpwd = (struct s_localpwd *)malloc((size_t)sizeof(struct s_localpwd));
245 localpwd->numentries=numentries;
246 localpwd->uid = (uid_t *)malloc((size_t)numentries*sizeof(uid_t));
247 localpwd->uname = (char **)malloc((size_t)numentries*sizeof(char *));
248 for (i=0;i<numentries;i++) {
249 localpwd->uname[i] = (char *)malloc((size_t)30*sizeof(char));
250 }
251 i=0;
252 setpwent();
253 while ((pwdent = getpwent()) && (i<numentries)) {
254 localpwd->uid[i]=pwdent->pw_uid;
255 memcpy(localpwd->uname[i],pwdent->pw_name,(strlen(pwdent->pw_name)>29)?29:strlen(pwdent->pw_name)+1);
256 i++;
257 }
258 endpwent();
259 return(localpwd);
260 }
261
262 void free_results(struct s_localpwd *localpwd) {
263 int i;
264 free(localpwd->uid);
265 for (i=0;i<(localpwd->numentries);i++) {
266 free(localpwd->uname[i]);
267 }
268 free(localpwd->uname);
269 free(localpwd);
270 }
271
272 uid_t *localgetpwnam(struct s_localpwd *localpwd, char *username) {
273 int i;
274 size_t len;
275
276 for (i=0; i<(localpwd->numentries);i++) {
277 len = (strlen(username)>29)?30:strlen(username)+1;
278 if (!memcmp(username,localpwd->uname[i],len)) {
279 return &(localpwd->uid[i]);
280 }
281 }
282 return NULL;
283 }
284
285 int getslot(struct s_localpwd *localpwd, uid_t uid)
286 {
287 int i;
288
289 for (i=0; i<(localpwd->numentries);i++)
290 {
291 if (localpwd->uid[i] == uid)
292 return i;
293 }
294 return -1;
295 }
296 #endif