summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS/Record.pm8
-rw-r--r--FS/FS/nas.pm12
-rw-r--r--FS/FS/session.pm27
-rw-r--r--FS/MANIFEST4
-rwxr-xr-xbin/fs-setup18
-rw-r--r--fs_sesmon/FS-SessionClient/MANIFEST2
-rw-r--r--fs_sesmon/FS-SessionClient/Makefile.PL2
-rw-r--r--fs_sesmon/FS-SessionClient/SessionClient.pm6
-rw-r--r--fs_sesmon/FS-SessionClient/bin/freeside-login36
-rw-r--r--fs_sesmon/FS-SessionClient/bin/freeside-logoff37
-rw-r--r--fs_sesmon/fs_session_server66
-rw-r--r--htdocs/docs/index.html1
-rw-r--r--htdocs/docs/schema.html24
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>