X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2Fbin%2Ffreeside-selfservice-server;h=c045893d18dc1afe646a2fea182a816f8bbf05af;hp=264cbc56df56094f2f4678d0cfe4424d38205ac2;hb=0247c39288b477060509240ef23a5e7b6bfcd8f8;hpb=0ebeec96313dd7edfca340f01f8fbbbac1f4aa1d diff --git a/FS/bin/freeside-selfservice-server b/FS/bin/freeside-selfservice-server index 264cbc56d..c045893d1 100644 --- a/FS/bin/freeside-selfservice-server +++ b/FS/bin/freeside-selfservice-server @@ -8,13 +8,15 @@ # Proc::Daemon or somesuch use strict; -use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid ); +use vars qw( $Debug %kids $kids $max_kids $shutdown $log_file $ssh_pid + $keepalives ); +use subs qw( lock_write unlock_write ); use Fcntl qw(:flock); use POSIX qw(:sys_wait_h setsid); use IO::Handle; use IO::Select; use IO::File; -use Storable qw(nstore_fd fd_retrieve); +use Storable 2.09 qw(nstore_fd fd_retrieve); use Net::SSH qw(sshopen2); use FS::UID qw(adminsuidsetup forksuidsetup); use FS::ClientAPI; @@ -23,27 +25,27 @@ use FS::Conf; use FS::cust_bill; use FS::cust_pkg; -$Debug = 2; # >= 2 will log packet contents, including potentially compromising - # information +$Debug = 1; # 2 will turn on more logging + # 3 will log packet contents, including passwords $shutdown = 0; $max_kids = '10'; #? +$keepalives = 0; #let clientd turn it on, so we don't barf on old ones $kids = 0; my $user = shift or die &usage; my $machine = shift or die &usage; -my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; -#my $pid_file = "/var/run/freeside-selfservice-server.$user.pid"; $FS::UID::datasrc not posible, but should include machine name at least, hmm +my $tag = scalar(@ARGV) ? shift : ''; + +# $FS::UID::datasrc not posible +my $pid_file = "/var/run/freeside-selfservice-server.$user.$machine.pid"; + +my $lock_file = "/usr/local/etc/freeside/selfservice.$machine.writelock"; &init($user); my $conf = new FS::Conf; -if ($conf->exists('selfservice_server-quiet')) { - $FS::cust_bill::quiet = 1; - $FS::cust_pkg::quiet = 1; -} - my $clientd = "/usr/local/sbin/freeside-selfservice-clientd"; #better name? my $warnkids=0; @@ -51,12 +53,13 @@ while (1) { my($writer,$reader,$error) = (new IO::Handle, new IO::Handle, new IO::Handle); warn "connecting to $machine\n" if $Debug; - $ssh_pid = sshopen2($machine,$reader,$writer,$clientd); + $ssh_pid = sshopen2($machine,$reader,$writer,$clientd,$tag); # nstore_fd(\*writer, {'hi'=>'there'}); warn "entering main loop\n" if $Debug; my $undisp = 0; + my $keepalive_count = 0; my $s = IO::Select->new( $reader ); while (1) { @@ -67,6 +70,12 @@ while (1) { my @handles = $s->can_read(5); unless ( @handles ) { &shutdown if $shutdown; + if ( $keepalives && $keepalive_count++ > 10 ) { + $keepalive_count = 0; + lock_write; + nstore_fd( { _token => '_keepalive' }, $writer ); + unlock_write; + } next; } @@ -74,10 +83,27 @@ while (1) { warn "receiving packet from client\n" if $Debug; - my $packet = fd_retrieve($reader); + my $packet = eval { fd_retrieve($reader); }; + if ( $@ ) { + warn "Storable error receiving packet from client". + " (assuming lost connection): $@\n" + if $Debug; + if ( $ssh_pid ) { + warn "sending TERM signal to ssh process $ssh_pid\n" if $Debug; + kill 'TERM', $ssh_pid; + $ssh_pid = 0; + } + last; + } warn "packet received\n". join('', map { " $_=>$packet->{$_}\n" } keys %$packet ) - if $Debug > 1; + if $Debug > 2; + + if ( $packet->{_packet} eq '_enable_keepalive' ) { + warn "enabling keep alives\n" if $Debug; + $keepalives=1; + next; + } #prevent runaway forking my $warnkids = 0; @@ -95,9 +121,12 @@ while (1) { warn "child $pid spawned\n" if $Debug; } else { #kid time - #get new db handle - $FS::UID::dbh->{InactiveDestroy} = 1; - forksuidsetup($user); + ##get new db handle + #$FS::UID::dbh->{InactiveDestroy} = 1; + #forksuidsetup($user); + + #get db handle + adminsuidsetup($user); my $type = $packet->{_packet}; warn "calling $type handler\n" if $Debug; @@ -108,11 +137,12 @@ while (1) { } $rv->{_token} = $packet->{_token}; #identifier + open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!"; + lock_write; warn "sending response\n" if $Debug; - flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!"; nstore_fd($rv, $writer) or die "FATAL: can't send response: $!"; $writer->flush or die "FATAL: can't flush: $!"; - flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!"; + unlock_write; warn "child exiting\n" if $Debug; exit; #end-of-kid @@ -120,6 +150,10 @@ while (1) { } + &shutdown if $shutdown; + warn "connection lost, reconnecting\n" if $Debug; + sleep 3; + } ### @@ -166,6 +200,10 @@ sub init { #false laziness w/freeside-queued my $freeside_gid = scalar(getgrnam('freeside')) or die "can't setgid to freeside group\n"; + + open(LOCKFILE,">$lock_file") or die "can't open $lock_file: $!"; + chown $FS::UID::freeside_uid, $freeside_gid, $lock_file; + $) = $freeside_gid; $( = $freeside_gid; #if freebsd can't setuid(), presumably it can't setgid() either. grr fleabsd @@ -198,10 +236,12 @@ sub init { } sub shutdown { + &reap_kids; my $wait = 12; #wait up to 1 minute while ( $kids > 0 && $wait-- ) { warn "waiting for $kids children to terminate"; sleep 5; + &reap_kids; } warn "abandoning $kids children" if $kids; kill 'TERM', $ssh_pid if $ssh_pid; @@ -229,7 +269,27 @@ sub _do_logmsg { close $log; } +sub lock_write { + warn "locking $lock_file mutex for write to write stream\n" if $Debug > 1; + + #broken on freebsd? + #flock($writer, LOCK_EX) or die "FATAL: can't lock write stream: $!"; + + flock(LOCKFILE, LOCK_EX) or die "FATAL: can't lock $lock_file: $!"; + +} + +sub unlock_write { + warn "unlocking $lock_file mutex\n" if $Debug > 1; + + #broken on freebsd? + #flock($writer, LOCK_UN) or die "WARNING: can't release write lock: $!"; + + flock(LOCKFILE, LOCK_UN) or die "FATAL: can't unlock $lock_file: $!"; + +} + sub usage { - die "Usage:\n\n fs_signup_server user machine\n"; + die "Usage:\n\n freeside-selfservice-server user machine\n"; }