"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