#!/usr/bin/perl
$|=1;
$install_p = 1;
# Check for fresh install, if it's not, we skip the configuration step
if ( $ARGV[0] eq "upgrade" ) {
  $install_p = 0;
}
# Setup Webmin environment
$no_acl_check++;
$ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin";
$ENV{'WEBMIN_VAR'} ||= "/var/webmin";
$ENV{'MINISERV_CONFIG'} = $ENV{'WEBMIN_CONFIG'}."/miniserv.conf";
open(CONF, "$ENV{'WEBMIN_CONFIG'}/miniserv.conf") || die "Failed to open miniserv.conf";
while(<CONF>) {
	if (/^root=(.*)/) {
		$root = $1;
		}
	}
close(CONF);
$root ||= "/usr/libexec/webmin";
chdir($root);
$0 = "$root/virtualmin_base.pl";
require './web-lib.pl';
&init_config();

# Stuff we only do on fresh install
if ( $install_p == "1" ) {
	# Configure virtual maps in Postfix
	print "Configuring Postfix\n";
	&foreign_require("postfix", "postfix-lib.pl");
	# Debian doesn't get a default main.cf unless apt-get is run
	# interactively.
	unless ( -e "/etc/postfix/main.cf" ) { 
	  system("cp /usr/share/postfix/main.cf.debian /etc/postfix/main.cf");
	} 
	if (!&postfix::get_real_value("virtual_alias_maps")) {
		&postfix::set_current_value("virtual_alias_maps",
					    "hash:/etc/postfix/virtual", 1);
		}
	&postfix::ensure_map($postfix::virtual_maps);
	&postfix::regenerate_virtual_table();
	&postfix::set_current_value("mailbox_command",
		"/usr/bin/procmail-wrapper -o -a \$DOMAIN -d \$LOGNAME", 1);
	&postfix::set_current_value("home_mailbox", "Maildir/", 1);
	&postfix::set_current_value("inet_interfaces", "all", 1);
	# Add smtp auth stuff to main.cf
	&postfix::set_current_value("smtpd_sasl_auth_enable", "yes", 1);
	&postfix::set_current_value("smtpd_sasl_security_options", "noanonymous", 1);
	&postfix::set_current_value("broken_sasl_auth_clients", "yes", 1);
	&postfix::set_current_value("smtpd_recipient_restrictions", "permit_mynetworks permit_sasl_authenticated reject_unauth_destination", 1);
	$mydest = &postfix::get_current_value("mydestination");
	$myhost = &get_system_hostname();
	if ($mydest !~ /\Q$myhost\E/) {
		&postfix::set_current_value("mydestination",
					    $mydest.", ".$myhost, 1);
		}

	# And master.cf
	$master = &postfix::get_master_config();
	($smtp) = grep { $_->{'name'} eq 'smtp' } @$master;
	$smtp || die "Failed to find SMTP postfix service!";
	if ($smtp->{'command'} !~ /smtpd_sasl_auth_enable/) {
		$smtp->{'command'} .= " -o smtpd_sasl_auth_enable=yes";
		&postfix::modify_master($smtp);
		}
	delete($main::file_cache{$postfix::config{'postfix_config_file'}});
	&postfix::reload_postfix();

	# Make sure Postfix is started at boot, and sendmail isn't
	print "Enabling Postfix and disabling Sendmail\n";
	&foreign_require("init", "init-lib.pl");
	if ( -e "/usr/sbin/alternatives" ) {
	  system("/usr/sbin/alternatives --set mta /usr/sbin/sendmail.postfix");
	}
	&init::enable_at_boot("postfix");
	&init::disable_at_boot("sendmail");
	&init::disable_at_boot("exim4");
	&foreign_require("sendmail", "sendmail-lib.pl");
	if (&sendmail::is_sendmail_running()) {
		&sendmail::stop_sendmail();
		}
	if (!&postfix::is_postfix_running()) {
		$err = &postfix::start_postfix();
		print STDERR "Failed to start Postfix!\n" if ($err);
		}

	print "Configuring Dovecot for POP3 and IMAP\n";
	&foreign_require("dovecot", "dovecot-lib.pl");
	$conf = &dovecot::get_config();
	&dovecot::save_directive($conf, "protocols", "imap imaps pop3 pop3s");
	&dovecot::save_directive($conf, "default_mail_env","maildir:~/Maildir");
	if (&dovecot::find($conf, "pop3_uidl_format", 2)) {
		&dovecot::save_directive($conf, "pop3_uidl_format",
					 "%08Xu%08Xv");
		}
	&flush_file_lines($dovecot::config{'dovecot_config'});
	print "Enabling Dovecot POP3 and IMAP servers\n";
	&init::enable_at_boot("dovecot");
	if (!&dovecot::is_dovecot_running()) {
	  $err = &dovecot::start_dovecot();
	  print STDERR "Failed to start Dovecot POP3/IMAP server!\n" if ($err);
	  }

	# SASL SMTP authentication
	print "Enabling SMTP Authentication\n";
	&init::enable_at_boot("saslauthd");
  if ($gconfig{'os_type'} eq "debian-linux" or $gconfig{'os_type'} eq "ubuntu-linux") {
    my $fn="/etc/default/saslauthd";
    $sasldefault = &read_file_lines($fn) or die "Failed to open $fn!";
    my $idx = &indexof("# START=yes", @$sasldefault);
    $sasldefault->[$idx]="START=yes";
    push(@$sasldefault, "PARAMS=\"-m /var/spool/postfix/var/run/saslauthd -r\""); 
    flush_file_lines($fn);
    $cf="/etc/postfix/sasl/smtpd.conf";
    system("mkdir -p -m 755 /var/spool/postfix/var/run/saslauthd");
  }
  else {
    # I'm not liking all of this jiggery pokery...need a better way to 
    # detect which lib directory to work in.XXX
    if ( -e "/usr/lib64" && -e "/usr/lib64/perl" ) { $libdir = "lib64"; }
    else { $libdir = "lib"; }
    if ( -e "/usr/$libdir/sasl2" ) { $cf="/usr/$libdir/sasl2/smtpd.conf"; }
    elsif ( -e "/usr/$libdir/sasl" ) { $cf="/usr/$libdir/sasl/smtpd.conf"; }
    else { print "No sasl library directory found.  SASL authentication probably won't work"; }
  }
  if (! -e $cf ) {
    system("touch $cf");
  }
  $smtpdconf= &read_file_lines($cf) or die "Failed to open $cf!";
  $idx = &indexof("", @$smtpdconf);
  if ($idx < 0) {
    push(@$smtpdconf, "pwcheck_method: saslauthd");
    push(@$smtpdconf, "mech_list: plain login");
    &flush_file_lines($cf);
  }   
	$cmd = "/etc/init.d/saslauthd start";
	&proc::safe_process_exec($cmd, 0, 0, STDOUT, undef, 1);

	# Tell Virtualmin to use Postfix, and enable all features
	print "Configuring Virtualmin\n";
	%vconfig = &foreign_config("virtual-server");
	$vconfig{'mail_system'} = 0;
	$vconfig{'home_base'} = "/home";
	$vconfig{'spam'} = 1;
	$vconfig{'virus'} = 1;
	$vconfig{'ssl'} = 2;
	$vconfig{'ftp'} = 2;
	$vconfig{'postgresql'} = 1;
	$vconfig{'logrotate'} = 3;
	$vconfig{'default_procmail'} = 1;
	$vconfig{'bind_spfall'} = 0;
	$vconfig{'bind_spf'} = "yes";
	$vconfig{'spam_delivery'} = "\$HOME/Maildir/.spam/";

	# Configure the Read User Mail module to look for sub-folders
	# under ~/Maildir
	%mconfig = &foreign_config("mailboxes");
	$mconfig{'mail_usermin'} = "Maildir";
	$mconfig{'from_virtualmin'} = 1;
	&save_module_config(\%mconfig, "mailboxes");

	# Setup the Usermin read mail module
	$cfile = "$usermin::config{'usermin_dir'}/mailbox/config";
	&read_file($cfile, \%mailconfig);
	($map) = &postfix::get_maps_files(&postfix::get_real_value(
			$postfix::virtual_maps));
	$map ||= "/etc/postfix/virtual";
	if (!$mailconfig{'from_map'}) {
		$mailconfig{'from_map'} = $map;
		$mailconfig{'from_format'} = 1;
		}
	$mailconfig{'mail_system'} = 4;
	$mailconfig{'pop3_server'} = 'localhost';
	$mailconfig{'mail_qmail'} = undef;
	$mailconfig{'mail_dir_qmail'} = 'Maildir';
	$mailconfig{'server_attach'} = 0;
	&write_file($cfile, \%mailconfig);

	# Set the mail folders subdir to Maildir
	$ucfile = "$usermin::config{'usermin_dir'}/mailbox/uconfig";
	&read_file($ucfile, \%umailconfig);
	$umailconfig{'mailbox_dir'} = 'Maildir';
	&write_file($ucfile, \%umailconfig);

	# Set the default Usermin ACL to only allow access to email modules
	&usermin::save_usermin_acl("user",
		[ "mailbox", "changepass", "spam", "filter" ]);

	# Lock down the Usermin file manager and browser to users' homes
	$cfile = "$usermin::config{'usermin_dir'}/file/config";
	&read_file($cfile, \%fileconfig);
	$fileconfig{'home_only'} = 1;
	&write_file($cfile, \%fileconfig);
	$afile = "$usermin::config{'usermin_dir'}/user.acl";
	&read_file($afile, \%uacl);
	$uacl{'root'} = '';
	&write_file($afile, \%uacl);

	# Create a global Procmail rule to deliver to ~/Maildir/
	print "Configuring Procmail\n";
	&foreign_require("procmail", "procmail-lib.pl");
	local @recipes = &procmail::get_procmailrc();
	foreach $r (@recipes) {
		if ($r->{'name'} eq "DEFAULT") {
			$defrec = $r;
			}
		elsif ($r->{'name'} eq "ORGMAIL") {
			$orgrec = $r;
			}
		}
	if ($defrec) {
		# Fix up this DEFAULT entry
		$defrec->{'value'} = '$HOME/Maildir/';
		&procmail::modify_recipe($defrec);
		}
	else {
		# Prepend a DEFAULT entry
		$defrec = { 'name' => 'DEFAULT',
			    'value' => '$HOME/Maildir/' };
		if (@recipes) {
			&procmail::create_recipe_before($defrec, $recipes[0]);
			}
		else {
			&procmail::create_recipe($defrec);
			}
		}
	if ($orgrec) {
		# Fix up this ORGMAIL entry
		$orgrec->{'value'} = '$HOME/Maildir/';
		&procmail::modify_recipe($orgrec);
		}
	else {
		# Prepend a ORGMAIL entry
		$orgrec = { 'name' => 'ORGMAIL',
			    'value' => '$HOME/Maildir/' };
		if (@recipes) {
			&procmail::create_recipe_before($orgrec, $recipes[0]);
			}
		else {
			&procmail::create_recipe($orgrec);
			}
		}
	}

# Fix up the Postfix config to use the procmail wrapper, regardless if we are
# installing or upgrading (but only if spam filtering is active)
&foreign_require("postfix", "postfix-lib.pl");
$mailcmd = &postfix::get_current_value("mailbox_command");
%vconfig = &foreign_config("virtual-server");
if ($vconfig{'spam'} && $mailcmd =~ /procmail/ &&
    $mailcmd !~ /procmail-wrapper/) {
	&postfix::set_current_value("mailbox_command",
		"/usr/bin/procmail-wrapper -o -a \$DOMAIN -d \$LOGNAME", 1);
	&postfix::reload_postfix();
	}

