#!/usr/bin/perl -wT #---------------------------------------------------------------------- # heading : Administration # description : Domain pseudonyms # navigation : 4000 4736 # # Author dungog.net # #---------------------------------------------------------------------- package esmith; use strict; use CGI ':all'; use CGI::Carp qw(fatalsToBrowser); use esmith::cgi; use esmith::config; use esmith::util; use esmith::db; sub showInitial ($$); #main form sub performSave ($); sub modifyOptions ($$); #vd authority and options sub performModifyOptions ($); sub modifyEmail ($$); #vd email sub editEmail ($$); sub performModifyEmail ($); sub removeEmail ($); BEGIN { # Clear PATH and related environment variables so that calls to # external programs do not cause results to be tainted. See # "perlsec" manual page for details. $ENV {'PATH'} = '/usr/sbin:/usr/bin:/usr/local/bin'; $ENV {'SHELL'} = '/bin/bash'; delete $ENV {'ENV'}; } esmith::util::setRealToEffective (); $CGI::POST_MAX=1024 * 100; # max 100K posts $CGI::DISABLE_UPLOADS = 1; # no uploads my %conf; tie %conf, 'esmith::config'; my %accounts; tie %accounts, 'esmith::config', '/home/e-smith/db/accounts'; my %domains; tie %domains, 'esmith::config', '/home/e-smith/db/domains'; my %dungog; tie %dungog, 'esmith::config', '/home/e-smith/db/dungog'; #------------------------------------------------------------ # examine state parameter and display the appropriate form #------------------------------------------------------------ my $q = new CGI; if (! grep (/^state$/, $q->param)) { showInitial ($q, ''); } elsif ($q->param ('state') eq "save") { performSave ($q); } #options elsif ($q->param ('state') eq "modifyOptions") { modifyOptions ($q, ''); } elsif ($q->param ('state') eq "performModifyOptions") { performModifyOptions ($q); } #pseudonyms elsif ($q->param ('state') eq "email") { modifyEmail ($q, ''); } elsif ($q->param ('state') eq "edit") { editEmail ($q, ''); } elsif ($q->param ('state') eq "performEmail") { performModifyEmail ($q); } elsif ($q->param ('state') eq "remove") { removeEmail ($q); } else { esmith::cgi::genStateError ($q, \%conf); } exit (0); ######################################################################### sub showInitial ($$) { my ($q, $msg) = @_; my @domains = db_get(\%domains); if ($msg eq '') { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Domain pseudonyms'); } else { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Domain pseudonyms'); print $q->h4 ('Operation status report'); print $q->p ($msg); print $q->hr; } print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->p ('Set pseudonyms for a single domain,
This panel just shows the pseudonyms for a single domain.
see also the Pseudonyms panel.'); my $numDomains = @domains; if ($numDomains == 0) { print $q->p ($q->b ('There are no virtual domains in the system.')); } else { print $q->p ($q->b ("Current List of Domains.")); print ""; print $q->Tr (esmith::cgi::genSmallCell ($q, $q->b ('Domain')), esmith::cgi::genSmallCell ($q, $q->b ('Description')), esmith::cgi::genSmallCell ($q, $q->b ('Mail Delivery')), esmith::cgi::genSmallCell ($q, $q->b ('Delegation'))); my $domain; foreach $domain (sort @domains) { my $desc = db_get_prop(\%domains, $domain, "Description") || ''; my $owner = db_get_prop(\%dungog, $domain, "owner") || 'admin'; my $group = db_get_prop(\%dungog, $domain, "group") || 'everyone'; if ($group eq 'Administrator') { $group = $owner; } print $q->Tr (esmith::cgi::genSmallCell ($q, $domain), esmith::cgi::genSmallCell ($q, $desc), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=email&domain=" . $domain}, 'Modify ...')), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=modifyOptions&domain=" . $domain}, $owner.'::'.$group))); } print '
'; } print $q->p ($q->b ("Save Settings")); print $q->p ("Pseudonym settings are not activated until you save them here"); print $q->Tr (esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => 'Save'))); print $q->hidden (-name => 'MailServer', -override => 1, -default => 'skipMS'); print $q->hidden (-name => 'state', -override => 1, -default => 'save'); print $q->endform; print $q->p ($q->hr, $q->font ({size => "-1"}, "Copyright dungog.net")); print ''; print ''; print $q->end_html; } sub modifyOptions ($$) { my ($q, $msg) = @_; my $domain = $q->param ('domain') || ''; if ($msg eq '') { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify Domain pseudonyms - Options.'); } else { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify Domain pseudonyms - Options.'); print $q->h4 ('Operation status report'); print $q->p ($msg); print $q->hr; } print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); # find system users my @userlist = ('admin','everyone'); push (@userlist, '-- groups --'); foreach (sort keys %accounts) { push (@userlist, $_) if (db_get_type(\%accounts, $_) eq 'group'); } push (@userlist, '-- users --'); foreach (sort keys %accounts) { push (@userlist, $_) if (db_get_type(\%accounts, $_) eq 'user'); } my @grouplist = ('everyone','Administrator'); foreach (keys %accounts) { push (@grouplist, $_) if (db_get_type(\%accounts, $_) eq 'group'); } print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, $q->Tr (esmith::cgi::genCell ($q, "Domain name:"), esmith::cgi::genCell ($q, $domain)), esmith::cgi::genTextRow ($q, 'The alternative administrator is used delegate a domain to a user or group.
They can then add email addresses with userpanel-domains
First delegate them here, then delegate the userpanel with userpanel access.
For full access delegate this panel, dungog-domains.'), esmith::cgi::genWidgetRow ($q, "Alternative administrator", $q->popup_menu (-name => "owner", -values => [ @userlist ], -default => db_get_prop(\%dungog, $domain, "owner") || 'admin')), esmith::cgi::genTextRow ($q, "Restrict the userlist in the email dropdown box to the Administrator or members of a group. "), esmith::cgi::genWidgetRow ($q, "Alternative group", $q->popup_menu (-name => "group", -values => [ sort @grouplist ], -default => db_get_prop(\%dungog, $domain, "group") || 'everyone')), esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => 'Modify'))); print $q->hidden (-name => 'domain', -override => 1, -default => $domain); print $q->hidden (-name => 'state', -override => 1, -default => 'performModifyOptions'); print $q->endform; print $q->p ($q->hr, $q->font ({size => "-1"}, "Copyright dungog.net")); print ''; print ''; print $q->end_html; } #------------------------------------------------------------ # Modify Domain #------------------------------------------------------------ sub performModifyOptions ($) { my ($q) = @_; my $domain = $q->param ('domain'); my $owner = $q->param ('owner'); my $group = $q->param ('group'); unless (exists $dungog {$domain}) { db_set(\%dungog, $domain, 'domain'); } db_set_prop(\%dungog, $domain, 'owner', $owner); db_set_prop(\%dungog, $domain, 'group', $group); showInitial ($q, "Successfully modified domain $domain."); } #------------------------------------------------------------ # modify email #------------------------------------------------------------ sub modifyEmail ($$) { my ($q, $msg) = @_; my $domain = $q->param ('domain'); if ($msg eq '') { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify domain Email.'); } else { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify domain Email.'); print $q->h4 ('Operation status report'); print $q->p ($msg); print $q->hr; } print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); #commom with userpanel print $q->p ($q->b ("Delegate the domain \"$domain\"")); print $q->Tr (esmith::cgi::genTextRow ($q, 'Forward all email for this domain to a remote mailserver, either use a FQDN mail.domain.net or an IP address. Or leave blank and forward domain specific pseudonyms below.
CAUTION. enable your remote server before delegating or you may create a mail loop.')); print '

'; print $q->Tr (esmith::cgi::genNameValueRow ($q,"Server Name or IP", "MailServer", db_get_prop(\%domains, $domain, "MailServer") || '')); # get all pseudonyms my @vdemail = (); foreach (keys %accounts) { push (@vdemail, $_) if (db_get_type(\%accounts, $_) eq 'pseudonym'); } # find email for this domain my @vdemail2 = (); foreach (@vdemail) { (my $u, my $d) = split (/@/, $_); push (@vdemail2, $u) if (defined $d and $d eq $domain); } #are there any ? my $vdemail = @vdemail2; if ($vdemail == 0) { print $q->p ($q->b ("There are no pseudonyms for the domain \"$domain\"")); print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=edit&domain=$domain&pseu=new2user"}, 'Click here'), 'to add your first pseudonym.'); } else { print $q->p ($q->b ("Current List of pseudonyms for the domain \"$domain\"")); print $q->p ($q->a ({href => $q->url (-absolute => 1) . "?state=edit&domain=$domain&pseu=new2user"}, 'Click here'), "to add another pseudonym."); print ""; print $q->Tr (esmith::cgi::genSmallCell ($q, $q->b ('Pseudonyms')), esmith::cgi::genSmallCell ($q, $q->b ('Local user')), $q->td (' '), $q->td (' ')); foreach my $pseu (sort @vdemail2) { my $acct = db_get_prop(\%accounts, "$pseu\@$domain", "Account") || ''; print $q->Tr (esmith::cgi::genSmallCell ($q, $pseu), esmith::cgi::genSmallCell ($q, $acct), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=edit&domain=$domain&acct=$acct&pseu=$pseu"}, 'Modify...')), esmith::cgi::genSmallCell ($q, $q->a ({href => $q->url (-absolute => 1) . "?state=remove&domain=$domain&pseu=$pseu"}, 'Remove...'))); } print '
'; } print $q->p ($q->b ("Save Settings")); print $q->p ("Pseudonym settings are not activated until you save them here"); print $q->Tr (esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => 'Save'))); print $q->hidden (-name => 'state', -override => 1, -default => 'save'); print $q->hidden (-name => 'domain', -override => 1, -default => $domain); print $q->endform; print $q->p ($q->hr, $q->font ({size => "-1"}, "Copyright dungog.net")); print ''; print ''; print $q->end_html; } #------------------------------------------------------------ # Edit Email address #------------------------------------------------------------ sub editEmail ($$) { my ($q, $msg) = @_; my $domain = $q->param ('domain'); my $acct = $q->param ('acct') || ''; my $pseu = $q->param ('pseu') || ''; my $user1 = $q->param ('pseu'); my $newuser = ''; if ($pseu eq 'new2user') { $newuser = 'new'; $pseu = ''; } # find system users in group #my $owner = $ENV{'REMOTE_USER'}; #userpanel my $owner = db_get_prop(\%dungog, $domain, "owner") || ''; my $group = db_get_prop(\%dungog, $domain, "group") || 'everyone'; my @selected ; my $userlist = db_get_prop(\%accounts, $group, 'Members') || ''; if ($group eq 'everyone') { foreach (keys %accounts) { push (@selected, $_) if (db_get_type(\%accounts, $_) eq 'user'); } } elsif ($group eq 'Administrator') { @selected = ($owner); } else { @selected = split (/,/, $userlist); } if ($msg eq '') { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify Email Address.'); } else { esmith::cgi::genHeaderNonCacheable ($q, \%conf, 'Modify Email Address.'); print $q->h4 ('Operation status report'); print $q->p ($msg); print $q->hr; } my @sorted = sort @selected; print $q->startform (-method => 'POST', -action => $q->url (-absolute => 1)); print $q->table ({border => 0, cellspacing => 0, cellpadding => 4}, $q->Tr (esmith::cgi::genCell ($q, "Domain name:"), esmith::cgi::genCell ($q, $domain)), esmith::cgi::genTextRow ($q, "Enter a pseudonym.
". "NOTE. \@$domain is added for you."), esmith::cgi::genNameValueRow ($q, "Pseudonym", "pseu", $pseu ,), esmith::cgi::genWidgetRow ($q, "Local Account", $q->popup_menu (-name => "acct", -values => [ '', @sorted ], -default => $acct )), esmith::cgi::genButtonRow ($q, $q->submit (-name => 'action', -value => 'Save'))); print $q->hidden (-name => 'domain', -override => 1, -default => $domain); print $q->hidden (-name => 'user1', -override => 1, -default => $user1); print $q->hidden (-name => 'newuser', -override => 1, -default => $newuser); print $q->hidden (-name => 'state', -override => 1, -default => 'performEmail'); print $q->endform; print $q->p ($q->hr, $q->font ({size => "-1"}, "Copyright dungog.net")); print ''; print ''; print $q->end_html; } sub performModifyEmail ($) { my ($q) = @_; my $domain = $q->param ('domain'); my $acct = $q->param ('acct'); my $pseu = $q->param ('pseu'); my $Pseudonym = "$pseu\@$domain"; my $user1 = $q->param ('user1'); my $newuser = $q->param ('newuser'); # get all pseudonyms my @vdemail = (); foreach (keys %accounts) { push (@vdemail, $_) if (db_get_type(\%accounts, $_) eq 'pseudonym'); } #don't overwite existing users if ($newuser eq 'new2user') { foreach (@vdemail) { if ($_ eq $Pseudonym) { editEmail ($q, "Error: Pseudonym already exists."); return; } } } if ($pseu =~ /^([a-zA-Z0-9][\-\_\.a-zA-Z0-9]*)$/) { $pseu = $1; } else { editEmail ($q, "Error: unexpected characters in Pseudonym, \"$pseu\"."); return; } if ($acct eq '') { editEmail ($q, "Error: please select a local account."); return; } unless (exists $accounts {$Pseudonym}) { db_set(\%accounts, $Pseudonym, 'pseudonym'); } db_set_prop(\%accounts, $Pseudonym, 'Account', $acct); #we changed the Pseudonym, so delete the old if ($user1 ne $pseu) { db_delete(\%accounts, "$user1\@$domain"); } showInitial ($q, "Successfully modified Pseudonym.\n"); #showInitial ($q, "Successfully modified Pseudonym for $domain." ,"$domain"); } sub removeEmail ($) { my ($q) = @_; my $pseu = $q->param ('pseu'); my $domain = $q->param ('domain'); my $Pseudonym = "$pseu\@$domain"; db_delete(\%accounts, $Pseudonym); showInitial ($q, "Successfully removed Pseudonym."); #showInitial ($q, "Successfully removed Pseudonym for $domain." ,"$domain"); } sub performSave ($) { my ($q) = @_; my $domain = $q->param ('domain'); my $MailServer = $q->param ('MailServer') || ''; unless ($MailServer eq 'skipMS') { if ($MailServer eq '') { db_delete_prop(\%domains, $domain, 'MailServer'); } else { db_set_prop(\%domains, $domain, 'MailServer', $MailServer); } } system ("/sbin/e-smith/signal-event", "email-update") == 0 or die ("Error occurred while restarting email.\n"); showInitial ($q, "Settings saved and email restarted."); #showInitial ($q, "Settings saved and email restarted." ,"$domain"); }