#!/usr/bin/perl -Tw
########################################################################
#                                                                      #
#    radlast                      InnerCite                            #
#                                 Mike Machado <mike@innercite.com>    #
#                                 26 June 2000                         #
#                                                                      #
#    See past logins to the system                                     #
#                                                                      #
#    To install as fingerd, copy to /usr/sbin/fingerd and update       #
#    your /etc/inetd.conf. Note, this fingerd does noe require root    #
#                                                                      #
########################################################################

use strict;
use DBI;

# radwho options
my $db_host = 'localhost';	# MySQL server
my $db_db = 'radius';		# MySQL RADIUS database
my $db_user = 'radius';		# MySQL username
my $db_pass = 'icradius';	# MySQL password


# Globals
my $dbh = '';
my $data = '';
my $showconntype = 0;
my $showserial = 0;
my $showcallid = 0;


if ($#ARGV < 0) {
	print "Usage: radlast <date|ALL> [user|nasipaddress] [nasipaddress] [-p|-i|-c]\n";
	print "\tShow logins since <date>. ALL shows all past logins in radacct table\n";
	print "\tSpecify optional username and/or nasipaddress to view specific records\n";
	print "\t-p Show protocol type\n";
	print "\t-i Show serial number\n";
	print "\t-c Show caller ID\n";
	exit;
}

my $date = shift;
my $user = shift;
my $nasipaddress = shift;


if ($user) {
	if ($user =~ /^\d+\.\d+\.\d+\.\d+/) {
		$nasipaddress = $user;
		$user = 0;
	} elsif ($user =~ /^-.*/) {
		push(@ARGV, $user);
		$user = 0;
	}
}

if ($nasipaddress) {
	if ($nasipaddress =~ /^-.*/) {
		push(@ARGV, $nasipaddress);
		$nasipaddress = 0;
	}
}

foreach my $arg (@ARGV) {
	if ($arg eq '-p') {
		$showconntype = 1;
	} elsif ($arg eq '-i') {
		$showserial = 1;
	} elsif ($arg eq '-c') {
		$showcallid = 1;
	}
}


$dbh = DBI->connect("DBI:mysql:$db_db:$db_host", $db_user, $db_pass) || die "Cannot connect to RADIUS database: $!";

my $sth = '';
my $sql = "SELECT * FROM radacct WHERE";
if (uc($date) eq 'ALL') {
	$sql .= " AcctStartTime > 0";
} else {
	$sql .= " AcctStartTime > $date";
}

$sql .= " AND UserName = '$user'" if $user;
$sql .= " AND NASIPAddress = '$nasipaddress'" if $nasipaddress;
$sql .= " ORDER BY AcctStartTime";

$sth = $dbh->prepare($sql) || die "Unable to prepare SQL statement: ".$dbh->errstr();
$sth->execute || die "Unable to execute SQL statement".$dbh->errstr;


print "Login\tName\t\tWhat\tTTY\tStart\t\t\tStop\t\t\tDuration\tFrom\t\tLocation\n";
while (my $rowref = $sth->fetchrow_hashref) {

	my $login = sprintf("%0.8s", $rowref->{UserName});
	my $name = sprintf("%0.16s", $rowref->{UserName});
	my $what = sprintf("%0.6s", $rowref->{FramedProtocol});
	my $tty = sprintf("S%0.6s", $rowref->{NASPortId});
	my $start = sprintf("%0.19s", $rowref->{AcctStartTime});
	my $stop = sprintf("%0.19s", $rowref->{AcctStopTime});
	my $from = sprintf("%0.15s", $rowref->{FramedIPAddress});
	my $duration = sprintf("%0.15s", formatseconds($rowref->{AcctSessionTime}));
	my $location = sprintf("%0.15s", $rowref->{NASIPAddress});
	$stop = 'still logged in ' if $stop eq '0000-00-00 00:00:00';
	my $what1 = '';
	if ($showconntype) {
		if ($rowref->{NASPortType} eq 'ISDN') {
			$what1 = ' I';
		} elsif ($rowref->{NASPortType} eq 'Async') {
			$what1 = ' A';
		} elsif ($rowref->{NASPortType} eq 'Sync') {
			$what1 = ' S';
		}
	}
	if ($showserial) {
		$name = sprintf("%.16s", $rowref->{AcctSessionId});
	}
	if ($showcallid) {
		$name = sprintf("%0.16s", $rowref->{CalledStationId});
	}

	print "$login\t$name\t";
	if (length($name) < 8) {
		print "\t";
	}
	print "$what$what1\t$tty\t$start\t$stop\t$duration\t";
	if (length($duration) < 8) {
		print "\t";
	}
	print "$from\t";
	if (length($from) < 8) {
		print "\t";
	}
	print "$location\n";
}

$sth->finish;
$dbh->disconnect;


sub formatseconds {
 
	my $seconds = shift;
	my $hours = 0;
	my $minutes = 0;
	my $ret = '';
 
	while ($seconds >= 3600) {
		$seconds -= 3600;
		$hours += 1;
	}
 
	while ($seconds >= 60) {
		$seconds -= 60;
		$minutes += 1;
	}
	$ret = "$hours"."h:" if $hours ne 0;
 
	$ret .= "$minutes"."m:".$seconds."s";
	return $ret;
} 
