#!/usr/bin/perl # SMRadius administration tool # Copyright (C) 2009, AllWorldIT # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # 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. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; use warnings; # Set library directory use lib qw( ../ ./ smradius awitpt/db ); use Config::IniFiles; use Getopt::Long; use smradius::logging; use smradius::version; print("SMRadius Admin Tool v".VERSION." - Copyright (c) 2008-2009 AllWorldIT\n"); # Fire up commandline processing... my %opts; GetOptions( \%opts, "help", "config:s", "cleanup", "debug", ); # Check for some args if ($opts{'help'}) { displayHelp(); exit 0; } # Set defaults my $cfg; $cfg->{'config_file'} = "smradiusd.conf"; # Check if we must override if (defined($opts{'config'}) && $opts{'config'} ne "") { $cfg->{'config_file'} = $opts{'config'}; } # Check config file exists if (! -f $cfg->{'config_file'}) { print(STDERR "ERROR: No configuration file '".$cfg->{'config_file'}."' found!\n"); displayHelp(); exit 1; } # Use config file, ignore case tie my %inifile, 'Config::IniFiles', ( -file => $cfg->{'config_file'}, -nocase => 1 ) or die "Failed to open config file '".$cfg->{'config_file'}."': $!"; # Copy config my %config = %inifile; # untie(%inifile); # Our fake server... my $server; # # Check what to do # # We must cleanup if ($opts{'cleanup'}) { loadModules(); # Loop with modules foreach my $module ( @{$server->{'modules_list'}} ) { $server->log(LOG_INFO,"Module: " . $module->{'Name'}); # If we have a cleanup module, run it if (defined($module->{'Cleanup'})) { $server->log(LOG_INFO," -> running cleanup..."); $module->{'Cleanup'}($server); } } # Huh, nothing todo... } else { print(STDERR "ERROR: Nothing to do!\n"); displayHelp(); exit 1; } # # Misc functions # # Register module info sub plugin_register { my ($self,$module,$info) = @_; # If no info, return if (!defined($info)) { $server->log(LOG_ERR,"Plugin info not found for module => $module"); return -1; } # Set real module name & save $info->{'Module'} = $module; push(@{$self->{'modules_list'}},$info); # If we should, init the module if (defined($info->{'init'})) { $info->{'init'}($self); } return 0; } # Function to load our modules sub loadModules { # # System modules # if (ref($config{'system'}{'modules'}) eq "ARRAY") { foreach my $module (@{$config{'system'}{'modules'}}) { $module =~ s/\s+//g; # Skip comments next if ($module =~ /^#/); $module = "system/$module"; push(@{$cfg->{'module_list'}},$module); } } else { my @moduleList = split(/\s+/,$config{'system'}{'modules'}); foreach my $module (@moduleList) { # Skip comments next if ($module =~ /^#/); $module = "system/$module"; push(@{$cfg->{'module_list'}},$module); } } # # Feature modules # if (ref($config{'features'}{'modules'}) eq "ARRAY") { foreach my $module (@{$config{'features'}{'modules'}}) { $module =~ s/\s+//g; # Skip comments next if ($module =~ /^#/); $module = "features/$module"; push(@{$cfg->{'module_list'}},$module); } } else { my @moduleList = split(/\s+/,$config{'features'}{'modules'}); foreach my $module (@moduleList) { # Skip comments next if ($module =~ /^#/); $module = "features/$module"; push(@{$cfg->{'module_list'}},$module); } } # # Authentication modules # if (ref($config{'authentication'}{'mechanisms'}) eq "ARRAY") { foreach my $module (@{$config{'authentication'}{'mechanisms'}}) { $module =~ s/\s+//g; # Skip comments next if ($module =~ /^#/); $module = "authentication/$module"; push(@{$cfg->{'module_list'}},$module); } } else { my @moduleList = split(/\s+/,$config{'authentication'}{'mechanisms'}); foreach my $module (@moduleList) { # Skip comments next if ($module =~ /^#/); $module = "authentication/$module"; push(@{$cfg->{'module_list'}},$module); } } if (ref($config{'authentication'}{'users'}) eq "ARRAY") { foreach my $module (@{$config{'authentication'}{'users'}}) { $module =~ s/\s+//g; # Skip comments next if ($module =~ /^#/); $module = "userdb/$module"; push(@{$cfg->{'module_list'}},$module); } } else { my @moduleList = split(/\s+/,$config{'authentication'}{'users'}); foreach my $module (@moduleList) { # Skip comments next if ($module =~ /^#/); $module = "userdb/$module"; push(@{$cfg->{'module_list'}},$module); } } # # Accounting modules # if (ref($config{'accounting'}{'modules'}) eq "ARRAY") { foreach my $module (@{$config{'accounting'}{'modules'}}) { $module =~ s/\s+//g; # Skip comments next if ($module =~ /^#/); $module = "accounting/$module"; push(@{$cfg->{'module_list'}},$module); } } else { my @moduleList = split(/\s+/,$config{'accounting'}{'modules'}); foreach my $module (@moduleList) { # Skip comments next if ($module =~ /^#/); $module = "accounting/$module"; push(@{$cfg->{'module_list'}},$module); } } # Emulate server $server = new smserver; $server->{'inifile'} = \%config; # Init everything $server->init(); # Load modules foreach my $module (@{$cfg->{'module_list'}}) { # Split off dir and mod name $module =~ /^(\w+)\/(\w+)$/; my ($mod_dir,$mod_name) = ($1,$2); # Load module my $res = eval(" use smradius::modules::${mod_dir}::${mod_name}; plugin_register(\$server,\"${mod_name}\",\$smradius::modules::${mod_dir}::${mod_name}::pluginInfo); "); if ($@ || (defined($res) && $res != 0)) { $server->log(LOG_ERR,"WARNING: Error loading module $module ($@)"); } else { $server->log(LOG_DEBUG,"[SMRADIUS] Plugin '$module' loaded."); } } } # Display help sub displayHelp { print(<<EOF); Usage: $0 [args] --config=<file> Configuration file --debug Put into debug mode --cleanup Cleanup database records EOF } # Server emulation package smserver; use strict; use warnings; use smradius::logging; use smradius::config; use awitpt::db::dbilayer; use awitpt::db::dblayer; # Return oursevles sub new { my $class = shift; my $self = { }; bless $self, $class; return $self; }; sub init { my $self = shift; # Init config smradius::config::Init($self); # Init system stuff $self->{'client'}->{'dbh'} = awitpt::db::dbilayer::Init($self,'smradius'); if (!defined($self->{'client'}->{'dbh'})) { $self->log(LOG_WARN,"Failed to Initialize: ".awitpt::db::dbilayer::internalError()." ($$)"); die; } if ($self->{'client'}->{'dbh'}->connect()) { $self->log(LOG_WARN,"Failed to connect to database: ".$self->{'client'}->{'dbh'}->Error()." ($$)"); die; } # Setup database handle awitpt::db::dblayer::setHandle($self->{'client'}->{'dbh'}); } sub log { my ($self,$level,@msg) = @_; # FIXME: we shouldn't ignore $level print(@msg, "\n"); } # vim: ts=4