#!/usr/bin/perl ######################################################################## # # # mailadmin.cgi NCI2000 # # Jeff Finucane # # 26 April 2001 # # # ######################################################################## use DBI; use strict; use CGI; use FS::MailAdminClient qw(authenticate list_packages list_mailboxes delete_mailbox password_mailbox add_mailbox list_forwards list_pkg_forwards delete_forward add_forward); my $sessionfile = '/usr/local/apache/htdocs/mailadmin/adminsess'; # session file my $tmpdir = '/usr/local/apache/htdocs/mailadmin/tmp'; # Location to store temp files my $cookiedomain = ".your.dom"; # domain if THIS server, should prepend with a '.' my $cookieexpire = '+12h'; # expire the cookie session after this much idle time my $sessexpire = 43200; # expire session after this long of no use (in seconds) my $body = ""; #### Should not have to change anything under this line #### my $printmainpage = 1; my $i = 0; my $printheader = 1; my $query = new CGI; my $cgi = $query->url(); my $now = getdatetime(); my $current_package = 0; my $current_account = 0; my $current_domname = ""; # if they are trying to login we wont check the session yet if ($query->param('login') eq '' && $query->param('action') ne 'login') { checksession(); printheader(); } if ($query->param('login') ne '') { my $username = $query->param('username'); my $password = $query->param('password'); if (!checkuserpass($username, $password)) { printheader(); error('not_admin'); } my @alpha = ('A'..'Z', 'a'..'z', 0..9); my $sessid = ''; for (my $i = 0; $i < 10; $i++) { $sessid .= @alpha[rand(@alpha)]; } my $cookie1 = $query->cookie(-name=>'username', -value=>$username, -expires=>$cookieexpire, -domain=>$cookiedomain); my $cookie2 = $query->cookie(-name=>'ma_sessionid', -value=>$sessid, -expires=>$cookieexpire, -domain=>$cookiedomain); my $now = time(); open(NEWSESS, ">>$sessionfile") || error('open'); print NEWSESS "$username $sessid $now 0 0\n"; close(NEWSESS); print $query->header(-COOKIE=>[$cookie1, $cookie2]); $printmainpage = 1; } elsif ($query->param('action') eq 'blankframe') { print "$body\n"; $printmainpage = 0; } elsif ($query->param('action') eq 'list_packages') { my $username = $query->cookie(-name=>'username'); # session checked my $list = list_packages($username); print "$body\n"; print "
\n"; print "\n"; foreach my $package ( @{$list} ) { print ""; print "\n"; print "\n"; print ""; } print "

Package Number

Description

$package->{'pkgnum'}

$package->{'domain'}

{'pkgnum'}&account=$package->{'account'}&domname=$package->{'domain'}\" target=\"rightmainframe\">select
\n"; print "\n"; $printmainpage=0; } elsif ($query->param('action') eq 'list_mailboxes') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $list = list_mailboxes($username, $current_package); my $forwardlist = list_pkg_forwards($username, $current_package); print "$body\n"; print "
\n"; print "\n"; foreach my $account ( @{$list} ) { print ""; print "\n"; print "\n"; print ""; # my $forwardlist = list_forwards($username, $account->{'svcnum'}); # foreach my $forward ( @{$forwardlist} ) { # my $label = qq!=> ! . $forward->{'dest'}; # print "\n"; # } foreach my $forward ( @{$forwardlist} ) { if ($forward->{'srcsvc'} == $account->{'svcnum'}) { my $label = qq!=> ! . $forward->{'dest'}; print "\n"; } } } print "

Username

Password

$account->{'username'}

$account->{'_password'}

{'svcnum'}&mailbox=$account->{'username'}\" target=\"rightmainframe\">change

$label

$label

\n"; print "\n"; $printmainpage=0; } elsif ($query->param('action') eq 'select') { my $username = $query->cookie(-name=>'username'); # session checked $current_package = $query->param('package'); $current_account = $query->param('account'); $current_domname = $query->param('domname'); set_package(); print "$body\n"; print "
\n"; print "
\n"; print "

Selected package $current_package\n"; print "

