#!/usr/local/bin/perl
use strict;
use CGI qw(-nosticky :standard);
use CGI::Carp ('fatalsToBrowser');
use CGI::Cookie;
use Mail::vpopmail;
use Mail::VRFY;
use DBI;
my $dbun = 'db_username';
my $dbpw = 'db_password';
my $dsn = 'DBI:Sybase:server=sql.example.net;database=esec';
my @admins = qw/postmaster@example.net otherguy@example.net/;
my $q = new CGI();
my $me = $ENV{'SCRIPT_NAME'};
my $esecurl = 'http://' . $ENV{'HTTP_HOST'} . '/cgi-bin/eseccgi.pl';
my $url = 'http://' . $ENV{'HTTP_HOST'} . $me;
my %cookies = fetch CGI::Cookie;
if( ($cookies{'sess_id'} =~ /sess_id=(.+)\;/) && (my $sess_id = $1) ){
my $dbh = DBI->connect($dsn, $dbun, $dbpw,{PrintError => 1});
my $sql = 'SELECT emailid,email FROM accounts WHERE session_id = ' . $dbh->quote($sess_id);
my $sth = $dbh->prepare($sql);
$sth->execute;
my $row=$sth->fetchrow_arrayref;
if((my $emailid = $row->[0]) && (my $email = $row->[1])){
print $q->header(),
"
\n",
"ESec Admin Console\n",
'', "\n",
"\n";
my $vchkpw = Mail::vpopmail->new(cache => 0, debug => 0);
my $dir = $vchkpw->get(email => $email, field => 'dir');
if((my $newaddr = $q->param('newaddr')) && (my $method=$q->param('method'))){
my $newpass = $q->param('newpass');
my $newname = $q->param('newname');
if($newaddr =~ /[A-Z]/){
print "lower-case, please\n";
exit;
}
if($method eq 'esec'){
die "invalid password\n" unless($newpass);
die "invalid Real Name\n" unless($newname);
}
my $domain = (split(/\@/, $email))[1];
my $fulladdr = $newaddr . '@' . $domain;
my $res = Mail::VRFY::CheckAddress(addr => $fulladdr, method => 'syntax', debug => 0);
if($res){
print "$fulladdr is not a good enough looking email address.";
exit;
}
if(open(FILE, ">$dir/.qmail-$newaddr")){
if($method eq 'esec'){
print FILE "| /usr/local/script/esec.pl $fulladdr\n";
}else{
print FILE "&${newaddr}\@mail.$domain\n";
}
close FILE;
chmod(0600, "$dir/.qmail-$newaddr") || die "couldnt chmod $dir/.qmail-$newaddr: $!\n";
}else{
die "could not write to $dir/.qmail-$newaddr: $!\n";
}
if($method eq 'esec'){
system('/home/vpopmail/bin/vadduser', $fulladdr, $newpass);
srand(time() ^($$ + ($$ << 15)));
my @a = grep {/[a-zA-Z0-9]/} map {chr($_)} (0..256);
my $salt = $a[ rand( @a ) ] . $a[ rand(@a) ];
my $crypt = crypt($newpass, $salt);
my $sql = 'INSERT INTO accounts (email,crypt,name) VALUES (';
$sql .= $dbh->quote($fulladdr) . ',' . $dbh->quote($crypt) . ',' . $dbh->quote($newname) . ')';
my $sth = $dbh->prepare($sql);
$sth->execute;
}
print '';
exit;
}elsif((my $addr=$q->param('addr')) && ($q->param('delete') || $q->param('convert'))){
if($addr =~ /[A-Z]/){
print "lower-case, please\n";
exit;
}
my $domain = (split(/\@/, $email))[1];
my $fulladdr = $addr . '@' . $domain;
foreach my $admin (@admins){
if($admin eq $fulladdr){
print "will not delete administrative user\n";
exit;
}
}
open(FILE, "$dir/.qmail-$addr") || die "couldnt open $dir/.qmail-$addr: $!\n";
chop(my $line = );
close FILE;
my $method = ($line =~ /esec.pl/) ? 'esec' : 'plain';
if($q->param('delete')){
if(unlink("$dir/.qmail-$addr")){
if($method eq 'esec'){
system('/home/vpopmail/bin/vdeluser', $fulladdr);
my $sql = 'SELECT emailid FROM accounts WHERE email = ' . $dbh->quote($fulladdr);
my $sth = $dbh->prepare($sql);
$sth->execute;
while(my $row = $sth->fetchrow_arrayref){ # just in case
if(my $emailid = $row->[0]){
foreach my $table ('accounts','messages','challenges','email_whitelists','email_blacklists','header_whitelists','header_blacklists'){
my $sql = "DELETE FROM $table WHERE emailid = " . $dbh->quote($emailid);
my $sth = $dbh->prepare($sql);
$sth->execute;
}
}
}
}
print '';
exit;
}else{
print "could not delete $dir/.qmail-$addr: $!\n";
}
}elsif($q->param('convert')){
# convert
if($method eq 'esec'){
if(open(FILE, ">${dir}/.qmail-${addr}")){
print FILE "&${addr}\@mail.${domain}\n";
close FILE;
my $sql = 'SELECT emailid FROM accounts WHERE email = ' . $dbh->quote($fulladdr);
my $sth = $dbh->prepare($sql);
$sth->execute;
while(my $row = $sth->fetchrow_arrayref){ # just in case
if(my $emailid = $row->[0]){
foreach my $table ('accounts','messages','challenges','email_whitelists','email_blacklists','header_whitelists','header_blacklists'){
my $sql = "DELETE FROM $table WHERE emailid = " . $dbh->quote($emailid);
my $sth = $dbh->prepare($sql);
$sth->execute;
}
}
}
print '';
}else{
print "cannot write to $dir/.qmail-$addr: $!\n";
exit;
}
}elsif($method eq 'plain'){
# make into an esec account
my ($first,$last) = $addr =~ /^(.)(.+)/;
my $newname = "$first $last";
my $randpass = getrand(8);
$url .= "?newaddr=${addr}&method=esec&newpass=${randpass}&newname=${newname}";
open(MAIL, "|/usr/lib/sendmail -t");
print MAIL "To: ${fulladdr}\n",
"Subject: Email Secretary account\n",
"\n",
"Your Email Secretary account has been initialized.\n",
"You may log in at the following URL:\n",
"${esecurl}\n",
"Username: $fulladdr\n",
"Password: $randpass\n";
close MAIL;
print '';
}else{
die "method error: $method\n";
}
}else{
die "confuzzled";
}
}else{
if(opendir(DIR, $dir)){
print '
', "\n";
foreach my $file (sort grep {/^.qmail-/} readdir DIR){
my ($addr) = $file =~ /.qmail-(.+)/;
next if ($addr eq 'default');
if(open(FILE, "$dir/$file")){
chop(my $line = );
close FILE;
my $method = ($line =~ /esec.pl/) ? 'esec' : 'plain';
print $q->start_form('post',$me),
"