Friday, September 02, 2005

last login

The third (preferred) method is to build or acquire a tool that will
read and interpret the contents of the wtmpx file and display login
records along with the year in which each login occurred. For example,
you could locate source code for the last command and modify it to
display the year along with the other date information. Alternately,
you could download a copy of Ed Cashin's utxreader.c, compile the code
on your system and produce output such as these two entries:

The date/time information in these records could benefit from a little
reformatting, but it's fairly clear. The string "20030317-133121"
refers to 03/17/2003 at 13:31:21. Notice that the older records appear
first, unlike the last command's output which is reversed so that the
more relevant entries appear first.

To track down a particular user's logins using utxreader, you would
have to pipe the program's output to a grep command like this:

# ./utxreader /var/adm/wtmpx | grep sbob

To look at his most recent logins, you could also pipe the output to
tail: # ./utxreader /var/adm/wtmpx | grep sbob | tail -3

Source for utxreader.c is available at

Another option is to build a script in Perl. This could be a very
tricky process. After all, information contained in wtmpx records is
not stored in string format. Fortunately, however, details on how to
read and parse this file using Perl are included in O'Reilly's "Perl
for System Administration" (David N. Blank-Edelman, 2000). In fact, a
sample chapter from this excellent book (also referred to as "the
otter book") is available at this URL:

"Stealing" Great Perl Code

The sample chapter from the otter book just happens to include code
for extracting information from the wtmpx file and displaying system
reboots (look under the heading "Stream Read-Count") and explains how
the unpack command can be used to read and parse wtmpx records.
Basically, the script defines a template which it then provides to the
unpack command so that each field in a wtmpx record can be extracted
and assigned to a separate variable.

I found that the script could be easily modified to print user logins
instead of reboots. To do this, I changed these two lines:

if ($ut_line eq "system boot"){
print "rebooted ".scalar localtime($tv_sec)."\n";

to these:
if ($ut_user eq "$username"){ print "$username ".scalar localtime($tv_sec)."\n";

Not much of a challenge, huh?

I also added code to prompt for, read and chomp (trim the newline
character from) the username:

print "username> ";
$username=<STDIN>; chomp $username;

Output from the unmodified sample code looks like this: boson>
./showreboots rebooted Tue Aug 19 20:39:28 2003 rebooted Sat Nov 8
08:52:30 2003 rebooted Thu Mar 11 19:08:34 2004 rebooted Wed Dec 1
15:24:46 2004 rebooted Thu Feb 10 05:22:01 2005

Notice that the date includes the year.

The showlogins script that I based on this script prompts for a
username and displays similarly formatted information:

boson> ./showlogins
username> jdoe jdoe Wed Apr 23 15:23:05 2003 jdoe Wed Apr 23 15:23:21
2003 jdoe Fri Apr 25 09:42:10 2003 jdoe Fri Apr 25 12:07:07 2003 jdoe
Fri Apr 25 12:16:35 2003

Again, notice that the output is not reversed but, instead, appears in
the order in which the records appear in the /var/adm/wtmpx file. This
means that the most recent records will appear last. The showlogins
script could be modified to look for the username on the command line,
making it more amenable for use within other scripts. You might, for
example, want to display the most recent login activity in a script
that you use to disable an account.

You could use lines like these to ensure that a username has been supplied:

# verify that a username has been provided
( 0 == $#ARGV ) or die "usage: $0 username"; $username=$ARGV[0];

NOTE: Since Perl arrays start with element 0, these lines are checking
for and using the first and only parameter. Given this code change,
you can retrieve only the most recent login like this:

boson> ./showlogins sbob | tail -1
sbob Thu Oct 28 09:21:26 2004

If you take a look at the Perl scripts provided in the sample chapter
from the otter book, you will probably be surprised at how easily the
required data can be extracted from the wtmpx file.


Post a Comment

<< Home