\n"; print "
\n"; print "\n"; $printmainpage=0; } elsif ($query->param('action') eq 'change') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $mailbox = $query->param('mailbox'); my $list = list_forwards($username, $account); print "$body\n"; print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; foreach my $forward ( @{$list} ) { my $label = qq!=> ! . $forward->{'dest'}; # print "\n"; print "\n"; } print "\n"; print "

Username

$mailbox

$label

$label

{'svcnum'}&mailbox=$mailbox&dest=$forward->{'dest'}\" target=\"rightmainframe\">remove

Password

\n"; print "\n"; print "\n"; print "\n"; print "
\n"; print "
\n"; print "
\n"; print "

You may delete this user and all mailforwarding by pressing Delete This User.\n"; print "

To set or change the password for this user, type the new password in the box next to Password and press Change The Password.\n"; print "

If you would like to have mail destined for this user forwarded to another email address then press the Add Forwarding button.\n"; print "\n"; $printmainpage=0; } elsif ($query->param('deleteaccount') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $mailbox = $query->param('mailbox'); print "$body\n"; print "

\n"; print "

Are you certain you want to delete user $mailbox?\n"; print "

\n"; print "\n"; print "\n"; $printmainpage=0; } elsif ($query->param('deleteaccounty') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); if ( my $error = delete_mailbox ( { 'authuser' => $username, 'account' => $account, } ) ) { print "$body\n"; print "

$error\n"; print "\n"; } else { print "$body\n"; print "

Deleted\n"; print "\n"; } $printmainpage=0; } elsif ($query->param('changepassword') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $_password = $query->param('_password'); if ( my $error = password_mailbox ( { 'authuser' => $username, 'account' => $account, '_password' => $_password, } ) ) { print "$body\n"; print "

$error\n"; print "\n"; } else { print "$body\n"; print "

Changed\n"; print "\n"; } $printmainpage=0; } elsif ($query->param('action') eq 'newmailbox') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; print "$body\n"; print "\n"; print "

\n"; print "\n"; print "\n"; print "

Username

@ " . $current_domname . "

Password

\n"; print "\n"; print "
\n"; print "
\n"; print "
\n"; print "

Use this screen to add a new mailbox user. If the domain name of the email address (the part after the @ sign) is not what you expect then you may need to use List Packages to select the package with the correct domain.\n"; print "

Enter the first portion of the email address in the box adjacent to Username and enter the password for that user in the space next to Password. Then press the button labeled Add The User.\n"; print "

If you do not want to add a new user at this time then select a choice from the menu at the left, such as List Mailboxes.\n"; print "\n"; $printmainpage=0; } elsif ($query->param('addmailbox') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $_password = $query->param('_password'); if ( my $error = add_mailbox ( { 'authuser' => $username, 'package' => $current_package, 'account' => $account, '_password' => $_password, } ) ) { print "$body\n"; print "

$error\n"; print "\n"; } else { print "$body\n"; print "

Created\n"; print "\n"; } $printmainpage=0; } elsif ($query->param('action') eq 'deleteforward') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $svcnum = $query->param('service'); my $mailbox = $query->param('mailbox'); my $dest = $query->param('dest'); print "$body\n"; print "

\n"; print "

Are you certain you want to remove the forwarding from $mailbox to $dest?\n"; print "

\n"; print "\n"; print "\n"; $printmainpage=0; } elsif ($query->param('deleteforwardy') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $service = $query->param('service'); if ( my $error = delete_forward ( { 'authuser' => $username, 'svcnum' => $service, } ) ) { print "$body\n"; print "

$error\n"; print "\n"; } else { print "$body\n"; print "

Forwarding Removed\n"; print "\n"; } $printmainpage=0; } elsif ($query->param('addforward') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $mailbox = $query->param('mailbox'); print "$body\n"; print "\n"; print "

\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
Forward mail from

$mailbox:

to

Destination:

\n"; print "\n"; print "
\n"; print "
\n"; print "
\n"; print "

If you would like mail originally destined for the above address to be forwarded to a different email address then type that email address in the box next to Destination: and press the Add the Forwarding button.\n"; print "

