It took me a while to figure out the file format for /var/log/lastlog on *NIX type machines. Some of the sysadmins out there may find it usefull to be able to determine the last time of login for an account without using any other apps.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#! /usr/bin/env python import struct def getrecord(file,uid, preserve = False): """Returns [int(unix_time),string(device),string(host)] from the lastlog formated file object, set preserve = True to preserve your position within the file""" position = file.tell() recordsize = struct.calcsize('L32s256s') file.seek(recordsize*uid) data = file.read(recordsize) if preserve: file.seek(position) try: returnlist = list(struct.unpack('L32s256s',data)) returnlist = returnlist.replace('\x00','') returnlist = returnlist.replace('\x00','') return returnlist except: return False if __name__ == '__main__': import sys import pwd import time try: llfile = open("/var/log/lastlog",'r') except: print "Unable to open /var/log/lastlog" sys.exit(1) for user in pwd.getpwall(): record = getrecord(llfile,user) if record and record > 0: print '%16s\t\t%s\t%s' % (user,time.ctime(record),record) elif record: print '%16s\t\tNever logged in' % (user,) else: pass llfile.close()
It took me a while to figure out the file format for /var/log/lastlog on NIX type machines. This file contains recordsizelargest_uid records, each record is accessed by seeking to the uid*recordsize and reading recordsize bytes. Each record consists of a long unsigned integer (important to note that on some machines this is the same size as an unsigned integer but may differ), up to a 16 character string denoting the device the connection was made with (i.e. tty0,:0,pts1), and a 256 character string denoting the host from which the connection was made. I tried to make this implementation as simple and flexible as possible and stick to the standard library. I welcome any suggestions for making this more efficient, usefull, elegant, etc.