Skip to content
Snippets Groups Projects
smadmin 7.29 KiB
Newer Older
#!/usr/bin/perl
# SMRadius administration tool
# Copyright (C) 2009, AllWorldIT
Nigel Kukard's avatar
Nigel Kukard committed
#
# 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.
Nigel Kukard's avatar
Nigel Kukard committed
#
# 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.
Nigel Kukard's avatar
Nigel Kukard committed
#
# 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(
Nigel Kukard's avatar
Nigel Kukard committed
	../ ./
Nigel Kukard's avatar
Nigel Kukard committed
	awitpt/db
);


use Config::IniFiles;
use Getopt::Long;

use smradius::logging;
use smradius::version;

Nigel Kukard's avatar
Nigel Kukard committed

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
Nigel Kukard's avatar
Nigel Kukard committed
#
# 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
{
	#
	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);
		}
	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;
Nigel Kukard's avatar
Nigel Kukard committed
	$server->{'inifile'} = \%config;
	# Init everything
	$server->init();
Nigel Kukard's avatar
Nigel Kukard committed

	# 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 = {
	};
Nigel Kukard's avatar
Nigel Kukard committed

	bless $self, $class;
	return $self;
};

Nigel Kukard's avatar
Nigel Kukard committed

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'});
Nigel Kukard's avatar
Nigel Kukard committed

sub log
{
	my ($self,$level,@msg) = @_;

	# FIXME: we shouldn't ignore $level
	print(@msg, "\n");