diff options
-rw-r--r-- | FS/FS/Record.pm | 8 | ||||
-rw-r--r-- | FS/FS/nas.pm | 12 | ||||
-rw-r--r-- | FS/FS/session.pm | 27 | ||||
-rw-r--r-- | FS/MANIFEST | 4 | ||||
-rwxr-xr-x | bin/fs-setup | 18 | ||||
-rw-r--r-- | fs_sesmon/FS-SessionClient/MANIFEST | 2 | ||||
-rw-r--r-- | fs_sesmon/FS-SessionClient/Makefile.PL | 2 | ||||
-rw-r--r-- | fs_sesmon/FS-SessionClient/SessionClient.pm | 6 | ||||
-rw-r--r-- | fs_sesmon/FS-SessionClient/bin/freeside-login | 36 | ||||
-rw-r--r-- | fs_sesmon/FS-SessionClient/bin/freeside-logoff | 37 | ||||
-rw-r--r-- | fs_sesmon/fs_session_server | 66 | ||||
-rw-r--r-- | htdocs/docs/index.html | 1 | ||||
-rw-r--r-- | htdocs/docs/schema.html | 24 |
13 files changed, 218 insertions, 25 deletions
diff --git a/FS/FS/Record.pm b/FS/FS/Record.pm index b0bfb0b3c..59472c898 100644 --- a/FS/FS/Record.pm +++ b/FS/FS/Record.pm @@ -731,10 +731,10 @@ Check/untaint ip addresses. IPv4 only for now. sub ut_ip { my( $self, $field ) = @_; - $self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/; + $self->getfield($field) =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ or return "Illegal (IP address) $field: ". $self->getfield($field); - for ( $1 $2 $3 $4 ) { return "Illegal (IP address) $field" if $_ > 255; }; - $self->$setfield($field, "$1.$2.$3.$3"); + for ( $1, $2, $3, $4 ) { return "Illegal (IP address) $field" if $_ > 255; } + $self->setfield($field, "$1.$2.$3.$3"); ''; } @@ -895,7 +895,7 @@ sub hfields { =head1 VERSION -$Id: Record.pm,v 1.8 2000-10-27 20:15:50 ivan Exp $ +$Id: Record.pm,v 1.9 2000-11-07 15:00:37 ivan Exp $ =head1 BUGS diff --git a/FS/FS/nas.pm b/FS/FS/nas.pm index 5ed95f92e..873c9bce6 100644 --- a/FS/FS/nas.pm +++ b/FS/FS/nas.pm @@ -117,11 +117,21 @@ sub check { || $self->ut_numbern('last'); } +=sub heartbeat TIMESTAMP + +Updates the timestamp for this nas + +=cut + +sub heartbeat { + warn "warning: heartbeat unimplemented!" +} + =back =head1 VERSION -$Id: nas.pm,v 1.1 2000-10-27 20:18:32 ivan Exp $ +$Id: nas.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $ =head1 BUGS diff --git a/FS/FS/session.pm b/FS/FS/session.pm index 0d766bd22..b85a5822f 100644 --- a/FS/FS/session.pm +++ b/FS/FS/session.pm @@ -4,6 +4,8 @@ use strict; use vars qw( @ISA ); use FS::Record qw( qsearchs ); use FS::svc_acct; +use FS::port; +use FS::nas; @ISA = qw(FS::Record); @@ -31,6 +33,8 @@ FS::session - Object methods for session records $error = $record->check; + $error = $record->nas_heartbeat($timestamp); + =head1 DESCRIPTION An FS::session object represents an user login session. FS::session inherits @@ -57,7 +61,7 @@ from FS::Record. The following fields are currently supported: =item new HASHREF -Creates a new example. To add the example to the database, see L<"insert">. +Creates a new session. To add the session to the database, see L<"insert">. Note that this stores the hash reference, not a distinct copy of the hash it points to. You can ask the object for a copy with the I<hash> method. @@ -95,6 +99,8 @@ sub insert { $error = $self->SUPER::insert; return $error if $error; + $self->nas_heartbeat($self->getfield('login')); + #session-starting callback! ''; @@ -136,6 +142,8 @@ sub replace { $error = $self->SUPER::replace; return $error if $error; + $self->nas_heartbeat($self->getfield('logout')); + #session-ending callback! ''; @@ -143,7 +151,7 @@ sub replace { =item check -Checks all fields to make sure this is a valid example. If there is +Checks all fields to make sure this is a valid session. If there is an error, returns the error, otherwise returns false. Called by the insert and replace methods. @@ -167,11 +175,24 @@ sub check { ''; } +=item nas_heartbeat + +Heartbeats the nas associated with this session (see L<FS::nas>). + +=cut + +sub nas_heartbeat { + my $self = shift; + my $port = qsearchs('port',{'portnum'=>$self->portnum}); + my $nas = qsearchs('nas',{'nasnum'=>$port->nasnum}); + $nas->heartbeat(shift); +} + =back =head1 VERSION -$Id: session.pm,v 1.1 2000-10-27 20:18:32 ivan Exp $ +$Id: session.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $ =head1 BUGS diff --git a/FS/MANIFEST b/FS/MANIFEST index e0b5b51e5..91d2e2fc0 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -40,12 +40,16 @@ FS/svc_acct_pop.pm FS/svc_acct_sm.pm FS/svc_domain.pm FS/type_pkgs.pm +FS/nas.pm +FS/port.pm +FS/session.pm MANIFEST MANIFEST.SKIP Makefile.PL test.pl README bin/freeside-bill +bin/freeside-print-batch FS/domain_record.pm FS/prepay_credit.pm FS/svc_www.pm diff --git a/bin/fs-setup b/bin/fs-setup index b0f47610f..602dc7274 100755 --- a/bin/fs-setup +++ b/bin/fs-setup @@ -1,6 +1,6 @@ #!/usr/bin/perl -Tw # -# $Id: fs-setup,v 1.28 2000-10-30 10:47:26 ivan Exp $ +# $Id: fs-setup,v 1.29 2000-11-07 15:00:37 ivan Exp $ # # ivan@sisd.com 97-nov-8,9 # @@ -32,7 +32,10 @@ # fix radius attributes ivan@sisd.com 98-sep-27 # # $Log: fs-setup,v $ -# Revision 1.28 2000-10-30 10:47:26 ivan +# Revision 1.29 2000-11-07 15:00:37 ivan +# session monitor +# +# Revision 1.28 2000/10/30 10:47:26 ivan # nas.last can't be defined NULL if indexed # # Revision 1.26 2000/07/06 08:57:27 ivan @@ -751,9 +754,7 @@ sub tables_hash_hack { 'nas', 'varchar', '', $char_d, 'nasip', 'varchar', '', 15, 'nasfqdn', 'varchar', '', $char_d, -# 'last', 'timestamp', '', '', -#change to above when move to DBIx::DBSchema!!! - 'last', 'datetime', '', '', + 'last', @date_type, ], 'primary_key' => 'nasnum', 'unique' => [ [ 'nas' ], [ 'nasip' ] ], @@ -765,11 +766,8 @@ sub tables_hash_hack { 'sessionnum', 'int', '', '', 'portnum', 'int', '', '', 'svcnum', 'int', '', '', -# 'login', 'timestamp', '', '', -# 'logout', 'timestamp', '', '', -#change to above when move to DBIx::DBSchema!!! - 'login', 'datetime', '', '', - 'logout', 'datetime', NULL, '', + 'login', @date_type, + 'logout', @date_type, ], 'primary_key' => 'sessionnum', 'unique' => [], diff --git a/fs_sesmon/FS-SessionClient/MANIFEST b/fs_sesmon/FS-SessionClient/MANIFEST index 3ced1df17..6da7b22e9 100644 --- a/fs_sesmon/FS-SessionClient/MANIFEST +++ b/fs_sesmon/FS-SessionClient/MANIFEST @@ -7,3 +7,5 @@ test.pl fs_sessiond cgi/logon.cgi cgi/logoff.cgi +bin/freeside-login +bin/freeside-logoff diff --git a/fs_sesmon/FS-SessionClient/Makefile.PL b/fs_sesmon/FS-SessionClient/Makefile.PL index 8dff176a7..1f598474a 100644 --- a/fs_sesmon/FS-SessionClient/Makefile.PL +++ b/fs_sesmon/FS-SessionClient/Makefile.PL @@ -4,7 +4,7 @@ use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'FS::SessionClient', 'VERSION_FROM' => 'SessionClient.pm', # finds $VERSION - 'EXE_FILES' => [ 'fs_sessiond' ], + 'EXE_FILES' => [ qw(fs_sessiond freeside-login freeside-logoff) ], 'INSTALLSCRIPT' => '/usr/local/sbin', 'PERM_RWX' => '750', ); diff --git a/fs_sesmon/FS-SessionClient/SessionClient.pm b/fs_sesmon/FS-SessionClient/SessionClient.pm index fd50e8908..97332cb26 100644 --- a/fs_sesmon/FS-SessionClient/SessionClient.pm +++ b/fs_sesmon/FS-SessionClient/SessionClient.pm @@ -1,7 +1,7 @@ package FS::SessionClient; use strict; -use vars qw($VERSION @ISA @EXPORT_OK $fs_sessiond_socket); +use vars qw($AUTOLOAD $VERSION @ISA @EXPORT_OK $fs_sessiond_socket); use Exporter; use Socket; use FileHandle; @@ -10,7 +10,7 @@ use IO::Handle; $VERSION = '0.01'; @ISA = qw( Exporter ); -@EXPORT_OK = qw( login logoff ); +@EXPORT_OK = qw( login logoff portnum ); $fs_sessiond_socket = "/usr/local/freeside/fs_sessiond_socket"; @@ -104,7 +104,7 @@ sub AUTOLOAD { =head1 VERSION -$Id: SessionClient.pm,v 1.1 2000-10-27 20:15:50 ivan Exp $ +$Id: SessionClient.pm,v 1.2 2000-11-07 15:00:37 ivan Exp $ =head1 BUGS diff --git a/fs_sesmon/FS-SessionClient/bin/freeside-login b/fs_sesmon/FS-SessionClient/bin/freeside-login new file mode 100644 index 000000000..6ca4455f8 --- /dev/null +++ b/fs_sesmon/FS-SessionClient/bin/freeside-login @@ -0,0 +1,36 @@ +#!/usr/bin/perl -Tw + +#false-laziness hack w freeside-logoff + +use strict; +use FS::SessionClient qw( login portnum ); + +my $username = shift; + +my $portnum; +if ( scalar(@ARGV) == 1 ) { + my $arg = shift; + if ( $arg =~ /^(\d+)$/ ) { + $portnum = $1; + } elsif ( $arg =~ /^([\d\.]+)$/ ) { + $portnum = portnum( { 'ip' => $1 } ) or die "unknown ip!" + } else { + &usage; + } +} elsif ( scalar(@ARGV) == 2 ) { + $portnum = portnum( { 'nasnum' => shift, 'nasport' => shift } ) + or die "unknown nasnum/nasport"; +} else { + &usage; +} + +my $error = login ( { + 'username' => $username, + 'portnum' => $portnum, +} ); + +warn $error if $error; + +sub usage { + die "Usage:\n\n freeside-login username ( portnum | ip | nasnum nasport )"; +} diff --git a/fs_sesmon/FS-SessionClient/bin/freeside-logoff b/fs_sesmon/FS-SessionClient/bin/freeside-logoff new file mode 100644 index 000000000..f7b876b33 --- /dev/null +++ b/fs_sesmon/FS-SessionClient/bin/freeside-logoff @@ -0,0 +1,37 @@ +#!/usr/bin/perl -Tw + +#false-laziness hack w freeside-login + +use strict; +use FS::SessionClient qw( logoff portnum ); + +my $username = shift; + +my $portnum; +if ( scalar(@ARGV) == 1 ) { + my $arg = shift; + if ( $arg =~ /^(\d+)$/ ) { + $portnum = $1; + } elsif ( $arg =~ /^([\d\.]+)$/ ) { + $portnum = portnum( { 'ip' => $1 } ) or die "unknown ip!" + } else { + &usage; + } +} elsif ( scalar(@ARGV) == 2 ) { + $portnum = portnum( { 'nasnum' => shift, 'nasport' => shift } ) + or die "unknown nasnum/nasport"; +} else { + &usage; +} + +my $error = login ( { + 'username' => $username, + 'portnum' => $portnum, +} ); + +warn $error if $error; + +sub usage { + die "Usage:\n\n freeside-logoff username ( portnum | ip | nasnum nasport )"; +} + diff --git a/fs_sesmon/fs_session_server b/fs_sesmon/fs_session_server index be0a01710..46e53d118 100644 --- a/fs_sesmon/fs_session_server +++ b/fs_sesmon/fs_session_server @@ -12,6 +12,8 @@ use FS::Record qw( qsearch qsearchs ); #use FS::cust_main_county; #use FS::cust_main; use FS::session; +use FS::port; +use FS::svc_acct; #require "configfile"; $Debug = 1; @@ -42,12 +44,70 @@ while (1) { } if ( $command eq 'login' ) { - + $error = &login(\%hash); + print $writer "$error\n"; } elsif ( $command eq 'logoff' ) { - + $error = &logoff(\%hash); + print $writer "$error\n"; } elsif ( $command eq 'portnum' ) { - + if ( exists $hash{'ip'} ) { + $hash{'ip'} =~ /^([\d\.]+)$/ or $1='nomatch'; + $port = qsearchs('port', { 'ip' => $1 } ); + } else { + $hash{'nasnum'} =~ /^(\d+)$/ and my $nasnum = $1; + $hash{'nasport'} =~ /^(\d+)$/ and my $nasport = $1; + $port = qsearchs('port', { 'nasnum'=>$nasnum, 'nasport'=>$nasport } ); + } + print $writer ( $port ? $port->portnum : '' ), "\n"; } else { warn "$me WARNING: unrecognized command"; } + } + #won't ever reach without code above to throw out of loop, but... + close $writer; + close $reader; + warn "connection to $machine lost!\n" + sleep 5; + warn "reconnecting...\n"; +} + +sub login { + my $href = shift; + $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username"; + my $username = $1; + $svc_acct = qsearchs('svc_acct', { 'username' => $username } ) + or return "Unknown user"; + return "Incorrect password" + if defined($href->{'password'}) + && $href->{'password'} ne $svc_acct->_password; + my $session = new FS::session { + 'portnum' => $href->{'portnum'}, + 'svcnum' => $svc_acct->svcnum, + 'login' => $href->{'login'}, + }; + $session->insert; +} + +sub logout { + my $href = shift; + $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username"; + my $username = $1; + $svc_acct = qsearchs('svc_acct', { 'username' => $username } ) + or return "Unknown user"; + return "Incorrect password" + if defined($href->{'password'}) + && $href->{'password'} ne $svc_acct->_password; + my $session = qsearchs FS::session { + 'portnum' => $href->{'portnum'}, + 'svcnum' => $svc_acct->svcnum, + 'logoff' => '', + }; + return "No currently open sessios found for that user/port!" unless $session; + my $nsession = new FS::session ( { $old->hash } ); + $nsession->replace($session); +} + +sub usage { + die "Usage:\n\n fs_session_server user machine\n"; +} diff --git a/htdocs/docs/index.html b/htdocs/docs/index.html index f4155c1b8..f5c43d02c 100644 --- a/htdocs/docs/index.html +++ b/htdocs/docs/index.html @@ -20,6 +20,7 @@ <li><a href="export.html">File exporting and remote setup</a> <li><a href="passwd.html">fs_passwd</a> <li><a href="signup.html">Signup server</a> + <li><a href="session.html">Session monitor</a> <li><a href="billing.html">Billing</a> <li><a href="trouble.html">Troubleshooting</a> <li><a href="schema.html">Schema reference</a> diff --git a/htdocs/docs/schema.html b/htdocs/docs/schema.html index 1ab0e7f62..474a3501a 100644 --- a/htdocs/docs/schema.html +++ b/htdocs/docs/schema.html @@ -143,6 +143,14 @@ <li>pkgnum - <a href="#cust_pkg">package</a> <li>svcpart - <a href="#part_svc">Service definition</a> </ul> + <li><a name="nas">nas</a> - Network Access Server (terminal server) + <ul> + <li>nasnum - primary key + <li>nas - NAS name + <li>nasip - NAS ip address + <li>nasfqdn - NAS fully-qualified domain name + <li>last - timestamp indicating the last instant the NAS was in a known state (used by the session monitoring). + </ul> <li><a name="part_pkg">part_pkg</a> - Package definitions <ul> <li>pkgpart - primary key @@ -176,12 +184,28 @@ <li>svcpart - <a href="#part_svc">Service definition</a> <li>quantity - quantity of this service that this package includes </ul> + <li><a name="port">port</a> - individual port on a <a href="#nas">nas</a> + <ul> + <li>portnum - primary key + <li>ip - IP address of this port + <li>nasport - port number on the NAS + <li>nasnum - <a href="#nas">NAS</a> + </ul> <li><a name="prepay_credit">prepay_credit</a> <ul> <li>prepaynum - primary key <li>identifier - text or numeric string used to receive this credit <li>amount - amount of credit </ul> + <li><a name="session">session</a> + <ul> + <li>sessionnum - primary key + <li>portnum - <a href="#port">Port</a> + <li>svcnum - <a href="#svc_acct">Account</a> + <li>login - timestamp indicating the beginning of this user session. + <li>logout - timestamp indicating the end of this user session. May be null, which indicates a currently open session. + </ul> + <li><a name="svc_acct">svc_acct</a> - Accounts <ul> <li>svcnum - <a href="#cust_svc">primary key</a> |