#!/usr/bin/perl # # Author: Peter Nixon # Summary: Count online radius users as reported by SQL # Copyright: 2006 Peter Nixon http://petenixon.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # $Id: radusers.pl,v 1.2 2006/08/29 15:21:06 peter Exp $ # # Modules that we use to get things done. require DBI; require Getopt::Long; use Sys::Syslog; # Default Variables my $database = "radius"; my $port = "3306"; my $user = "rad-www"; my $password = "password"; my $default_db_host = "localhost"; my %config = ( 'debug' => 1, # Need debugging info? 0=No 1=Yes 'syslog_facility' => 'local4', # Syslog facility to send logging 'syslog_name' => 'calling script name', 'syslog_priority' => 'err', 'syslog_host' => '127.0.0.1', 'syslog_port' => 514 ); #### You should not have to modify anything below here $progname = "APN Users"; $version = 1.1; # Set up some basic variables my $passno = 0; my $duplicates = 0; my $verbose = 0; my %duplicate_records = (); my $starttime = time(); sub db_connect { my $hostname = shift; if ($verbose > 1) { print "DEBUG: Connecting to Database Host: $hostname\n" } if ($hostname eq 'localhost') { if ($verbose > 1) { print "DEBUG: localhost connection so using UNIX socket instead of network socket.\n" } $dbh = DBI->connect("DBI:Pg:dbname=$database", "$user", "$password") or die "Couldn't connect to database: " . DBI->errstr; } else { $dbh = DBI->connect("DBI:Pg:dbname=$database;host=$hostname", "$user", "$password") or die "Couldn't connect to database: " . DBI->errstr; } } sub db_disconnect { my $hostname = shift; if ($verbose > 1) { print "DEBUG: Disconnecting from Database Host: $hostname\n" } $dbh->disconnect # Disconnect from the database or warn "Disconnection failed: $DBI::errstr\n"; } sub db_read { my $query = pop @_; #print "Using APN: $$ref{apn}\n" if ($verbose > 0); print "QUERY: $query\n" if ($verbose > 2); my $sth = $dbh->prepare("$query") or die "\nCouldn't prepare statement: " . $dbh->errstr . "\n"; my @data; $sth->execute() # Execute the query or die "\nCouldn't execute statement: " . $sth->errstr . "\n"; my $returned_rows = $sth->rows; if ($sth->rows == 0) { print "For some reason we got no result! We have a problem!\n"; } elsif ($sth->rows == 1) { while (@data = $sth->fetchrow_array()) { my $usercount = $data[0]; print "$usercount\n"; } } else { print "More than one result! We have a problem!\n"; } $sth->finish; } # printlog: To send a message to the log (syslog) sub printlog { my($level, $msg, $facility); $level = shift @_; $msg = shift @_; $facility = ( ( !defined($config{'syslog_facility'}) ) ? 'local5' : $config{'syslog_facility'} ); if ( $level =~ /debug/i && !$config{'debug'} ) { return; } if ( ! openlog($0, 'cons,pid', $facility) ) { print STDERR "It didnt work SYSLOG: $0\t$facility\.$level\t$msg\n"; return; } syslog($level, '%s', $msg); closelog(); if ($config{'debug'}) { open LOG, ">>/tmp/$0.log" or return; print LOG localtime() . " [$0 -> $facility\.$level] $msg\n"; close(LOG); } return; } sub print_banner { # Do not edit this variable. It is updated automatically by CVS when you commit my $rcs_info = 'CVS Revision $Revision: 1.2 $ created on $Date: 2006/08/29 15:21:06 $ by $Author: peter $ '; $rcs_info =~ s/\$\s*Revision: (\S+) \$/$1/; $rcs_info =~ s/\$\s*Date: (\S+) (\S+) \$/$1 at $2/; $rcs_info =~ s/\$\s*Author: (\S+) \$ /$1/; print "\n"; print "$progname Version $version by Peter Nixon - http://peternixon.net/\n"; print "Copyright (c) 2002-2006 Peter Nixon\n"; print " ($rcs_info)\n"; print "\n"; } sub print_usage_info { print "\n"; $leader = "$progname $version Usage Information"; $underbar = $leader; $underbar =~ s/./-/g; print "$leader\n$underbar\n"; print "\n"; print " Syntax: radusers.pl [ options ] apn\n"; print "\n"; print " -h --help Show this usage information\n"; print " -c --custid Query for \"custid\"\n"; print " -u --user Query for \"user\"\n"; print " -g --group Query for \"group\"\n"; print " -d --database Database to use\n"; print " -H --host Database host to connect to (Default: localhost)\n"; print " -q --quiet Turn on quiet mode (No Output)\n"; print " -v --verbose Turn on verbose\n"; print " -V --version Show version and copyright\n"; print " -x --debug Turn on debugging\n"; print "\n"; } sub main { # See the Getopt::Long man page for details on the syntax of this line @valid_opts = ("h|help", "V|version", "a|all", "x|debug", "d|database=s", "v|verbose+" => \$verbose, "q|quiet+" => \$quiet, "D|date=s", "H|host=s", "c|custid=s", "g|group=s", "u|user=s"); Getopt::Long::Configure("no_getopt_compat", "bundling", "no_ignore_case"); Getopt::Long::GetOptions(@valid_opts); my $query; # Post-parse the options stuff select STDOUT; $| = 1; if ($opt_V) { &print_banner(); return SUCCESS; } elsif ($opt_h) { &print_usage_info(); exit(SUCCESS); } if ($opt_x) { print "DEBUG: Debug mode is enabled.\n"; $verbose = 2; } elsif ($quiet) { $verbose -= $quiet; } if ($opt_d) { if ($verbose > 0) { print "Using database \"$opt_d\" instead of default database \"$database\"\n"; } $database = $opt_d; } $query = "SELECT count(DISTINCT(callingstationid)) FROM radacct WHERE acctstoptime ISNULL"; if (@ARGV) { $query = "$query" . " AND calledstationid = '$ARGV[0]' "; } if ($opt_g) { $query = "$query" . " AND groupname = '$opt_g' "; } if ($opt_u) { $query = "$query" . " AND username = '$opt_u' "; } if ($opt_c) { $query = "$query" . " AND custid = '$opt_c' "; } my $db_host; if ($opt_H) { $db_host = $opt_H; } else { $db_host = "$default_db_host"; } &db_connect($db_host); # Loop through the specified APNs #foreach $apn (@ARGV) { # &db_read($apn); #} &db_read($query); &db_disconnect($db_host); my $runtime = (time() - $starttime); if ($runtime < 1) { $runtime = 1; } if ($verbose >= 1) { print "DEBUG Runtime: $runtime seconds\n"; } } exit &main();