📄 chklastlog.c
字号:
/* Copyright (c) DFN-CERT, Univ. of Hamburg 1994 Univ. Hamburg, Dept. of Computer Science DFN-CERT Vogt-Koelln-Strasse 30 22527 Hamburg Germany 02/20/97 - Minimal changes for Linux/FreeBSD port. 02/25/97 - Another little bit change 12/26/98 - New Red Hat compatibility Nelson Murilo, nelson@pangeia.com.br 01/05/00 - Performance patches 09/07/00 - Ports for Solaris Andre Gustavo de Carvalho Albuquerque 12/15/00 - Add -f & -l options Nelson Murilo, nelson@pangeia.com.br 01/09/01 - Many fixes Nelson Murilo, nelson@pangeia.com.br 01/20/01 - More little fixes Nelson Murilo, nelson@pangeia.com.br 24/01/01 - Segfault in some systems fixed, Thanks for Manfred Bartz 02/06/01 - Beter system detection & fix bug in OBSD, Thanks for Rudolf Leitgeb 09/19/01 - Another Segfault in some systems fixed, Thanks for Andreas Tirok 06/26/02 - Fix problem with maximum uid number - Thanks for Gerard van Wageningen 07/02/02 - Minor fixes Nelson Murilo, nelson@pangeia.com.br*/#if defined(SOLARIS2) || defined(__linux__)#define HAVE_LASTLOG_H 1#else#undef HAVE_LASTLOG_H#endif#include <stdio.h>#ifdef __linux__#include <stdlib.h>#endif#include <sys/stat.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <pwd.h>#include <sys/types.h>#include <utmp.h>#if (HAVE_LASTLOG_H)#include <lastlog.h>#endif#include <sys/file.h>#ifdef SOLARIS2#include <fcntl.h>#endif#ifdef __FreeBSD__#define WTMP_FILENAME "/var/log/wtmp"#define LASTLOG_FILENAME "/var/log/lastlog"#endif#ifdef __OpenBSD__#define WTMP_FILENAME "/var/log/wtmp"#define LASTLOG_FILENAME "/var/log/lastlog"#endif#ifndef WTMP_FILENAME#define WTMP_FILENAME "/var/adm/wtmp"#endif#ifndef LASTLOG_FILENAME#define LASTLOG_FILENAME "/var/adm/lastlog"#endif#define TRUE 1L#define FALSE 0Llong total_wtmp_bytes_read=0;size_t wtmp_file_size;uid_t *uid;void read_status();struct s_localpwd { int numentries; uid_t *uid; char **uname;};#ifndef SOLARIS2int nonuser(struct utmp utmp_ent);#endifstruct s_localpwd *read_pwd();void free_results(struct s_localpwd *);uid_t *localgetpwnam(struct s_localpwd *, char *);int getslot(struct s_localpwd *, uid_t);#define MAX_ID 99999int main(int argc, char*argv[]) { int fh_wtmp; int fh_lastlog; struct lastlog lastlog_ent; struct utmp utmp_ent; long userid[MAX_ID]; long i, slot; int status = 0; long wtmp_bytes_read; struct stat wtmp_stat; struct s_localpwd *localpwd; uid_t *uid; char wtmpfile[128], lastlogfile[128]; memcpy(wtmpfile, WTMP_FILENAME, 127); memcpy(lastlogfile, LASTLOG_FILENAME, 127); while (--argc && ++argv) /* poor man getopt */ { if (!memcmp("-f", *argv, 2)) { if (!--argc) break; ++argv; memcpy(wtmpfile, *argv, 127); } else if (!memcmp("-l", *argv, 2)) { if (!--argc) break; ++argv; memcpy(lastlogfile, *argv, 127); } } signal(SIGALRM, read_status); alarm(5); for (i=0; i<MAX_ID; i++) userid[i]=FALSE; if ((fh_lastlog=open(lastlogfile,O_RDONLY)) < 0) { fprintf(stderr, "unable to open lastlog-file %s\n", lastlogfile); return(1); } if ((fh_wtmp=open(wtmpfile,O_RDONLY)) < 0) { fprintf(stderr, "unable to open wtmp-file %s\n", wtmpfile); close(fh_lastlog); return(2); } if (fstat(fh_wtmp,&wtmp_stat)) { perror("chklastlog::main: "); close(fh_lastlog); close(fh_wtmp); return(3); } wtmp_file_size = wtmp_stat.st_size; localpwd = read_pwd(); while ((wtmp_bytes_read = read (fh_wtmp, &utmp_ent, sizeof (struct utmp))) >0) { if (wtmp_bytes_read < sizeof(struct utmp)) { fprintf(stderr, "wtmp entry may be corrupted"); break; } total_wtmp_bytes_read+=wtmp_bytes_read; if ( !nonuser(utmp_ent) && strncmp(utmp_ent.ut_line, "ftp", 3) && (uid=localgetpwnam(localpwd,utmp_ent.ut_name)) != NULL ) { if (*uid > MAX_ID) { fprintf(stderr, "MAX_ID is %ld and current uid is %ld, please check\n\r", MAX_ID, *uid ); exit (1); } if (!userid[*uid]) { lseek(fh_lastlog, (long)*uid * sizeof (struct lastlog), 0); if ((wtmp_bytes_read = read(fh_lastlog, &lastlog_ent, sizeof (struct lastlog))) > 0) { if (wtmp_bytes_read < sizeof(struct lastlog)) { fprintf(stderr, "lastlog entry may be corrupted"); break; } if (lastlog_ent.ll_time == 0) { if (-1 != (slot = getslot(localpwd, *uid))) printf("user %s deleted or never logged from lastlog!\n", NULL != localpwd->uname[slot] ? (char*)localpwd->uname[slot] : "(null)"); else printf("deleted user uid(%d) not in passwd\n", *uid); ++status; } userid[*uid]=TRUE; } } } }#if 0 printf("\n");#endif free_results(localpwd); close(fh_wtmp); close(fh_lastlog); return(status);}#ifndef SOLARIS2/* minimal funcionality of nonuser() */int nonuser(struct utmp utmp_ent){ return (!memcmp(utmp_ent.ut_name, "shutdown", sizeof ("shutdown")));}#endifvoid read_status() { double remaining_time; static long last_total_bytes_read=0; int diff; diff = total_wtmp_bytes_read-last_total_bytes_read; if (diff == 0) diff = 1; remaining_time=(wtmp_file_size-total_wtmp_bytes_read)*5/(diff); last_total_bytes_read=total_wtmp_bytes_read; printf("Remaining time: %6.2f seconds\n", remaining_time);/* signal(SIGALRM,read_status); alarm(5);*/}struct s_localpwd *read_pwd() { struct passwd *pwdent; int numentries=0,i=0; struct s_localpwd *localpwd; setpwent(); while ((pwdent = getpwent())) { numentries++; } endpwent(); localpwd = (struct s_localpwd *)malloc((size_t)sizeof(struct s_localpwd)); localpwd->numentries=numentries; localpwd->uid = (uid_t *)malloc((size_t)numentries*sizeof(uid_t)); localpwd->uname = (char **)malloc((size_t)numentries*sizeof(char *)); for (i=0;i<numentries;i++) { localpwd->uname[i] = (char *)malloc((size_t)30*sizeof(char)); } i=0; setpwent(); while ((pwdent = getpwent()) && (i<numentries)) { localpwd->uid[i]=pwdent->pw_uid; memcpy(localpwd->uname[i],pwdent->pw_name,(strlen(pwdent->pw_name)>29)?29:strlen(pwdent->pw_name)+1); i++; } endpwent(); return(localpwd);}void free_results(struct s_localpwd *localpwd) { int i; free(localpwd->uid); for (i=0;i<(localpwd->numentries);i++) { free(localpwd->uname[i]); } free(localpwd->uname); free(localpwd);}uid_t *localgetpwnam(struct s_localpwd *localpwd, char *username) { int i; size_t len; for (i=0; i<(localpwd->numentries);i++) { len = (strlen(username)>29)?30:strlen(username)+1; if (!memcmp(username,localpwd->uname[i],len)) { return &(localpwd->uid[i]); } } return NULL;}int getslot(struct s_localpwd *localpwd, uid_t uid){ int i; for (i=0; i<(localpwd->numentries);i++) { if (localpwd->uid[i] == uid) return i; } return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -