/*
   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
*/


#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <utmp.h>
#if (HAVE_LASTLOG_H)
#include <lastlog.h>
#endif
#include <sys/file.h>

#ifdef __FreeBSD__
#define WTMP_FILENAME "/var/log/wtmp"
#else
#ifndef WTMP_FILENAME 
#define WTMP_FILENAME "/var/adm/wtmp"
#endif
#endif

#ifdef __FreeBSD__
#define LASTLOG_FILENAME "/var/log/lastlog"
#else
#ifndef LASTLOG_FILENAME
#define LASTLOG_FILENAME "/var/adm/lastlog"
#endif
#endif

#define TRUE 1
#define FALSE 0


int main() {
	int		fh_wtmp;
	int		fh_lastlog;
	struct lastlog	lastlog_ent;
	struct utmp	utmp_ent;
	struct passwd	*pw_ent;
	int		userid[65535];
	int		i;
	int		status = 0;

	for (i=0; i<65535; i++)
		userid[i]=FALSE;

	if ((fh_lastlog=open(LASTLOG_FILENAME,O_RDONLY)) < 0) {
		fprintf(stderr, "unable to open lastlog-file %s\n", LASTLOG_FILENAME);
		return(1);
	}

	if ((fh_wtmp=open(WTMP_FILENAME,O_RDONLY)) < 0) {
		fprintf(stderr, "unable to open wtmp-file %s\n", WTMP_FILENAME);
		close(fh_lastlog);
		return(2);
	}

	while (read (fh_wtmp, &utmp_ent, sizeof (struct utmp)) > 0)
	    if ( !nonuser(utmp_ent) && strncmp(utmp_ent.ut_line, "ftp", 3) &&
		 (pw_ent=getpwnam(utmp_ent.ut_name)) != NULL )
		if ( userid[pw_ent->pw_uid] == FALSE ) {
		    lseek(fh_lastlog, (long)pw_ent->pw_uid * sizeof (struct lastlog), 0);
		    if (read(fh_lastlog, &lastlog_ent, sizeof (struct lastlog)) > 0)
			if (lastlog_ent.ll_time == 0)
                        {
			    printf("user %s deleted or never loged from lastlog!\n", pw_ent->pw_name);
                            ++status;
                        }
		    userid[pw_ent->pw_uid]=TRUE;
		}
	close(fh_wtmp);
	close(fh_lastlog);
	return(status);
}

/* minimal funcionality of nonuser() */
nonuser(struct utmp utmp_ent)
{
   return (!memcmp(utmp_ent.ut_name, "shutdown", sizeof ("shutdown")));
}