If you do not want to add mail forwarding then select a choice from the menu at the left, such as List Accounts.\n"; $printmainpage=0; } elsif ($query->param('addforwarddst') ne '') { my $username = $query->cookie(-name=>'username'); # session checked select_package($username) unless $current_package; my $account = $query->param('account'); my $dest = $query->param('dest'); if ( my $error = add_forward ( { 'authuser' => $username, 'package' => $current_package, 'source' => $account, 'dest' => $dest, } ) ) { print "$body\n"; print "

$error\n"; print "\n"; } else { print "$body\n"; print "

Forwarding Created\n"; print "\n"; } $printmainpage=0; } elsif ($query->param('action') eq 'navframe') { print "\n"; print "

NCI2000 MAIL ADMIN Web Interface

\n"; print "
Choose Action:

\n"; print "
\n"; print "
    \n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
  • Log Off
  • List Packages
  • List Accounts
  • Add Account
  • \n"; print "


    \n"; print "\n"; $printmainpage = 0; } elsif ($query->param('action') eq 'rightmainframe') { print "$body\n"; print "


    \n"; print "<----- Please choose function on the left menu\n"; print "

    \n"; print "

    Choose Log Off when you are finished. This helps prevent unauthorized access to your accounts.\n"; print "

    Use List Packages when you administer multiple packages. When you have multiple domains at NCI2000 you are likely to have multiple packages. Use of List Packages is not necessary if administer only one package.\n"; print "

    Use List Accounts to view your current arrangement of mailboxes. From this list you my choose to make changes to existing mailboxes or delete mailboxes. If you would like to modify the forwarding associated with a mailbox then choose it from this list.\n"; print "

    Use Add Account when you would like an additional mailbox. After you have added the mailbox you may choose to make additional changes from the list provided by List Accounts.\n"; print "\n"; $printmainpage = 0; } if ($query->param('action') eq 'login') { printheader(); printlogin(); } elsif ($query->param('action') eq 'logout') { destroysession(); printheader(); printlogin(); } elsif ($printmainpage) { print "NCI2000 MAIL ADMIN Web Interface\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; } sub getdatetime { my $today = localtime(time()); my ($day,$mon,$dayofmon,$time,$year) = split(/\s+/,$today); my @datemonths = ("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"); my $numidx = "01"; my ($nummon); foreach my $mons (@datemonths) { if ($mon eq $mons) { $nummon = $numidx; } $numidx++; } return "$year-$nummon-$dayofmon $time"; } sub error { my $error = shift; my $arg1 = shift; printheader(); if ($error eq 'not_admin') { print "Error!\n"; print "$body\n"; print "

    Error!

    \n"; print "Unauthorized attempt to access mail administration.\n"; print "
    Please login again if you think this is an error.\n"; print "
    \n"; print "\n"; } elsif ($error eq 'exists') { print "Error!\n"; print "$body\n"; print "

    Error!

    \n"; print "The user you are trying to enter already exists. Please go back and enter a different username\n"; print "\n"; } elsif ($error eq 'ingroup') { print "Error!\n"; print "$body\n"; print "

    Error!

    \n"; print "This user is already in the group $arg1. Please go back and deselect group $arg1 from the list.\n"; print "
    \n"; print "\n"; } elsif ($error eq 'sess_expired') { print "$body\n"; print "
    Your session has expired.
    \n"; print "

    Please login again HERE
    \n"; print "\n"; } elsif ($error eq 'open') { print "$body\n"; print "
    Unable to open or rename file.
    \n"; print "

    If this continues, please contact your administrator
    \n"; print "\n"; } exit; } #print a html header if not printed yet sub printheader { if ($printheader) { print "Content-Type: text/html\n\n"; $printheader = 0; } } #verify user can access administration sub checksession { my $username = $query->cookie(-name=>'username'); my $sessionid = $query->cookie(-name=>'ma_sessionid'); if ($sessionid eq '') { printheader(); if ($query->param()) { error('sess_expired'); } else { printlogin(); exit; } } my $now = time(); my $founduser = 0; open(SESSFILE, "$sessionfile") || error('open'); error('open') if -l "$tmpdir/adminsess.$$"; open(NEWSESS, ">$tmpdir/adminsess.$$") || error('open'); while () { chomp(); my ($user, $sess, $time, $pkgnum, $svcdomain, $domname) = split(/\s+/); next if $now - $sessexpire > $time; if ($username eq $user && !$founduser) { if ($sess eq $sessionid) { $founduser = 1; print NEWSESS "$user $sess $now $pkgnum $svcdomain $domname\n"; $current_package=$pkgnum; $current_account=$svcdomain; $current_domname=$domname; next; } } print NEWSESS "$user $sess $time $pkgnum $svcdomain $domname\n"; } close(SESSFILE); close(NEWSESS); system("mv $tmpdir/adminsess.$$ $sessionfile"); error('sess_expired') unless $founduser; my $cookie1 = $query->cookie(-name=>'username', -value=>$username, -expires=>$cookieexpire, -domain=>$cookiedomain); my $cookie2 = $query->cookie(-name=>'ma_sessionid', -value=>$sessionid, -expires=>$cookieexpire, -domain=>$cookiedomain); print $query->header(-COOKIE=>[$cookie1, $cookie2]); $printheader = 0; return 0; } sub destroysession { my $username = $query->cookie(-name=>'username'); my $sessionid = $query->cookie(-name=>'ma_sessionid'); if ($sessionid eq '') { printheader(); if ($query->param()) { error('sess_expired'); } else { printlogin(); exit; } } my $now = time(); my $founduser = 0; open(SESSFILE, "$sessionfile") || error('open'); error('open') if -l "$tmpdir/adminsess.$$"; open(NEWSESS, ">$tmpdir/adminsess.$$") || error('open'); while () { chomp(); my ($user, $sess, $time, $pkgnum, $svcdomain, $domname) = split(/\s+/); next if $now - $sessexpire > $time; if ($username eq $user && !$founduser) { if ($sess eq $sessionid) { $founduser = 1; next; } } print NEWSESS "$user $sess $time $pkgnum $svcdomain $domname\n"; } close(SESSFILE); close(NEWSESS); system("mv $tmpdir/adminsess.$$ $sessionfile"); error('sess_expired') unless $founduser; $printheader = 0; return 0; } # checks the username and pass against the database sub checkuserpass { my $username = shift; my $password = shift; my $error = authenticate ( { 'authuser' => $username, '_password' => $password, } ); if ($error eq "$username OK") { return 1; }else{ return 0; } } #printlogin prints a login page sub printlogin { print "$body\n"; print "
    Please login to access MAIL ADMIN
    \n"; print "
    \n"; print "
    Email Address:   \n"; print "
    Email Password: \n"; print "
    \n"; print "
    \n"; print "\n"; } #select_package chooses a administrable package if more than one exists sub select_package { my $user = shift; my $packages = list_packages($user); if (scalar(@{$packages}) eq 1) { $current_package = @{$packages}[0]->{'pkgnum'}; set_package(); } if (scalar(@{$packages}) > 1) { # print $query->redirect("$cgi\?action=list_packages"); print "

    No package selected. You must first select a package.\n"; exit; } } sub set_package { my $username = $query->cookie(-name=>'username'); my $sessionid = $query->cookie(-name=>'ma_sessionid'); if ($sessionid eq '') { printheader(); if ($query->param()) { error('sess_expired'); } else { printlogin(); exit; } } my $now = time(); my $founduser = 0; open(SESSFILE, "$sessionfile") || error('open'); error('open') if -l "$tmpdir/adminsess.$$"; open(NEWSESS, ">$tmpdir/adminsess.$$") || error('open'); while () { chomp(); my ($user, $sess, $time, $pkgnum, $svcdomain, $domname) = split(/\s+/); next if $now - $sessexpire > $time; if ($username eq $user && !$founduser) { if ($sess eq $sessionid) { $founduser = 1; print NEWSESS "$user $sess $time $current_package $current_account $current_domname\n"; next; } } print NEWSESS "$user $sess $time $pkgnum $svcdomain $domname\n"; } close(SESSFILE); close(NEWSESS); system("mv $tmpdir/adminsess.$$ $sessionfile"); error('sess_expired') unless $founduser; $printheader = 0; return 0; }