diff options
Diffstat (limited to 'fs_selfadmin/fs_mailadmin_server')
-rwxr-xr-x | fs_selfadmin/fs_mailadmin_server | 642 |
1 files changed, 0 insertions, 642 deletions
diff --git a/fs_selfadmin/fs_mailadmin_server b/fs_selfadmin/fs_mailadmin_server deleted file mode 100755 index ef4788543..000000000 --- a/fs_selfadmin/fs_mailadmin_server +++ /dev/null @@ -1,642 +0,0 @@ -#!/usr/bin/perl -Tw -# -# fs_mailadmin_server -# - -use strict; -use IO::Handle; -use FS::SSH qw(sshopen2); -use FS::UID qw(adminsuidsetup); -use FS::Conf; -use FS::Record qw( qsearch qsearchs ); -use FS::cust_main_county; -use FS::cust_main; -use FS::svc_acct_admin; - -use vars qw( $opt $Debug $conf $default_domain ); - -$Debug = 1; - -#my @payby = qw(CARD PREPAY); - -my $user = shift or die &usage; -&adminsuidsetup( $user ); - -$conf = new FS::Conf; -$default_domain = $conf->config('domain'); - -my $machine = shift or die &usage; - -my $agentnum = shift or die &usage; -my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } ) or die &usage; -my $pkgpart = $agent->pkgpart_hashref; - -my $refnum = shift or die &usage; - -#causing trouble for some folks -#$SIG{CHLD} = sub { wait() }; - -my($fs_mailadmind)=$conf->config('fs_mailadmind'); - -while (1) { - my($reader,$writer)=(new IO::Handle, new IO::Handle); - $writer->autoflush(1); - warn "[fs_mailadmin_server] Connecting to $machine...\n" if $Debug; - sshopen2($machine,$reader,$writer,$fs_mailadmind); - - my $data; - - warn "[fs_mailadmin_server] Sending locales...\n" if $Debug; - my @cust_main_county = qsearch('cust_main_county', {} ); - print $writer $data = join("\n", - ( scalar(@cust_main_county) || die "no tax rates (cust_main_county records)" ), - map { - $_->taxnum, - $_->state, - $_->county, - $_->country, - } @cust_main_county - ),"\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - warn "[fs_mailadmin_server] Sending package definitions...\n" if $Debug; - my @part_pkg = grep { $_->svcpart('svc_acct') && $pkgpart->{ $_->pkgpart } } - qsearch( 'part_pkg', {} ); - print $writer $data = join("\n", - ( scalar(@part_pkg) || die "no usable package definitions, agent $agentnum" ), - map { - $_->pkgpart, - $_->pkg, - } @part_pkg - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - warn "[fs_mailadmin_server] Sending POPs...\n" if $Debug; - my @svc_acct_pop = qsearch ('svc_acct_pop',{} ); - print $writer $data = join("\n", - ( scalar(@svc_acct_pop) || die "No points of presence (svc_acct_pop records)" ), - map { - $_->popnum, - $_->city, - $_->state, - $_->ac, - $_->exch, - $_->loc, - } @svc_acct_pop - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - warn "[fs_mailadmin_server] Entering main loop...\n" if $Debug; -COMMAND: while (1) { - warn "[fs_mailadmin_server] Reading (waiting for) command...\n" if $Debug; - chop( my($command, $user) = map { scalar(<$reader>) } ( 1 .. 2 ) ); - my $domain = $default_domain; - $user =~ /^([\w\.\-]+)\@(([\w\-]+\.)+\w+)$/; - ($user, $domain) = ($1, $2); - - if ($command eq 'authenticate'){ - warn "[fs_mailadmin_server] Processing authenticate command for $user \n" if $Debug; - chop( my($password) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - - my $error = ''; - - my @svc_domain = qsearchs('svc_domain', { 'domain' => $domain }); - - if (scalar(@svc_domain) != 1) { - warn "Nonexistant or duplicate service account for \"$domain\""; - next COMMAND; - } - - my @svc_acct = qsearchs('svc_acct', { 'username' => $user, - 'domsvc' => $svc_domain[0]->svcnum }); - if (scalar(@svc_acct) != 1) { - die "Nonexistant or duplicate service account for \"$user\""; - next COMMAND; - } - - if ($svc_acct[0]->_password eq $password) { - $error = "$user\@$domain OK"; - }else{ - $error = "$user\@$domain FAILED"; - } - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - } - elsif ($command eq 'list_packages'){ - warn "[fs_mailadmin_server] Processing list_packages command for $user \n" if $Debug; - - my $error = ''; - - my @packages = eval {find_administrable_packages( $user, $domain )}; - warn "$@" if $@; - - my %packages; - my %accounts; - - foreach my $package (@packages) { - $packages{my $pkgnum = $package->getfield('pkgnum')} = $default_domain; - $accounts{$pkgnum} = 0; - my @services = qsearch('cust_svc', { 'pkgnum' => $pkgnum }); - foreach my $service (@services) { - if ($service->getfield('svcpart') eq '4'){ - my $account=qsearchs('svc_domain', { 'svcnum' => $service->getfield('svcnum') }); - $packages{$pkgnum}=$account->getfield('domain'); - $accounts{$pkgnum}=$account->getfield('svcnum'); - } - } - } - - print $writer $data = join("\n", - ( scalar(keys(%packages)) ), - map { - $_, - $packages{$_}, - $accounts{$_}, - } keys(%packages) - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - }elsif ($command eq 'list_mailboxes'){ - - warn "[fs_mailadmin_server] Processing list_mailboxes command for $user" if $Debug; - chop( my($pkgnum) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - warn "package $pkgnum \n" if $Debug; - - my $error = ''; - - my @packages = eval {find_administrable_packages( $user, $domain )}; - warn "$@" if $@; - - my @accounts; - - foreach my $package (@packages) { - next unless ($pkgnum eq $package->getfield('pkgnum')); - my @services = qsearch('cust_svc', { 'pkgnum' => $package->getfield('pkgnum') }); - foreach my $service (@services) { - if ($service->getfield('svcpart') eq '2'){ - my $account=qsearchs('svc_acct', { 'svcnum' => $service->getfield('svcnum') }); -# $accounts[$#accounts+1]=$account->getfield('username'); - $accounts[$#accounts+1]=$account; - } - } - } - - print $writer $data = join("\n", -# ( scalar(@accounts) || die "No accounts (svc_acct records)" ), - ( scalar(@accounts) ), - map { - $_->svcnum, -# $_->username, - $_->email, -# $_->_password, - '*****', - } @accounts - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - - } elsif ($command eq 'delete_mailbox'){ - warn "[fs_mailadmin_server] Processing delete_mailbox command for $user " if $Debug; - chop( my($account) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - warn "account $account \n" if $Debug; - - my $error = ''; - - my @packages = eval { find_administrable_packages($user, $domain) }; - warn "$@" if $@; - $error ||= "$@" if $@; - - my @svc_acct = qsearchs('svc_acct', { 'svcnum' => $account }) unless $error; - if (scalar(@svc_acct) != 1) { $error ||= 'Nonexistant or duplicate service account for user.' }; - if (! $error && check_administrator(\@packages, $svc_acct[0])){ -# not sure about the next three lines... do we delete? or return error - foreach my $svc_forward (qsearch('svc_forward', { 'dstsvc' => $svc_acct[0]->getfield('svcnum') })) { - $error ||= $svc_forward->delete; - } - foreach my $svc_forward (qsearch('svc_forward', { 'srcsvc' => $svc_acct[0]->getfield('svcnum') })) { - $error ||= $svc_forward->delete; - } - $error ||= $svc_acct[0]->delete; - } else { - $error ||= "Illegal attempt to remove service"; - } - - - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - - } elsif ($command eq 'password_mailbox'){ - warn "[fs_mailadmin_server] Processing password_mailbox command for $user " if $Debug; - chop( my($account, $_password) = map { scalar(<$reader>) } ( 1 .. 2 ) ); - warn "account $account with password $_password \n" if $Debug; - - my $error = ''; - - my @packages = eval { find_administrable_packages($user, $domain) }; - warn "$@" if $@; - $error ||= "$@" if $@; - - my @svc_acct = qsearchs('svc_acct', { 'svcnum' => $account }) unless $error; - if (scalar(@svc_acct) != 1) { $error ||= 'Nonexistant or duplicate service account.' }; - - if (! $error && check_administrator(\@packages, $svc_acct[0])){ - my $new = new FS::svc_acct ({$svc_acct[0]->hash}); - $new->setfield('_password' => $_password); - $error ||= $new->replace($svc_acct[0]); - } else { - $error ||= "Illegal attempt to change password"; - } - - - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - - } elsif ($command eq 'add_mailbox'){ - warn "[fs_mailadmin_server] Processing add_mailbox command for $user " if $Debug; - chop( my($target_package, $account, $_password) = map { scalar(<$reader>) } ( 1 .. 3 ) ); - warn "in package $target_package account $account with password $_password \n" if $Debug; - - my $found_package; - my $domainsvc=0; - my $svcpart=2; # this is 'email box' - my $svcpartsm=3; # this is 'domain alias' - my $error = ''; - my $found = 0; - - my @packages = eval { find_administrable_packages($user, $domain) }; - warn "$@" if $@; - $error ||= "$@" if $@; - - foreach my $package (@packages) { - if ($package->getfield('pkgnum') eq $target_package) { - $found = 1; - $found_package=$package; - my @services = qsearch('cust_svc', { 'pkgnum' => $target_package }); - foreach my $service (@services) { - if ($service->getfield('svcpart') eq '4'){ - my @svc_domain=qsearchs('svc_domain', { 'svcnum' => $service->getfield('svcnum') }); - if (scalar(@svc_domain) eq 1) { - $domainsvc=$svc_domain[0]->getfield('svcnum'); - } - } - } - last; - } - } - warn "User $user does not have administration rights to package $target_package\n" unless $found; - $error ||= "User $user does not have administration rights to package $target_package\n" unless $found; - - my $part_pkg = qsearchs('part_pkg',{'pkgpart'=>$found_package->getfield('pkgpart')}); - - #list of services this pkgpart includes (although at the moment we only care - # about $svcpart - my $pkg_svc; - my %pkg_svc = (); - foreach $pkg_svc ( qsearch('pkg_svc',{'pkgpart'=> $found_package->pkgpart }) ) { - $pkg_svc{$pkg_svc->svcpart} = $pkg_svc->quantity if $pkg_svc->quantity; - } - - my @services = qsearch('cust_svc', {'pkgnum' => $found_package->getfield('pkgnum'), - 'svcpart' => $svcpart, - }); - - if (scalar(@services) >= $pkg_svc{$svcpart}) { - $error="Maximum allowed already reached."; - } - - my $svc_acct = new FS::svc_acct ( { - 'pkgnum' => $found_package->pkgnum, - 'svcpart' => $svcpart, - 'username' => $account, - 'domsvc' => $domainsvc, - '_password' => $_password, - } ); - - my $y = $svc_acct->setdefault; # arguably should be in new method - $error ||= $y unless ref($y); - #and just in case you were silly - $svc_acct->pkgnum($found_package->pkgnum); - $svc_acct->svcpart($svcpart); - $svc_acct->username($account); - $svc_acct->domsvc($domainsvc); - $svc_acct->_password($_password); - - $error ||= $svc_acct->check; - - if ( ! $error ) { #in this case, $cust_pkg should always - #be definied, but.... - $error ||= $svc_acct->insert; - warn "WARNING: $error on pre-checked svc_acct record!" if $error; - } - - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - - }elsif ($command eq 'list_forwards'){ - - warn "[fs_mailadmin_server] Processing list_forwards command for $user" if $Debug; - chop( my($svcnum) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - warn "service $svcnum \n" if $Debug; - - my $error = ''; - - my @packages = eval {find_administrable_packages( $user, $domain )}; - warn "$@" if $@; - - my @forwards; - - foreach my $package (@packages) { -# next unless ($pkgnum eq $package->getfield('pkgnum')); - my @services = qsearch('cust_svc', { 'pkgnum' => $package->getfield('pkgnum') }); - foreach my $service (@services) { - if ($service->getfield('svcpart') eq '10'){ - my $forward=qsearchs('svc_forward', { 'svcnum' => $service->getfield('svcnum') }); - $forwards[$#forwards+1]=$forward if ($forward->getfield('srcsvc') == $svcnum); - } - } - } - - print $writer $data = join("\n", - ( scalar(@forwards) ), - map { - $_->svcnum, - ($_->dstsvc ? qsearchs('svc_acct', {'svcnum' => $_->dstsvc})->email : $_->dst), - } @forwards - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - - }elsif ($command eq 'list_pkg_forwards'){ - - warn "[fs_mailadmin_server] Processing list_pkg_forwards command for $user" if $Debug; - chop( my($pkgnum) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - warn "package $pkgnum \n" if $Debug; - - my $error = ''; - - my @packages = eval {find_administrable_packages( $user, $domain )}; - warn "$@" if $@; - - my @forwards; - - foreach my $package (@packages) { - next unless ($pkgnum eq $package->getfield('pkgnum')); - my @services = qsearch('cust_svc', { 'pkgnum' => $package->getfield('pkgnum') }); - foreach my $service (@services) { - if ($service->getfield('svcpart') eq '10'){ - my $forward=qsearchs('svc_forward', { 'svcnum' => $service->getfield('svcnum') }); - $forwards[$#forwards+1]=$forward; - } - } - } - - print $writer $data = join("\n", - ( scalar(@forwards) ), - map { - $_->svcnum, - $_->srcsvc, - ($_->dstsvc ? qsearchs('svc_acct', {'svcnum' => $_->dstsvc})->email : $_->dst), - } @forwards - ), "\n"; - warn "[fs_mailadmin_server] $data\n" if $Debug > 2; - - - } elsif ($command eq 'delete_forward'){ - warn "[fs_mailadmin_server] Processing delete_forward command for $user " if $Debug; - chop( my($forward) = map { scalar(<$reader>) } ( 1 .. 1 ) ); - warn "forward $forward \n" if $Debug; - - my $error = ''; - - my @packages = eval { find_administrable_packages($user, $domain) }; - warn "$@" if $@; - $error ||= "$@" if $@; - - my @svc_forward = qsearchs('svc_forward', { 'svcnum' => $forward }) unless $error; - if (scalar(@svc_forward) != 1) { $error ||= 'Nonexistant or duplicate service account for user.' }; - if (! $error && check_administrator(\@packages, $svc_forward[0])){ -# not sure about the next three lines... do we delete? or return error - $error ||= $svc_forward[0]->delete; - } else { - $error ||= "Illegal attempt to remove service"; - } - - - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - - } elsif ($command eq 'add_forward'){ - warn "[fs_mailadmin_server] Processing add_forward command for $user " if $Debug; - chop( my($target_package, $source, $dest) = map { scalar(<$reader>) } ( 1 .. 3 ) ); - warn "in package $target_package source $source with destination $dest \n" if $Debug; - - my $found_package; - my $domainsvc=0; - my $svcpart=10; # this is 'forward service' - my $error = ''; - my $found = 0; - - my @packages = eval { find_administrable_packages($user, $domain) }; - warn "$@" if $@; - $error ||= "$@" if $@; - - foreach my $package (@packages) { - if ($package->getfield('pkgnum') eq $target_package) { - $found = 1; - $found_package=$package; - last; - } - } - warn "User $user does not have administration rights to package $target_package\n" unless $found; - $error ||= "User $user does not have administration rights to package $target_package\n" unless $found; - - my $svc_acct = qsearchs('svc_acct', { 'svcnum' => $source }); - warn "Forwarding source $source does not exist.\n" unless $svc_acct; - $error ||= "Forwarding source $source does not exist.\n" unless $svc_acct; - - my $cust_svc = qsearchs('cust_svc', { 'svcnum' => $source }); - warn "Forwarding source $source not attached to any account.\n" unless $cust_svc; - $error ||= "Forwarding source $source not attached to any account.\n" unless $cust_svc; - - if ( ! $error ) { - warn "Forwarding source $source is not in package $target_package\n" - unless ($cust_svc->getfield('pkgnum') == $target_package); - $error ||= "Forwarding source $source is not in package $target_package\n" - unless ($cust_svc->getfield('pkgnum') == $target_package); - } - - my $part_pkg = qsearchs('part_pkg',{'pkgpart'=>$found_package->getfield('pkgpart')}); - - #list of services this pkgpart includes (although at the moment we only care - # about $svcpart - my $pkg_svc; - my %pkg_svc = (); - foreach $pkg_svc ( qsearch('pkg_svc',{'pkgpart'=> $found_package->pkgpart }) ) { - $pkg_svc{$pkg_svc->svcpart} = $pkg_svc->quantity if $pkg_svc->quantity; - } - - my @services = qsearch('cust_svc', {'pkgnum' => $found_package->getfield('pkgnum'), - 'svcpart' => $svcpart, - }); - - if (scalar(@services) >= $pkg_svc{$svcpart}) { - $error="Maximum allowed already reached."; - } - - my $svc_forward = new FS::svc_forward ( { - 'pkgnum' => $found_package->pkgnum, - 'svcpart' => $svcpart, - 'srcsvc' => $source, - 'dstsvc' => 0, - 'dst' => $dest, - } ); - - my $y = $svc_forward->setdefault; # arguably should be in new method - $error ||= $y unless ref($y); - #and just in case you were silly - $svc_forward->pkgnum($found_package->pkgnum); - $svc_forward->svcpart($svcpart); - $svc_forward->srcsvc($source); - $svc_forward->dstsvc(0); - $svc_forward->dst($dest); - - $error ||= $svc_forward->check; - - if ( ! $error ) { #in this case, $cust_pkg should always - #be definied, but.... - $error ||= $svc_forward->insert; - warn "WARNING: $error on pre-checked svc_forward record!" if $error; - } - - warn "[fs_mailadmin_server] Sending results...\n" if $Debug; - print $writer $error, "\n"; - - } else { - warn "[fs_mailadmin_server] Bad command: $command \n" if $Debug; - print $writer "Bad command \n"; - } - } - close $writer; - close $reader; - warn "connection to $machine lost! waiting 60 seconds...\n"; - sleep 60; - warn "reconnecting...\n"; -} - -sub usage { - die "Usage:\n\n fs_mailadmin_server user machine agentnum refnum\n"; -} - -#sub find_administrable_packages { -# my $user = shift; -# -# my $error = ''; -# -# my @svc_acct = qsearchs('svc_acct', { 'username' => $user }); -# if (scalar(@svc_acct) != 1) { -# die "Nonexistant or duplicate service account for \"$user\""; -# } -# -# my @cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_acct[0]->getfield('svcnum') }); -# if (scalar(@cust_svc) != 1 ) { -# die "Nonexistant or duplicate customer service for \"$user\""; -# } -# -# my @cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_svc[0]->getfield('pkgnum') }); -# if (scalar(@cust_pkg) != 1) { -# die "Nonexistant or duplicate customer package for \"$user\""; -# } -# -# my @cust_main = qsearchs('cust_main', { 'custnum' => $cust_pkg[0]->getfield('custnum') }); -# if (scalar(@cust_main) != 1 ) { -# die "Nonexistant or duplicate customer for \"$user\""; -# } -# -# my @packages = $cust_main[0]->ncancelled_pkgs; -#} - -sub find_administrable_packages { - my $user = shift; - my $domain = shift; - - my @packages; - my $error = ''; - - my @svc_domain = qsearchs('svc_domain', { 'domain' => $domain }); - - if (scalar(@svc_domain) != 1) { - die "Nonexistant or duplicate service account for \"$domain\""; - } - - my @svc_acct = qsearchs('svc_acct', { 'username' => $user, - 'domsvc' => $svc_domain[0]->svcnum }); - if (scalar(@svc_acct) != 1) { - die "Nonexistant or duplicate service account for \"$user\""; - } - - my @svc_acct_admin = qsearch('svc_acct_admin', {'adminsvc' => $svc_acct[0]->getfield('svcnum') }); - die "Nonexistant or duplicate customer service for \"$user\"" unless scalar(@svc_acct_admin); - - foreach my $svc_acct_admin (@svc_acct_admin) { - my @cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_acct_admin->getfield('svcnum') }); - if (scalar(@cust_svc) != 1 ) { - die "Nonexistant or duplicate customer service for admin \"$svc_acct_admin->getfield('svcnum')\""; - } - - my @cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_svc[0]->getfield('pkgnum') }); - if (scalar(@cust_pkg) != 1) { - die "Nonexistant or duplicate customer package for admin \"$user\""; - } - - push @packages, $cust_pkg[0] unless $cust_pkg[0]->getfield('cancel'); - - } - (@packages); -} - -sub check_administrator { - my ($allowed_packages_aref, $svc_acct_ref) = @_; - - my $error = ''; - my $found = 0; - - { - my @cust_svc = qsearchs('cust_svc', { 'svcnum' => $svc_acct_ref->getfield('svcnum') }); - if (scalar(@cust_svc) != 1 ) { - warn "Nonexistant or duplicate customer service for \"$svc_acct_ref->getfield('username')\""; - last; - } - - my @cust_pkg = qsearchs('cust_pkg', { 'pkgnum' => $cust_svc[0]->getfield('pkgnum') }); - if (scalar(@cust_pkg) != 1) { - warn "Nonexistant or duplicate customer package for \"$svc_acct_ref->getfield('username')\""; - last; - } - - foreach my $package (@$allowed_packages_aref) { - if ($package->getfield('pkgnum') eq $cust_pkg[0]->getfield('pkgnum')) { - $found = 1; - last; - } - } - } - - $found; -} - -sub check_add { - my ($allowed_packages_aref, $target_package) = @_; - - my $error = ''; - my $found = 0; - - foreach my $package (@$allowed_packages_aref) { - if ($package->getfield('pkgnum') eq $target_package) { - $found = 1; - last; - } - } - - $found; -} - |