Everhart,Glenn From: Ryan [warf@GOODNET.COM] Sent: Sunday, April 19, 1998 7:18 AM To: BUGTRAQ@NETSPACE.ORG Subject: lastx.c v2.0 Here's version 2.0 of Lastx.c. There are 4 files here. 1. README.TXT 2. Makefile 3. lastx.c 4. lastx.h just take all files and stick them into one directory. type 'make' to compile it, type 'make ; make install ; make clean' to make it, install it, and clean it. =) It installs to /usr/local/bin/lastx ===== 1st file - README.TXT ============================= lastx v2.0 By Ryan Wyler Package Includes: README.TXT This file Makefile Standard Makefile lastx.c Main C file for lastx lastx.h Header File Authors Notes: I origionally wrote lastx v1.0, but it was written very fast and very poor. Others (which knew C much better than I) ripped my code apart, or actually threw it completely away, and basicly re-wrote lastx. Purpose: There have been many times when trying to track down a specific login useing the 'last' command in solaris and have the users hostname/IP address cut off. The wtmp file does not retain the whole IP address. Using this utility (lastx) it reads the wtmpx file and gives the whole hostname/IP adresses. Platforms: Any Solaris box that uses the /var/adm/log/wtmpx. Tested myself on Solaris 2.5.1 (Sparc). Installation Notes: Very Easy. Run 'make; make install; make clean' It will install the lastx binary to the /usr/local/bin directory with owner of bin and group bin with permissions of 555 so anyone can use it. I personally don't want users to access that, so I changed my permissions on it to 550, owned by root, gid root. Any Bugs/Questions/Comments/Patches/Ideas, Give me a holler: Ryan Wyler ===== END OF README.TXT ============================= ===== 2nd file - Makefile ============================= CC = gcc RM = /bin/rm INSTALL = /usr/sbin/install CFLAGS = -ggdb -O2 -Wall SRC = lastx.c OBJ = lastx.o lastx: $(OBJ) $(CC) $(CFLAGS) -o $@ $? $(OBJ): $(SRC) $(CC) -c $? -o $@ install: lastx $(RM) -f /usr/local/bin/$? $(INSTALL) -s -c /usr/local/bin -m 555 -u bin -g bin $? clean: $(RM) -f *.o core lastx ===== END OF Makefile ============================= ===== 3rd file - lastx.c ============================= /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Lastx.c v2.0 By Ryan Wyler */ /* */ /* Discription: Solaris wtmpx 'last logins' viewer */ /* */ /* This version was completely re-written from lastx.c v1.0 */ /* It was re-written by a friend who decides to remain annon */ /* */ /* Changes: In this version, you can read in different files */ /* by placing a -f in the command line. */ /* Also, opens /var/adm/log/wtmpx with O_RDONLY instead of */ /* O_RDWR, I got like 200 e-mails about that one.. :) */ /* */ /* Any questions, comments, or requests for re-posts email me */ /* */ /* Ryan Wyler */ /* ryanw@goodnet.com */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include "lastx.h" static int f; static char *Argv0, *User; int main (int argc, char **argv) { register int opt; struct utmpx utmp_ent; Argv0 = strrchr (*argv, '/'); if (Argv0) Argv0++; else Argv0 = *argv; opterr = 0; while ((opt = getopt (argc, argv, "hdf:")) != EOF) { switch (opt) { case 'f': if ((f = open (optarg, O_RDONLY)) < 0) { (void) fprintf (stderr, "open: %s: %s\n", optarg, strerror(errno)); exit(-1); /* NOTREACHED */ } break; case 'h': default : print_version(); usage(); exit (-1); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc > 0) User = strdup(*argv); if (!f) if ((f = open (_PATH_WTMP, O_RDONLY)) < 0) { perror(_PATH_WTMP); exit(-1); } setvbuf (stdout, NULL, _IONBF, 0); dup2 (1, 2); print_header (); while (read_tmp_entry (f, &utmp_ent)) if (check_utmp (&utmp_ent)) pr_out (&utmp_ent); free (User); exit (0); } static void usage (void) { printf("Usage: %s [ -hv ] [ -f file ] user\n", Argv0); printf("Options:\n -h Help\n -f Specify Other wtmpx file to use\n"); return; } static void print_header (void) { printf("Username IP/Hostname Date\n"); } static int read_tmp_entry (int fd, struct utmpx *utp) { register int rv; rv = read (fd, (void*) utp, sizeof (*utp)); if (rv < 1 || rv != sizeof (*utp)) { (void) fprintf (stderr, "read: %s\n", rv ? strerror(errno) : "EOF"); return 0; } return rv; } inline static void pr_out (struct utmpx *utp) { printf ("%-8.8s %-25.256s %-s\n", utp->ut_user, utp->ut_host, tv_time(&utp->ut_tv)); } static char *tv_time (struct timeval *tp) { static char *ct, *p; if (!ct) ct = (char *)calloc(1, 25); p = ctime(&tp->tv_sec); strncpy (ct, p, 24); ct[25] = 0; return (ct); } static int check_utmp (struct utmpx *utp) { return (utp->ut_type == USER_PROCESS && (!User || !strcmp(User, utp->ut_user))); } static void print_version(void) { printf("lastx v2.0 - Ryan Wyler \n\n", Argv0); return; } ===== END OF lastx.c ============================= ===== 4th file - lastx.h ============================= #ifndef LASTX_H #define LASTX_H #if defined(__STDC__) # define _PROTO_(p) p #else # define _PROTO_(p) #endif #if !defined(_PATH_WTMP) # define _PATH_WTMP "/var/adm/wtmpx" #endif #if !defined (_PATH_UTMP) # define _PATH_UTMP "/var/adm/utmpx" #endif extern char *optarg; extern int optind, opterr; inline static void pr_out _PROTO_((struct utmpx *)); static void usage _PROTO_((void)), print_header _PROTO_((void)), print_version _PROTO_((void)); static int read_tmp_entry _PROTO_((int, struct utmpx *)), check_utmp _PROTO_((struct utmpx *)); static char *tv_time _PROTO_((struct timeval *)); #endif /* LASTX_H */ ===== END OF lastx.h ============================= ____ | _ \ _ _ __ _ _ __ | |_) | | | |/ _` | '_ \ | _ <| |_| | (_| | | | | |_| \_\\__, |\__,_|_| |_| |___/ GoodNet System Administration warf@goodnet.com