From 7d89f56a66811cddbfdb60abea19f6945f1f51d9 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 2 Sep 2008 13:19:31 +0000
Subject: [PATCH] - Added support for openSUSE 11.0

---
 INSTALL_OPENSUSE_11.txt                   | 212 ++++++
 install/dist/conf/opensuse110.conf.php    |  86 +++
 install/dist/lib/opensuse110.lib.php      | 733 ++++++++++++++++++++
 install/install.php                       |   2 +-
 install/lib/install.lib.php               |  11 +
 install/lib/installer_base.lib.php        |  17 +-
 install/tpl/opensuse_amavisd_conf.master  | 784 ++++++++++++++++++++++
 install/tpl/opensuse_pureftpd_conf.master | 447 ++++++++++++
 install/update.php                        |   2 +-
 server/conf/vhost.conf.master             |   7 +
 10 files changed, 2289 insertions(+), 12 deletions(-)
 create mode 100644 INSTALL_OPENSUSE_11.txt
 create mode 100644 install/dist/conf/opensuse110.conf.php
 create mode 100644 install/dist/lib/opensuse110.lib.php
 create mode 100644 install/tpl/opensuse_amavisd_conf.master
 create mode 100644 install/tpl/opensuse_pureftpd_conf.master

diff --git a/INSTALL_OPENSUSE_11.txt b/INSTALL_OPENSUSE_11.txt
new file mode 100644
index 0000000000..0824057743
--- /dev/null
+++ b/INSTALL_OPENSUSE_11.txt
@@ -0,0 +1,212 @@
+Installation
+-----------
+
+It is recommended to use a clean (fresh) OpenSUSE installatiom where you selected to install just the minimal packages. A Gnome or KDE desktop is not needed and will just slow down the server. Then follow the steps below to setup your server with ISPConfig 3:
+
+Install some basic packes and the compilers that we need later
+
+yast2 -i findutils readline libgcc glibc-devel findutils-locate gcc flex lynx compat-readline4 db-devel wget gcc-c++ make vim telnet cron iptables iputils man man-pages
+
+1) Install Postfix, Courier, Saslauthd, MySQL, phpMyAdmin with the following command line (on one line!):
+
+yast2 -i postfix postfix-mysql mysql mysql-client phpMyAdmin courier-imap courier-authlib courier-authlib-mysql python cron cyrus-sasl cyrus-sasl-crammd5 cyrus-sasl-digestmd5 cyrus-sasl-gssapi cyrus-sasl-otp cyrus-sasl-plain cyrus-sasl-saslauthd libmysqlclient-devel
+
+chkconfig --add mysql
+/etc/init.d/mysql start
+
+chkconfig --add postfix
+/etc/init.d/postfix start
+
+chkconfig --add saslauthd
+/etc/init.d/saslauthd start
+
+chkconfig --add saslauthd
+/etc/init.d/saslauthd start
+
+chkconfig --add fam
+chkconfig --add courier-authdaemon
+chkconfig --add courier-pop
+chkconfig --add courier-imap
+/etc/init.d/courier-pop start
+/etc/init.d/courier-imap start
+chkconfig --add courier-pop-ssl
+chkconfig --add courier-imap-ssl
+/etc/init.d/courier-pop-ssl start
+/etc/init.d/courier-imap-ssl start
+
+cd /tmp
+wget http://download.opensuse.org/repositories/server:/mail/openSUSE_11.0/i586/getmail-4.7.6-1.4.i586.rpm
+rpm -i getmail-4.7.6-1.4.i586.rpm
+
+// Warnings like "warning: getmail-4.7.6-1.4.i586.rpm: Header V3 DSA signature: NOKEY, key ID 367fe7fc" can be ignored.
+
+// Install maildrop
+rpm --force -i http://download.opensuse.org/repositories/home%3A/cboltz/openSUSE_10.3/i586/maildrop-2.0.3-16.1.i586.rpm
+
+// Install pam_mysql
+
+yast2 -i pam-devel
+cd /tmp
+wget http://heanet.dl.sourceforge.net/sourceforge/pam-mysql/pam_mysql-0.7RC1.tar.gz
+tar xvfz pam_mysql-0.7RC1.tar.gz
+cd pam_mysql-0.7RC1
+./configure
+make
+make install
+rm -rf pam_mysql-0.7RC1
+rm pam_mysql-0.7RC1.tar.gz
+
+// Set the mysql database password:
+
+mysqladmin -u root password yourrootsqlpassword
+mysqladmin -h ispconfig.local -u root password yourrootsqlpassword
+
+
+2) Install Amavisd-new, Spamassassin and Clamav (1 line!):
+
+yast2 -i amavisd-new clamav clamav-db zoo unzip unrar bzip2 unarj perl-DBD-mysql
+
+chkconfig --add amavis
+chkconfig --add clamd
+/etc/init.d/amavis start
+/etc/init.d/clamd start
+
+3) Install PHP5 modules (1 line!):
+
+yast2 -i php5-bcmath php5-bz2 php5-calendar php5-ctype php5-curl php5-dbase php5-dom php5-ftp php5-gd php5-gettext php5-gmp php5-iconv php5-imap php5-ldap php5-mbstring php5-mcrypt php5-mysql php5-ncurses php5-odbc php5-openssl php5-pcntl php5-pgsql php5-posix php5-shmop php5-snmp php5-soap php5-sockets php5-sqlite php5-sysvsem php5-tokenizer php5-wddx php5-xmlrpc php5-xsl php5-zlib php5-exif php5-fastcgi php5-pear php5-sysvmsg php5-sysvshm ImageMagick curl
+
+Then run the following to enable the Apache modules:
+
+a2enmod suexec
+a2enmod rewrite
+a2enmod ssl
+
+chkconfig --add apache2
+/etc/init.d/apache2 start
+
+4) Install pure-ftpd and quota
+
+yast2 -i pure-ftpd quota
+
+// The current pure-ftpd package from SuSE is unstable and segfaults when a file is uploaded, 
+// we will replace it with a manually compiled package now:
+
+cd /tmp
+wget http://download.pureftpd.org/pub/pure-ftpd/releases/pure-ftpd-1.0.21.tar.gz
+tar xvfz pure-ftpd-1.0.21.tar.gz
+cd pure-ftpd-1.0.21/
+./configure --sysconfdir=/etc/pure-ftpd --with-everything --with-mysql
+make
+make install
+mv /usr/sbin/pure-ftpd /usr/sbin/pure-ftpd.suse
+ln -s /usr/local/sbin/pure-ftpd /usr/sbin/pure-ftpd
+rm -rf pure-ftpd-1.0.21
+rm -f pure-ftpd-1.0.21.tar.gz
+
+chkconfig --add pure-ftpd
+/etc/init.d/pure-ftpd start
+
+
+5) Install mydns
+
+cd /tmp
+wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/server:/dns/SUSE_Factory/i586/mydns-mysql-1.1.0-3.72.i586.rpm
+wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/server:/dns/SUSE_Factory/i586/mydns-1.1.0-3.72.i586.rpm
+rpm -i mydns*.rpm
+rm -rf /tmp/mydns*
+
+chkconfig --add mydns
+
+6) Install vlogger and webalizer
+
+cd /tmp
+wget http://n0rp.chemlab.org/vlogger/vlogger-1.3.tar.gz
+tar xvfz vlogger-1.3.tar.gz
+mv vlogger-1.3/vlogger /usr/sbin/
+rm -rf vlogger*
+
+
+yast2 -i webalizer perl-DateManip
+
+
+7) Install ISPConfig 3
+
+There are two possile scenarios, but not both:
+7.1) Install the latest released version 
+7.2) Install directly from SVN
+
+apt-get install php5-cli
+
+7.1) Installation of beta 3 from tar.gz
+
+  cd /tmp
+  wget http://www.ispconfig.org/downloads/ISPConfig-3.0.0.6-beta.tar.gz
+  tar xvfz ISPConfig-3.0.0.6-beta.tar.gz
+  cd ispconfig3_install/install/
+
+7.2) Installation from SVN
+
+  apt-get install subversion
+  cd /tmp
+  svn export svn://svn.ispconfig.org/ispconfig3/trunk/
+  cd trunk/install
+
+
+7.1+7.2) Now proceed with the ISPConfig installation.
+
+Now start the installation process by executing:
+
+php -q install.php
+
+The installer will configure all services like postfix, sasl, courier, etc. for you. A manual setup as required for ISPConfig 2 (perfect setup guides) is not nescessary. To login to the ISPConfig controlpanel, open the following URL in your browser (replace the IP to match your settings!):
+
+http://192.168.0.100:8080/
+
+the default login is:
+
+user: admin
+password: admin
+
+In case you get a permission denied error from apache, please restart the apache webserver process.
+
+Optional:
+
+Install a webbased FTP Client
+
+apt-get install squirrelmail
+ln -s /usr/share/squirrelmail/ /var/www/webmail
+
+Access squirrelmail:
+
+http://192.168.0.100/webmail
+
+
+To configure squirrelmail, run:
+
+/usr/sbin/squirrelmail-configure
+
+----------------------------------------------------------------------------------------------------------
+
+Hints:
+
+debian 4.0 under openvz:
+
+VPSID=101
+for CAP in CHOWN DAC_READ_SEARCH SETGID SETUID NET_BIND_SERVICE NET_ADMIN SYS_CHROOT SYS_NICE CHOWN DAC_READ_SEARCH SETGID SETUID NET_BIND_SERVICE NET_ADMIN SYS_CHROOT SYS_NICE
+do
+  vzctl set $VPSID --capability ${CAP}:on --save
+done
+
+----------------------------------------------------------------------------------------------------------
+
+Installing Jailkit:
+
+apt-get install build-essential autoconf automake1.9 libtool flex bison
+cd /tmp
+wget http://olivier.sessink.nl/jailkit/jailkit-2.5.tar.gz
+tar xvfz jailkit-2.5.tar.gz
+cd jailkit-2.5
+./configure
+make
+make install
+rm -rf jailkit-2.5*
diff --git a/install/dist/conf/opensuse110.conf.php b/install/dist/conf/opensuse110.conf.php
new file mode 100644
index 0000000000..6f6b100c07
--- /dev/null
+++ b/install/dist/conf/opensuse110.conf.php
@@ -0,0 +1,86 @@
+<?php
+
+//***  OpenSUSE 11.0 default settings
+
+//* Main
+$conf['language'] = 'en';
+$conf['distname'] = 'opensuse110';
+$conf['hostname'] = 'server1.example.com'; // Full hostname
+$conf['ispconfig_install_dir'] = '/usr/local/ispconfig';
+$conf['ispconfig_config_dir'] = '/usr/local/ispconfig';
+$conf['ispconfig_log_priority'] = 2;  // 0 = Debug, 1 = Warning, 2 = Error
+$conf['server_id'] = 1;
+$conf['init_scripts'] = '/etc/init.d';
+$conf['runlevel'] = '/etc';
+$conf['shells'] = '/etc/shells';
+$conf['cron_tab'] = '/var/spool/cron/tabs/root';
+$conf['pam'] = '/etc/pam.d';
+
+//* MySQL
+$conf['mysql']['init_script'] = 'mysql';
+$conf['mysql']['host'] = 'localhost';
+$conf['mysql']['ip'] = '127.0.0.1';
+$conf['mysql']['port'] = '3306';
+$conf['mysql']['database'] = 'dbispconfig';
+$conf['mysql']['admin_user'] = 'root';
+$conf['mysql']['admin_password'] = '';
+$conf['mysql']['ispconfig_user'] = 'ispconfig';
+$conf['mysql']['ispconfig_password'] = md5 (uniqid (rand()));
+
+//* Apache
+$conf['apache']['user'] = 'wwwrun';
+$conf['apache']['group'] = 'www';
+$conf['apache']['init_script'] = 'apache2';
+$conf['apache']['version'] = '2.2';
+$conf['apache']['vhost_conf_dir'] = '/etc/apache2/sites-available';
+$conf['apache']['vhost_conf_enabled_dir'] = '/etc/apache2/sites-enabled';
+$conf['apache']['vhost_port'] = '8080';
+
+//* Postfix
+$conf['postfix']['config_dir'] = '/etc/postfix';
+$conf['postfix']['init_script'] = 'postfix';
+$conf['postfix']['user'] = 'postfix';
+$conf['postfix']['group'] = 'postfix';
+$conf['postfix']['vmail_userid'] = '5000';
+$conf['postfix']['vmail_username'] = 'vmail';
+$conf['postfix']['vmail_groupid'] = '5000';
+$conf['postfix']['vmail_groupname'] = 'vmail';
+$conf['postfix']['vmail_mailbox_base'] = '/home/vmail';
+
+//* Getmail
+$conf['getmail']['config_dir'] = '/etc/getmail';
+$conf['getmail']['program'] = '/usr/bin/getmail';
+
+//* Courier
+$conf['courier']['config_dir'] = '/etc/authlib';
+$conf['courier']['courier-authdaemon'] = 'courier-authdaemon';
+$conf['courier']['courier-imap'] = 'courier-imap';
+$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl';
+$conf['courier']['courier-pop'] = 'courier-pop';
+$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl';
+
+//* SASL
+$conf['saslauthd']['config'] = '/etc/default/saslauthd';
+$conf['saslauthd']['init_script'] = 'saslauthd';
+
+//* Amavisd
+$conf['amavis']['config_dir'] = '/etc/amavis';
+$conf['amavis']['init_script'] = 'amavis';
+
+//* ClamAV
+$conf['clamav']['init_script'] = 'clamd';
+
+//* Pureftpd
+$conf['pureftpd']['config_dir'] = '/etc/pure-ftpd';
+$conf['pureftpd']['init_script'] = 'pure-ftpd';
+
+//* MyDNS
+$conf['mydns']['config_dir'] = '/etc';
+$conf['mydns']['init_script'] = 'mydns';
+
+//* Jailkit
+$conf['jailkit']['config_dir'] = '/etc/jailkit';
+$conf['jailkit']['jk_init'] = 'jk_init.ini';
+$conf['jailkit']['jk_chrootsh'] = 'jk_chrootsh.ini';
+
+?>
\ No newline at end of file
diff --git a/install/dist/lib/opensuse110.lib.php b/install/dist/lib/opensuse110.lib.php
new file mode 100644
index 0000000000..092a407669
--- /dev/null
+++ b/install/dist/lib/opensuse110.lib.php
@@ -0,0 +1,733 @@
+<?php
+
+/*
+Copyright (c) 2008, Till Brehm, projektfarm Gmbh
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class installer extends installer_base {
+	
+	function configure_postfix($options = '')
+    {
+        global $conf;
+		$cf = $conf['postfix'];
+		$config_dir = $cf['config_dir'];
+        
+		if(!is_dir($config_dir)){
+            $this->error("The postfix configuration directory '$config_dir' does not exist.");
+        }
+        
+		//* mysql-virtual_domains.cf
+        $this->process_postfix_config('mysql-virtual_domains.cf');
+
+		//* mysql-virtual_forwardings.cf
+        $this->process_postfix_config('mysql-virtual_forwardings.cf');
+
+		//* mysql-virtual_mailboxes.cf
+        $this->process_postfix_config('mysql-virtual_mailboxes.cf');
+
+		//* mysql-virtual_email2email.cf
+        $this->process_postfix_config('mysql-virtual_email2email.cf');
+
+		//* mysql-virtual_transports.cf
+        $this->process_postfix_config('mysql-virtual_transports.cf');
+
+		//* mysql-virtual_recipient.cf
+        $this->process_postfix_config('mysql-virtual_recipient.cf');
+
+		//* mysql-virtual_sender.cf
+        $this->process_postfix_config('mysql-virtual_sender.cf');
+
+		//* mysql-virtual_client.cf
+        $this->process_postfix_config('mysql-virtual_client.cf');
+		
+		//* mysql-virtual_relaydomains.cf
+        $this->process_postfix_config('mysql-virtual_relaydomains.cf');
+
+		//* Changing mode and group of the new created config files.
+		caselog('chmod o= '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null',
+                 __FILE__, __LINE__, 'chmod on mysql-virtual_*.cf*', 'chmod on mysql-virtual_*.cf* failed');
+		caselog('chgrp '.$cf['group'].' '.$config_dir.'/mysql-virtual_*.cf* &> /dev/null', 
+                __FILE__, __LINE__, 'chgrp on mysql-virtual_*.cf*', 'chgrp on mysql-virtual_*.cf* failed');
+		
+		//* Creating virtual mail user and group
+		$command = 'groupadd -g '.$cf['vmail_groupid'].' '.$cf['vmail_groupname'];
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+
+		$command = 'useradd -g '.$cf['vmail_groupname'].' -u '.$cf['vmail_userid'].' '.$cf['vmail_username'].' -d '.$cf['vmail_mailbox_base'].' -m';
+		caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");		
+
+		$postconf_commands = array (
+			'myhostname = '.$conf['hostname'],
+			'mydestination = '.$conf['hostname'].', localhost, localhost.localdomain',
+			'mynetworks = 127.0.0.0/8',
+			'virtual_alias_domains =',
+			'virtual_alias_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_forwardings.cf, mysql:'.$config_dir.'/mysql-virtual_email2email.cf',
+			'virtual_mailbox_domains = proxy:mysql:'.$config_dir.'/mysql-virtual_domains.cf',
+			'virtual_mailbox_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_mailboxes.cf',
+			'virtual_mailbox_base = '.$cf['vmail_mailbox_base'],
+			'virtual_uid_maps = static:'.$cf['vmail_userid'],
+			'virtual_gid_maps = static:'.$cf['vmail_groupid'],
+			'smtpd_sasl_auth_enable = yes',
+			'broken_sasl_auth_clients = yes',
+			'smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, check_recipient_access mysql:'.$config_dir.'/mysql-virtual_recipient.cf, reject_unauth_destination',
+			'smtpd_use_tls = yes',
+			'smtpd_tls_cert_file = '.$config_dir.'/smtpd.cert',
+			'smtpd_tls_key_file = '.$config_dir.'/smtpd.key',
+			'transport_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_transports.cf',
+			'relay_domains = mysql:'.$config_dir.'/mysql-virtual_relaydomains.cf',
+			'virtual_create_maildirsize = yes',
+			'virtual_mailbox_extended = yes',
+			'virtual_mailbox_limit_maps = proxy:mysql:'.$config_dir.'/mysql-virtual_mailbox_limit_maps.cf',
+			'virtual_mailbox_limit_override = yes',
+			'virtual_maildir_limit_message = "The user you are trying to reach is over quota."',
+			'virtual_overquota_bounce = yes',
+			'proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps',
+			'smtpd_sender_restrictions = check_sender_access mysql:'.$config_dir.'/mysql-virtual_sender.cf',
+			'smtpd_client_restrictions = check_client_access mysql:'.$config_dir.'/mysql-virtual_client.cf',
+			'maildrop_destination_concurrency_limit = 1',
+			'maildrop_destination_recipient_limit   = 1',
+			'virtual_transport = maildrop',
+			'header_checks = regexp:'.$config_dir.'/header_checks',
+			'mime_header_checks = regexp:'.$config_dir.'/mime_header_checks',
+			'nested_header_checks = regexp:'.$config_dir.'/nested_header_checks',
+			'body_checks = regexp:'.$config_dir.'/body_checks',
+			'inet_interfaces = all'
+		);
+		
+		//* Create the header and body check files
+		touch($config_dir.'/header_checks');
+		touch($config_dir.'/mime_header_checks');
+		touch($config_dir.'/nested_header_checks');
+		touch($config_dir.'/body_checks');
+		
+		
+		//* Make a backup copy of the main.cf file
+		copy($config_dir.'/main.cf', $config_dir.'/main.cf~');
+		
+		//* Executing the postconf commands
+		foreach($postconf_commands as $cmd) {
+			$command = "postconf -e '$cmd'";
+			caselog($command." &> /dev/null", __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
+		}
+		
+		if(!stristr($options,'dont-create-certs')) {
+			//* Create the SSL certificate
+			$command = 'cd '.$config_dir.'; '
+                      .'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout '
+                      .'smtpd.key -keyform PEM -days 365 -x509';
+			exec($command);
+		
+			$command = 'chmod o= '.$config_dir.'/smtpd.key';
+			caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
+		}
+		
+		//** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop.
+		$command = 'chmod 755  /var/run/authdaemon.courier-imap';
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
+		
+		//* Changing maildrop lines in posfix master.cf
+		if(is_file($config_dir.'/master.cf')){
+            copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
+        }
+		if(is_file($config_dir.'/master.cf~')){
+            exec('chmod 400 '.$config_dir.'/master.cf~');
+        }
+		$configfile = $config_dir.'/master.cf';
+		$content = rf($configfile);
+		$content = str_replace('  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}', 
+                   '  flags=R user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d ${recipient} ${extension} ${recipient} ${user} ${nexthop} ${sender}',
+                     $content);
+		wf($configfile, $content);
+		
+		//* Writing the Maildrop mailfilter file
+		$configfile = 'mailfilter';
+		if(is_file($cf['vmail_mailbox_base'].'/.'.$configfile)){
+            copy($cf['vmail_mailbox_base'].'/.'.$configfile, $cf['vmail_mailbox_base'].'/.'.$configfile.'~');
+        }
+		$content = rf("tpl/$configfile.master");
+		$content = str_replace('{dist_postfix_vmail_mailbox_base}', $cf['vmail_mailbox_base'], $content);
+		wf($cf['vmail_mailbox_base'].'/.'.$configfile, $content);
+		
+		//* Create the directory for the custom mailfilters
+		$command = 'mkdir '.$cf['vmail_mailbox_base'].'/mailfilters';
+		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Chmod and chown the .mailfilter file
+		$command = 'chown -R '.$cf['vmail_username'].':'.$cf['vmail_groupname'].' '.$cf['vmail_mailbox_base'].'/.mailfilter';
+		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		$command = 'chmod -R 600 '.$cf['vmail_mailbox_base'].'/.mailfilter';
+		caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+	}
+	
+	public function configure_saslauthd() {
+		global $conf;
+		
+		/*
+		$configfile = 'sasl_smtpd.conf';
+		if(is_file('/etc/sasl2/smtpd.conf')) copy('/etc/sasl2/smtpd.conf','/etc/sasl2/smtpd.conf~');
+		if(is_file('/etc/sasl2/smtpd.conf~')) exec('chmod 400 '.'/etc/sasl2/smtpd.conf~');
+		$content = rf("tpl/".$configfile.".master");
+		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
+		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
+		$content = str_replace('{mysql_server_ip}',$conf['mysql']['ip'],$content);
+		wf('/etc/sasl2/smtpd.conf',$content);
+		*/
+		
+		// TODO: Chmod and chown on the config file
+		
+		
+		/*
+		// Create the spool directory
+		exec('mkdir -p /var/spool/postfix/var/run/saslauthd');
+		
+		// Edit the file /etc/default/saslauthd
+		$configfile = $conf["saslauthd"]["config"];
+		if(is_file($configfile)) copy($configfile,$configfile.'~');
+		if(is_file($configfile.'~')) exec('chmod 400 '.$configfile.'~');
+		$content = rf($configfile);
+		$content = str_replace('START=no','START=yes',$content);
+		$content = str_replace('OPTIONS="-c"','OPTIONS="-m /var/spool/postfix/var/run/saslauthd -r"',$content);
+		wf($configfile,$content);
+		*/
+		
+		// Edit the file /etc/init.d/saslauthd
+		$configfile = $conf["init_scripts"].'/'.$conf["saslauthd"]["init_script"];
+		$content = rf($configfile);
+		$content = str_replace('/sbin/startproc $AUTHD_BIN -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1','/sbin/startproc $AUTHD_BIN -r -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1',$content);
+		wf($configfile,$content);
+		
+		
+		
+	}
+	
+	public function configure_pam()
+    {
+		global $conf;
+		$pam = $conf['pam'];
+		//* configure pam for SMTP authentication agains the ispconfig database
+		$configfile = 'pamd_smtp';
+		if(is_file("$pam/smtp"))    copy("$pam/smtp", "$pam/smtp~");
+		if(is_file("$pam/smtp~"))   exec("chmod 400 $pam/smtp~");
+
+		$content = rf("tpl/$configfile.master");
+		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
+		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
+		$content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content);
+		wf("$pam/smtp", $content);
+		//exec("chmod 660 $pam/smtp");
+		//exec("chown root:root $pam/smtp");
+	
+	}
+	
+	public function configure_courier()
+    {
+		global $conf;
+		$config_dir = $conf['courier']['config_dir'];
+		//* authmysqlrc
+		$configfile = 'authmysqlrc';
+		if(is_file("$config_dir/$configfile")){
+            copy("$config_dir/$configfile", "$config_dir/$configfile~");
+        }
+		exec("chmod 400 $config_dir/$configfile~");
+		$content = rf("tpl/$configfile.master");
+		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
+		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
+		$content = str_replace('{mysql_server_host}',$conf['mysql']['host'],$content);
+		wf("$config_dir/$configfile", $content);
+		
+		exec("chmod 660 $config_dir/$configfile");
+		exec("chown root:root $config_dir/$configfile");
+		
+		//* authdaemonrc
+		$configfile = $conf['courier']['config_dir'].'/authdaemonrc';
+		if(is_file($configfile)){
+            copy($configfile, $configfile.'~');
+        }
+		if(is_file($configfile.'~')){
+            exec('chmod 400 '.$configfile.'~');
+        }
+		$content = rf($configfile);
+		$content = str_replace('authmodulelist=', 'authmodulelist="authmysql"', $content);
+		wf($configfile, $content);
+	}
+	
+	public function configure_amavis() {
+		global $conf;
+		
+		// amavisd user config file
+		$configfile = 'opensuse_amavisd_conf';
+		if(is_file($conf["amavis"]["config_dir"].'/amavisd.conf')) copy($conf["amavis"]["config_dir"].'/amavisd.conf',$conf["courier"]["config_dir"].'/amavisd.conf~');
+		if(is_file($conf["amavis"]["config_dir"].'/amavisd.conf~')) exec('chmod 400 '.$conf["amavis"]["config_dir"].'/amavisd.conf~');
+		$content = rf("tpl/".$configfile.".master");
+		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
+		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
+		$content = str_replace('{mysql_server_port}',$conf["mysql"]["port"],$content);
+		$content = str_replace('{mysql_server_ip}',$conf['mysql']['ip'],$content);
+		wf($conf["amavis"]["config_dir"].'/amavisd.conf',$content);
+		
+		
+		// Adding the amavisd commands to the postfix configuration
+		$postconf_commands = array (
+			'content_filter = amavis:[127.0.0.1]:10024',
+			'receive_override_options = no_address_mappings'
+		);
+		
+		// Make a backup copy of the main.cf file
+		copy($conf["postfix"]["config_dir"].'/main.cf',$conf["postfix"]["config_dir"].'/main.cf~2');
+		
+		// Executing the postconf commands
+		foreach($postconf_commands as $cmd) {
+			$command = "postconf -e '$cmd'";
+			caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		}
+		
+		// Append the configuration for amavisd to the master.cf file
+		if(is_file($conf["postfix"]["config_dir"].'/master.cf')) copy($conf["postfix"]["config_dir"].'/master.cf',$conf["postfix"]["config_dir"].'/master.cf~');
+		$content = rf($conf["postfix"]["config_dir"].'/master.cf');
+		// Only add the content if we had not addded it before
+		if(!stristr($content,"127.0.0.1:10025")) {
+			unset($content);
+			$content = rf("tpl/master_cf_amavis.master");
+			af($conf["postfix"]["config_dir"].'/master.cf',$content);
+		}
+		unset($content);
+		
+		// Add the clamav user to the vscan group
+		exec('groupmod --add-user clamav vscan');
+		
+		
+	}
+	
+	public function configure_spamassassin()
+    {
+		global $conf;
+		
+		//* Enable spamasasssin on debian and ubuntu
+		/*
+		$configfile = '/etc/default/spamassassin';
+		if(is_file($configfile)){
+            copy($configfile, $configfile.'~');
+        }
+		$content = rf($configfile);
+		$content = str_replace('ENABLED=0', 'ENABLED=1', $content);
+		wf($configfile, $content);
+		*/
+	}
+	
+	public function configure_getmail()
+    {
+		global $conf;
+		
+		$config_dir = $conf['getmail']['config_dir'];
+		
+		if(!is_dir($config_dir)) exec("mkdir -p ".escapeshellcmd($config_dir));
+
+		$command = "useradd -d $config_dir getmail";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		$command = "chown -R getmail $config_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		$command = "chmod -R 700 $config_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+	}
+	
+	
+	public function configure_pureftpd()
+    {
+		global $conf;
+		
+		$config_dir = $conf['pureftpd']['config_dir'];
+
+		//* configure pam for SMTP authentication agains the ispconfig database
+		$configfile = 'db/mysql.conf';
+		if(is_file("$config_dir/$configfile")){
+            copy("$config_dir/$configfile", "$config_dir/$configfile~");
+        }
+		if(is_file("$config_dir/$configfile~")){
+            exec("chmod 400 $config_dir/$configfile~");
+        }
+		$content = rf('tpl/pureftpd_mysql.conf.master');
+		$content = str_replace('{mysql_server_ispconfig_user}', $conf["mysql"]["ispconfig_user"], $content);
+		$content = str_replace('{mysql_server_ispconfig_password}', $conf["mysql"]["ispconfig_password"], $content);
+		$content = str_replace('{mysql_server_database}', $conf["mysql"]["database"], $content);
+		$content = str_replace('{mysql_server_ip}', $conf["mysql"]["ip"], $content);
+		$content = str_replace('{server_id}', $conf["server_id"], $content);
+		wf("$config_dir/$configfile", $content);
+		exec("chmod 600 $config_dir/$configfile");
+		exec("chown root:root $config_dir/$configfile");
+		
+		// copy our customized copy of pureftpd.conf to the pure-ftpd config directory
+		exec("cp tpl/opensuse_pureftpd_conf.master $config_dir/pure-ftpd.conf");
+		
+	}
+	
+	public function configure_mydns()
+    {
+		global $conf;
+		
+		// configure pam for SMTP authentication agains the ispconfig database
+		$configfile = 'mydns.conf';
+		if(is_file($conf["mydns"]["config_dir"].'/'.$configfile)) copy($conf["mydns"]["config_dir"].'/'.$configfile,$conf["mydns"]["config_dir"].'/'.$configfile.'~');
+		if(is_file($conf["mydns"]["config_dir"].'/'.$configfile.'~')) exec('chmod 400 '.$conf["mydns"]["config_dir"].'/'.$configfile.'~');
+		$content = rf("tpl/".$configfile.".master");
+		$content = str_replace('{mysql_server_ispconfig_user}',$conf['mysql']['ispconfig_user'],$content);
+		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}',$conf['mysql']['database'],$content);
+		$content = str_replace('{mysql_server_host}',$conf["mysql"]["host"],$content);
+		$content = str_replace('{server_id}',$conf["server_id"],$content);
+		wf($conf["mydns"]["config_dir"].'/'.$configfile,$content);
+		exec('chmod 600 '.$conf["mydns"]["config_dir"].'/'.$configfile);
+		exec('chown root:root '.$conf["mydns"]["config_dir"].'/'.$configfile);
+	
+	}
+	
+	public function configure_apache()
+    {	
+		global $conf;
+		
+		//* Create the logging directory for the vhost logfiles
+		exec('mkdir -p /var/log/ispconfig/httpd');
+		
+		// Sites enabled and avaulable dirs
+		exec('mkdir -p '.$conf['apache']['vhost_conf_enabled_dir']);
+		exec('mkdir -p '.$conf['apache']['vhost_conf_dir']);
+		
+		$content = rf('/etc/apache2/httpd.conf');
+		if(!stristr($content,'Include /etc/apache2/sites-enabled/')) {
+			af('/etc/apache2/httpd.conf',"\nInclude /etc/apache2/sites-enabled/\n\n");
+		}
+		unset($content);
+		
+	}
+	
+	public function configure_firewall()
+	{
+		global $conf;
+		
+		$dist_init_scripts = $conf['init_scripts'];
+  		
+		if(is_dir("/etc/Bastille.backup")) caselog("rm -rf /etc/Bastille.backup", __FILE__, __LINE__);
+		if(is_dir("/etc/Bastille")) caselog("mv -f /etc/Bastille /etc/Bastille.backup", __FILE__, __LINE__);
+  		@mkdir("/etc/Bastille", octdec($directory_mode));
+  		if(is_dir("/etc/Bastille.backup/firewall.d")) caselog("cp -pfr /etc/Bastille.backup/firewall.d /etc/Bastille/", __FILE__, __LINE__);
+  		caselog("cp -f tpl/bastille-firewall.cfg.master /etc/Bastille/bastille-firewall.cfg", __FILE__, __LINE__);
+  		caselog("chmod 644 /etc/Bastille/bastille-firewall.cfg", __FILE__, __LINE__);
+  		$content = rf("/etc/Bastille/bastille-firewall.cfg");
+  		$content = str_replace("{DNS_SERVERS}", "", $content);
+
+  		$tcp_public_services = '';
+  		$udp_public_services = '';
+		
+		$row = $this->db->queryOneRecord("SELECT * FROM firewall WHERE server_id = ".intval($conf['server_id']));
+		
+  		if(trim($row["tcp_port"]) != '' || trim($row["udp_port"]) != ''){
+    		$tcp_public_services = trim(str_replace(',',' ',$row["tcp_port"]));
+    		$udp_public_services = trim(str_replace(',',' ',$row["udp_port"]));
+  		} else {
+    		$tcp_public_services = '21 22 25 53 80 110 443 8080 10000';
+    		$udp_public_services = '53';
+  		}
+  		$content = str_replace("{TCP_PUBLIC_SERVICES}", $tcp_public_services, $content);
+  		$content = str_replace("{UDP_PUBLIC_SERVICES}", $udp_public_services, $content);
+
+  		wf("/etc/Bastille/bastille-firewall.cfg", $content);
+
+  		if(is_file($dist_init_scripts."/bastille-firewall")) caselog("mv -f $dist_init_scripts/bastille-firewall $dist_init_scripts/bastille-firewall.backup", __FILE__, __LINE__);
+  		caselog("cp -f apps/bastille-firewall $dist_init_scripts", __FILE__, __LINE__);
+  		caselog("chmod 700 $dist_init_scripts/bastille-firewall", __FILE__, __LINE__);
+
+  		if(is_file("/sbin/bastille-ipchains")) caselog("mv -f /sbin/bastille-ipchains /sbin/bastille-ipchains.backup", __FILE__, __LINE__);
+  		caselog("cp -f apps/bastille-ipchains /sbin", __FILE__, __LINE__);
+  		caselog("chmod 700 /sbin/bastille-ipchains", __FILE__, __LINE__);
+
+  		if(is_file("/sbin/bastille-netfilter")) caselog("mv -f /sbin/bastille-netfilter /sbin/bastille-netfilter.backup", __FILE__, __LINE__);
+  		caselog("cp -f apps/bastille-netfilter /sbin", __FILE__, __LINE__);
+  		caselog("chmod 700 /sbin/bastille-netfilter", __FILE__, __LINE__);
+		
+		if(!@is_dir('/var/lock/subsys')) caselog("mkdir /var/lock/subsys", __FILE__, __LINE__);
+
+  		exec("which ipchains &> /dev/null", $ipchains_location, $ret_val);
+  		if(!is_file("/sbin/ipchains") && !is_link("/sbin/ipchains") && $ret_val == 0) phpcaselog(@symlink(shell_exec("which ipchains"), "/sbin/ipchains"), 'create symlink', __FILE__, __LINE__);
+  		unset($ipchains_location);
+  		exec("which iptables &> /dev/null", $iptables_location, $ret_val);
+  		if(!is_file("/sbin/iptables") && !is_link("/sbin/iptables") && $ret_val == 0) phpcaselog(@symlink(trim(shell_exec("which iptables")), "/sbin/iptables"), 'create symlink', __FILE__, __LINE__);
+  		unset($iptables_location);
+
+	}
+	
+	
+	public function install_ispconfig()
+    {
+		global $conf;
+		
+		$install_dir = $conf['ispconfig_install_dir'];
+
+		//* Create the ISPConfig installation directory
+		if(!@is_dir("$install_dir")) {
+			$command = "mkdir $install_dir";
+			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		}
+		
+		//* Create a ISPConfig user and group
+		$command = 'groupadd ispconfig';
+		if(!is_group('vacp')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		$command = "useradd -g ispconfig -d $install_dir ispconfig";
+		if(!is_user('vacp')) caselog($command.' &> /dev/null 2> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* copy the ISPConfig interface part
+		$command = "cp -rf ../interface $install_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* copy the ISPConfig server part
+		$command = "cp -rf ../server $install_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Create a symlink, so ISPConfig is accessible via web
+		// Replaced by a separate vhost definition for port 8080
+		// $command = "ln -s $install_dir/interface/web/ /var/www/ispconfig";
+		// caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Create the config file for ISPConfig interface
+		$configfile = 'config.inc.php';
+		if(is_file($install_dir.'/interface/lib/'.$configfile)){
+            copy("$install_dir/interface/lib/$configfile", "$install_dir/interface/lib/$configfile~");
+        }
+		$content = rf("tpl/$configfile.master");
+		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
+		$content = str_replace('{mysql_server_ispconfig_password}',$conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
+		$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
+		$content = str_replace('{ispconfig_log_priority}', $conf['ispconfig_log_priority'], $content);
+		wf("$install_dir/interface/lib/$configfile", $content);
+		
+		//* Create the config file for ISPConfig server
+		$configfile = 'config.inc.php';
+		if(is_file($install_dir.'/server/lib/'.$configfile)){
+            copy("$install_dir/server/lib/$configfile", "$install_dir/interface/lib/$configfile~");
+        }
+		$content = rf("tpl/$configfile.master");
+		$content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content);
+		$content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content);
+		$content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content);
+		$content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content);
+		$content = str_replace('{server_id}', $conf['server_id'], $content);
+		$content = str_replace('{ispconfig_log_priority}', $conf['ispconfig_log_priority'], $content);
+		wf("$install_dir/server/lib/$configfile", $content);
+		
+		
+		//* Enable the server modules and plugins.
+		// TODO: Implement a selector which modules and plugins shall be enabled.
+		$dir = $install_dir.'/server/mods-available/';
+		if (is_dir($dir)) {
+			if ($dh = opendir($dir)) {
+				while (($file = readdir($dh)) !== false) {
+					if($file != '.' && $file != '..') {
+						if(!@is_link($install_dir.'/server/mods-enabled/'.$file)) @symlink($install_dir.'/server/mods-available/'.$file, $install_dir.'/server/mods-enabled/'.$file);
+					}
+				}
+				closedir($dh);
+			}
+		}
+		
+		$dir = $install_dir.'/server/plugins-available/';
+		if (is_dir($dir)) {
+			if ($dh = opendir($dir)) {
+				while (($file = readdir($dh)) !== false) {
+					if($file != '.' && $file != '..') {
+						if(!@is_link($install_dir.'/server/plugins-enabled/'.$file)) @symlink($install_dir.'/server/plugins-available/'.$file, $install_dir.'/server/plugins-enabled/'.$file);
+					}
+				}
+				closedir($dh);
+			}
+		}
+		
+		//* Chmod the files
+		$command = "chmod -R 750 $install_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+
+		//* chown the files to the ispconfig user and group
+		$command = "chown -R ispconfig:ispconfig $install_dir";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Make the global language file directory group writable
+		exec("chmod -R 770 $install_dir/interface/lib/lang");
+		
+		//* Make the temp directory for language file exports writable
+		exec("chmod -R 770 $install_dir/interface/web/temp");
+		
+		//* Make all interface language file directories group writable
+		$handle = @opendir($install_dir.'/interface/web');
+		while ($file = @readdir ($handle)) { 
+	   		if ($file != '.' && $file != '..') {
+	        	if(@is_dir($install_dir.'/interface/web'.'/'.$file.'/lib/lang')) {
+					$handle2 = opendir($install_dir.'/interface/web'.'/'.$file.'/lib/lang');
+					chmod($install_dir.'/interface/web'.'/'.$file.'/lib/lang',0770);
+					while ($lang_file = @readdir ($handle2)) {
+						if ($lang_file != '.' && $lang_file != '..') {
+							chmod($install_dir.'/interface/web'.'/'.$file.'/lib/lang/'.$lang_file,0770);
+						}
+					}
+				}
+			}
+		}
+		
+		//* make sure that the server config file (not the interface one) is only readable by the root user
+		exec("chmod 600 $install_dir/server/lib/$configfile");
+		exec("chown root:root $install_dir/server/lib/$configfile");
+		if(@is_file("$install_dir/server/lib/mysql_clientdb.conf")) {
+			exec("chmod 600 $install_dir/server/lib/mysql_clientdb.conf");
+			exec("chown root:root $install_dir/server/lib/mysql_clientdb.conf");
+		}
+		
+		// TODO: FIXME: add the www-data user to the ispconfig group. This is just for testing
+		// and must be fixed as this will allow the apache user to read the ispconfig files.
+		// Later this must run as own apache server or via suexec!
+		$command = 'groupmod --add-user wwwrun ispconfig';
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Make the shell scripts executable
+		$command = "chmod +x $install_dir/server/scripts/*.sh";
+		caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		
+		//* Copy the ISPConfig vhost for the controlpanel
+        // TODO: These are missing! should they be "vhost_dist_*_dir" ?
+        $vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
+        $vhost_conf_enabled_dir = $conf['apache']['vhost_conf_enabled_dir'];
+        
+        
+        // Dont just copy over the virtualhost template but add some custom settings
+         
+        $content = rf("tpl/apache_ispconfig.vhost.master");
+		$content = str_replace('{vhost_port}', $conf['apache']['vhost_port'], $content);
+		wf("$vhost_conf_dir/ispconfig.vhost", $content);
+		
+		//copy('tpl/apache_ispconfig.vhost.master', "$vhost_conf_dir/ispconfig.vhost");
+		//* and create the symlink
+		if($this->install_ispconfig_interface == true) {
+			if(!@is_link("$vhost_conf_enabled_dir/ispconfig.vhost")) {
+				exec("ln -s $vhost_conf_dir/ispconfig.vhost $vhost_conf_enabled_dir/ispconfig.vhost");
+			}
+		}
+		
+		// Make the Clamav log files readable by ISPConfig
+		//exec('chmod +r /var/log/clamav/clamav.log');
+		//exec('chmod +r /var/log/clamav/freshclam.log');
+		
+		//* Install the SVN update script
+		exec('cp ../helper_scripts/update_from_svn.sh /usr/local/bin/ispconfig_update_from_svn.sh');
+		exec('chown root /usr/local/bin/ispconfig_update_from_svn.sh');
+		exec('chmod 700 /usr/local/bin/ispconfig_update_from_svn.sh');
+		
+		//set the fast cgi starter script to executable
+		exec('chmod 755 '.$install_dir.'/interface/bin/php-fcgi');
+		
+		//* Make the logs readable for the ispconfig user
+		if(@is_file('/var/log/mail.log')) exec('chmod +r /var/log/mail.log');
+		if(@is_file('/var/log/mail.warn')) exec('chmod +r /var/log/mail.warn');
+		if(@is_file('/var/log/mail.err')) exec('chmod +r /var/log/mail.err');
+		if(@is_file('/var/log/messages')) exec('chmod +r /var/log/messages');
+		
+		//To enable apache to read the directories
+		exec('chmod a+rx /usr/local/ispconfig');
+		exec('chmod -R 751 /usr/local/ispconfig/interface');
+		exec('chmod a+rx /usr/local/ispconfig/interface/web');
+		
+		
+	}
+	
+	public function configure_dbserver()
+	{
+		global $conf;
+		
+		//* If this server shall act as database server for client DB's, we configure this here
+		$install_dir = $conf['ispconfig_install_dir'];
+		
+		// Create a file with the database login details which 
+		// are used to create the client databases.
+		
+		if(!is_dir("$install_dir/server/lib")) {
+			$command = "mkdir $install_dir/server/lib";
+			caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
+		}
+		
+		$content = rf("tpl/mysql_clientdb.conf.master");
+		$content = str_replace('{username}',$conf['mysql']['admin_user'],$content);
+		$content = str_replace('{password}',$conf['mysql']['admin_password'], $content);
+		wf("$install_dir/server/lib/mysql_clientdb.conf",$content);
+		exec('chmod 600 '."$install_dir/server/lib/mysql_clientdb.conf");
+		exec('chown root:root '."$install_dir/server/lib/mysql_clientdb.conf");
+		
+	}
+	
+	public function install_crontab()
+    {		
+		global $conf;
+		
+		//* Root Crontab
+		exec('crontab -u root -l > crontab.txt');
+		$existing_root_cron_jobs = file('crontab.txt');
+		
+		$root_cron_jobs = array(
+			'* * * * * /usr/local/ispconfig/server/server.sh &> /dev/null',
+			'30 00 * * * /usr/local/ispconfig/server/cron_daily.sh &> /dev/null'
+		);
+		foreach($root_cron_jobs as $cron_job) {
+			if(!in_array($cron_job."\n", $existing_root_cron_jobs)) {
+				$existing_root_cron_jobs[] = $cron_job."\n";
+			}
+		}
+		file_put_contents('crontab.txt', $existing_root_cron_jobs);
+		exec('crontab -u root crontab.txt &> /dev/null');
+		unlink('crontab.txt');
+		
+		//* Getmail crontab
+        $cf = $conf['getmail'];
+		exec('crontab -u getmail -l > crontab.txt');
+		$existing_cron_jobs = file('crontab.txt');
+		
+		$cron_jobs = array('*/5 * * * * '.$cf['program'].' -g '.$cf['config_dir'].' -r '.$cf['config_dir'].'/*.conf &> /dev/null');
+		foreach($cron_jobs as $cron_job) {
+			if(!in_array($cron_job."\n", $existing_cron_jobs)) {
+				$existing_cron_jobs[] = $cron_job."\n";
+			}
+		}
+		file_put_contents('crontab.txt', $existing_cron_jobs);
+		exec('crontab -u getmail crontab.txt &> /dev/null');
+		unlink('crontab.txt');
+	}
+
+}
+
+?>
\ No newline at end of file
diff --git a/install/install.php b/install/install.php
index 2958a038ed..07e6886baf 100644
--- a/install/install.php
+++ b/install/install.php
@@ -213,7 +213,7 @@ if($install_mode == 'Standard') {
 	system($conf['init_scripts'].'/'.$conf['courier']['courier-pop-ssl'].' restart');
 	system($conf['init_scripts'].'/'.$conf['apache']['init_script'].' restart');
 	system($conf['init_scripts'].'/'.$conf['pureftpd']['init_script'].' restart');
-	system($conf['init_scripts'].'/'.$conf['mydns']['init_script'].' restart');
+	system($conf['init_scripts'].'/'.$conf['mydns']['init_script'].' restart &> /dev/null');
 	
 }else{
 
diff --git a/install/lib/install.lib.php b/install/lib/install.lib.php
index d8eb0d67c3..78ef578f54 100644
--- a/install/lib/install.lib.php
+++ b/install/lib/install.lib.php
@@ -74,9 +74,20 @@ function get_distname() {
 		}
 	}
 	
+	//** OpenSuSE
+	elseif(file_exists("/etc/SuSE-release")) {
+		if(stristr(file_get_contents('/etc/SuSE-release'),'11.0')) {
+			$distname = 'opensuse110';
+			swriteln("Operating System: openSUSE 11.0 or compatible\n");
+		}
+	}
+	
+	
 	//** Redhat
 	elseif(file_exists("/etc/redhat_release")) {
 	
+	} else {
+		die('unrecognized linux distribution');
 	}
 	
 	return $distname;
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index 7b38923be4..3ca35b4508 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -187,7 +187,7 @@ class installer_base {
 	
 
     //** writes postfix configuration files
-    private function process_postfix_config($configfile)
+    public function process_postfix_config($configfile)
     {	
 		global $conf;
 		
@@ -329,12 +329,6 @@ class installer_base {
 			caselog($command." &> /dev/null", __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command);
 		}
 		
-		// TODO: Change the master.cf file
-		/*
-		Add:
-        maildrop  unix  -       n       n       -       -       pipe
-        flags=R user=vmail argv=/usr/bin/maildrop -d ${recipient} ${extension} ${recipient} ${user} ${nexthop} ${sender}
-		*/
 		if(!stristr($options,'dont-create-certs')) {
 			//* Create the SSL certificate
 			$command = 'cd '.$config_dir.'; '
@@ -386,7 +380,7 @@ class installer_base {
 		
 	}
 	
-	function configure_saslauthd() {
+	public function configure_saslauthd() {
 		global $conf;
 		
 	
@@ -478,7 +472,7 @@ class installer_base {
 		wf($configfile, $content);
 	}
 	
-	function configure_amavis() {
+	public function configure_amavis() {
 		global $conf;
 		
 		// amavisd user config file
@@ -513,11 +507,14 @@ class installer_base {
 		
 		// Append the configuration for amavisd to the master.cf file
 		if(is_file($conf["postfix"]["config_dir"].'/master.cf')) copy($conf["postfix"]["config_dir"].'/master.cf',$conf["postfix"]["config_dir"].'/master.cf~');
-		$content = rf("tpl/master_cf_amavis.master");
+		$content = rf($conf["postfix"]["config_dir"].'/master.cf');
 		// Only add the content if we had not addded it before
 		if(!stristr($content,"127.0.0.1:10025")) {
+			unset($content);
+			$content = rf("tpl/master_cf_amavis.master");
 			af($conf["postfix"]["config_dir"].'/master.cf',$content);
 		}
+		unset($content);
 		
 		// Add the clamav user to the amavis group
 		exec('adduser clamav amavis');
diff --git a/install/tpl/opensuse_amavisd_conf.master b/install/tpl/opensuse_amavisd_conf.master
new file mode 100644
index 0000000000..f6721b7307
--- /dev/null
+++ b/install/tpl/opensuse_amavisd_conf.master
@@ -0,0 +1,784 @@
+use strict;
+
+# a minimalistic configuration file for amavisd-new with all necessary settings
+#
+#   see amavisd.conf-default for a list of all variables with their defaults;
+#   see amavisd.conf-sample for a traditional-style commented file;
+#   for more details see documentation in INSTALL, README_FILES/*
+#   and at http://www.ijs.si/software/amavisd/amavisd-new-docs.html
+
+
+# COMMONLY ADJUSTED SETTINGS:
+
+# @bypass_virus_checks_maps = (1);  # controls running of anti-virus code
+# @bypass_spam_checks_maps  = (1);  # controls running of anti-spam code
+# $bypass_decode_parts = 1;         # controls running of decoders&dearchivers
+
+$max_servers = 2;            # num of pre-forked children (2..15 is common), -m
+$daemon_user  = 'vscan';     # (no default;  customary: vscan or amavis), -u
+$daemon_group = 'vscan';     # (no default;  customary: vscan or amavis), -g
+
+$mydomain = 'site';   # a convenient default for other settings
+
+$MYHOME = '/var/spool/amavis';   # a convenient default for other settings, -H
+$TEMPBASE = "$MYHOME/tmp";   # working directory, needs to exist, -T
+$ENV{TMPDIR} = $TEMPBASE;    # environment variable TMPDIR, used by SA, etc.
+$QUARANTINEDIR = '/var/spool/amavis/virusmails';  # -Q
+# $quarantine_subdir_levels = 1;  # add level of subdirs to disperse quarantine
+
+# $daemon_chroot_dir = $MYHOME;   # chroot directory or undef, -R
+
+# $db_home   = "$MYHOME/db";      # dir for bdb nanny/cache/snmp databases, -D
+# $helpers_home = "$MYHOME/var";  # working directory for SpamAssassin, -S
+# $lock_file = "$MYHOME/var/amavisd.lock";  # -L
+# $pid_file  = "$MYHOME/var/amavisd.pid";   # -P
+#NOTE: create directories $MYHOME/tmp, $MYHOME/var, $MYHOME/db manually
+
+$log_level = 0;              # verbosity 0..5, -d
+$log_recip_templ = undef;    # disable by-recipient level-0 log entries
+$DO_SYSLOG = 1;              # log via syslogd (preferred)
+$syslog_facility = 'mail';   # Syslog facility as a string
+           # e.g.: mail, daemon, user, local0, ... local7
+$syslog_priority = 'debug';  # Syslog base (minimal) priority as a string,
+           # choose from: emerg, alert, crit, err, warning, notice, info, debug
+
+$enable_db = 1;              # enable use of BerkeleyDB/libdb (SNMP and nanny)
+$enable_global_cache = 1;    # enable use of libdb-based cache if $enable_db=1
+$nanny_details_level = 2;    # nanny verbosity: 1: traditional, 2: detailed
+
+@local_domains_maps = ( [".$mydomain"] );  # list of all local domains
+
+@mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10
+                  10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );
+
+$unix_socketname = "$MYHOME/amavisd.sock";  # amavisd-release or amavis-milter
+               # option(s) -p overrides $inet_socket_port and $unix_socketname
+
+$inet_socket_port = 10024;   # listen on this local TCP port(s)
+# $inet_socket_port = [10024,10026];  # listen on multiple TCP ports
+
+$policy_bank{'MYNETS'} = {   # mail originating from @mynetworks
+  originating => 1,  # is true in MYNETS by default, but let's make it explicit
+  os_fingerprint_method => undef,  # don't query p0f for internal clients
+};
+
+# it is up to MTA to re-route mail from authenticated roaming users or
+# from internal hosts to a dedicated TCP port (such as 10026) for filtering
+$interface_policy{'10026'} = 'ORIGINATING';
+
+$policy_bank{'ORIGINATING'} = {  # mail supposedly originating from our users
+  originating => 1,  # declare that mail was submitted by our smtp client
+  allow_disclaimers => 1,  # enables disclaimer insertion if available
+  # notify administrator of locally originating malware
+  virus_admin_maps => ["virusalert\@$mydomain"],
+  spam_admin_maps  => ["virusalert\@$mydomain"],
+  warnbadhsender   => 1,
+  # forward to a smtpd service providing DKIM signing service
+  forward_method => 'smtp:[127.0.0.1]:10027',
+  # force MTA conversion to 7-bit (e.g. before DKIM signing)
+  smtpd_discard_ehlo_keywords => ['8BITMIME'],
+  bypass_banned_checks_maps => [1],  # allow sending any file names and types
+  terminate_dsn_on_notify_success => 0,  # don't remove NOTIFY=SUCCESS option 
+};
+
+$interface_policy{'SOCK'} = 'AM.PDP-SOCK'; # only applies with $unix_socketname
+
+# Use with amavis-release over a socket or with Petr Rehor's amavis-milter.c
+# (with amavis-milter.c from this package or old amavis.c client use 'AM.CL'):
+$policy_bank{'AM.PDP-SOCK'} = {
+  protocol => 'AM.PDP',
+  auth_required_release => 0,  # do not require secret_id for amavisd-release
+};
+
+$sa_tag_level_deflt  = 2.0;  # add spam info headers if at, or above that level
+$sa_tag2_level_deflt = 6.31; # add 'spam detected' headers at that level
+$sa_kill_level_deflt = 6.31; # triggers spam evasive actions
+$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent
+# $sa_quarantine_cutoff_level = 20; # spam level beyond which quarantine is off
+# $penpals_bonus_score = 5;  # (no effect without a @storage_sql_dsn database)
+# $penpals_threshold_high = $sa_kill_level_deflt; # don't waste time on hi spam
+
+$sa_mail_body_size_limit = 400*1024; # don't waste time on SA if mail is larger
+$sa_local_tests_only = 0;    # only tests which do not require internet access?
+
+# @lookup_sql_dsn =
+#   ( ['DBI:mysql:database=mail;host=127.0.0.1;port=3306', 'user1', 'passwd1'],
+#     ['DBI:mysql:database=mail;host=host2', 'username2', 'password2'],
+#     ["DBI:SQLite:dbname=$MYHOME/sql/mail_prefs.sqlite", '', ''] );
+# @storage_sql_dsn = @lookup_sql_dsn;  # none, same, or separate database
+
+# $timestamp_fmt_mysql = 1; # if using MySQL *and* msgs.time_iso is TIMESTAMP;
+#   defaults to 0, which is good for non-MySQL or if msgs.time_iso is CHAR(16)
+
+$virus_admin               = "virusalert\@$mydomain";  # notifications recip.
+
+$mailfrom_notify_admin     = "virusalert\@$mydomain";  # notifications sender
+$mailfrom_notify_recip     = "virusalert\@$mydomain";  # notifications sender
+$mailfrom_notify_spamadmin = "spam.police\@$mydomain"; # notifications sender
+$mailfrom_to_quarantine = ''; # null return path; uses original sender if undef
+
+@addr_extension_virus_maps      = ('virus');
+@addr_extension_banned_maps     = ('banned');
+@addr_extension_spam_maps       = ('spam');
+@addr_extension_bad_header_maps = ('badh');
+# $recipient_delimiter = '+';  # undef disables address extensions altogether
+# when enabling addr extensions do also Postfix/main.cf: recipient_delimiter=+
+
+$path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin';
+# $dspam = 'dspam';
+
+$MAXLEVELS = 14;
+$MAXFILES = 1500;
+$MIN_EXPANSION_QUOTA =      100*1024;  # bytes  (default undef, not enforced)
+$MAX_EXPANSION_QUOTA = 300*1024*1024;  # bytes  (default undef, not enforced)
+
+$sa_spam_subject_tag = '***SPAM*** ';
+$defang_virus  = 1;  # MIME-wrap passed infected mail
+$defang_banned = 1;  # MIME-wrap passed mail containing banned name
+# for defanging bad headers only turn on certain minor contents categories:
+$defang_by_ccat{+CC_BADH.",3"} = 1;  # NUL or CR character in header
+$defang_by_ccat{+CC_BADH.",5"} = 1;  # header line longer than 998 characters
+$defang_by_ccat{+CC_BADH.",6"} = 1;  # header field syntax error
+
+
+# OTHER MORE COMMON SETTINGS (defaults may suffice):
+
+$myhostname = 'linux-jfp8.site';
+
+# $notify_method  = 'smtp:[127.0.0.1]:10025';
+# $forward_method = 'smtp:[127.0.0.1]:10025';  # set to undef with milter!
+
+# $final_virus_destiny      = D_DISCARD;
+# $final_banned_destiny     = D_BOUNCE;
+# $final_spam_destiny       = D_BOUNCE;
+# $final_bad_header_destiny = D_PASS;
+
+# $os_fingerprint_method = 'p0f:127.0.0.1:2345';  # to query p0f-analyzer.pl
+
+## hierarchy by which a final setting is chosen:
+##   policy bank (based on port or IP address) -> *_by_ccat
+##   *_by_ccat (based on mail contents) -> *_maps
+##   *_maps (based on recipient address) -> final configuration value
+
+
+# SOME OTHER VARIABLES WORTH CONSIDERING (see amavisd.conf-default for all)
+
+# $warnbadhsender,
+# $warnvirusrecip, $warnbannedrecip, $warnbadhrecip, (or @warn*recip_maps)
+#
+# @bypass_virus_checks_maps, @bypass_spam_checks_maps,
+# @bypass_banned_checks_maps, @bypass_header_checks_maps,
+#
+# @virus_lovers_maps, @spam_lovers_maps,
+# @banned_files_lovers_maps, @bad_header_lovers_maps,
+#
+# @blacklist_sender_maps, @score_sender_maps,
+#
+# $clean_quarantine_method, $virus_quarantine_to, $banned_quarantine_to,
+# $bad_header_quarantine_to, $spam_quarantine_to,
+#
+# $defang_bad_header, $defang_undecipherable, $defang_spam
+
+
+# REMAINING IMPORTANT VARIABLES ARE LISTED HERE BECAUSE OF LONGER ASSIGNMENTS
+
+@keep_decoded_original_maps = (new_RE(
+# qr'^MAIL$',   # retain full original message for virus checking (can be slow)
+  qr'^MAIL-UNDECIPHERABLE$', # recheck full mail if it contains undecipherables
+  qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,
+# qr'^Zip archive data',     # don't trust Archive::Zip
+));
+
+
+# for $banned_namepath_re (a new-style of banned table) see amavisd.conf-sample
+
+$banned_filename_re = new_RE(
+
+### BLOCKED ANYWHERE
+# qr'^UNDECIPHERABLE$',  # is or contains any undecipherable components
+  qr'^\.(exe-ms|dll)$',                   # banned file(1) types, rudimentary
+# qr'^\.(exe|lha|tnef|cab|dll)$',         # banned file(1) types
+
+### BLOCK THE FOLLOWING, EXCEPT WITHIN UNIX ARHIVES:
+# [ qr'^\.(gz|bz2)$'             => 0 ],  # allow any in gzip or bzip2
+  [ qr'^\.(rpm|cpio|tar)$'       => 0 ],  # allow any in Unix-type archives
+
+  qr'.\.(pif|scr)$'i,                     # banned extensions - rudimentary
+# qr'^\.zip$',                            # block zip type
+
+### BLOCK THE FOLLOWING, EXCEPT WITHIN ARHIVES:
+# [ qr'^\.(zip|rar|arc|arj|zoo)$'=> 0 ],  # allow any within these archives
+
+  qr'^application/x-msdownload$'i,        # block these MIME types
+  qr'^application/x-msdos-program$'i,
+  qr'^application/hta$'i,
+
+# qr'^message/partial$'i,         # rfc2046 MIME type
+# qr'^message/external-body$'i,   # rfc2046 MIME type
+
+# qr'^(application/x-msmetafile|image/x-wmf)$'i,  # Windows Metafile MIME type
+# qr'^\.wmf$',                            # Windows Metafile file(1) type
+
+  # block certain double extensions in filenames
+  qr'\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
+
+# qr'\{[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}\}?'i, # Class ID CLSID, strict
+# qr'\{[0-9a-z]{4,}(-[0-9a-z]{4,}){0,7}\}?'i, # Class ID extension CLSID, loose
+
+  qr'.\.(exe|vbs|pif|scr|cpl)$'i,             # banned extension - basic
+# qr'.\.(exe|vbs|pif|scr|cpl|bat|cmd|com)$'i, # banned extension - basic+cmd
+# qr'.\.(ade|adp|app|bas|bat|chm|cmd|com|cpl|crt|emf|exe|fxp|grp|hlp|hta|
+#        inf|ins|isp|js|jse|lnk|mda|mdb|mde|mdw|mdt|mdz|msc|msi|msp|mst|
+#        ops|pcd|pif|prg|reg|scr|sct|shb|shs|vb|vbe|vbs|
+#        wmf|wsc|wsf|wsh)$'ix,  # banned ext - long
+# qr'.\.(ani|cur|ico)$'i,                 # banned cursors and icons filename
+# qr'^\.ani$',                            # banned animated cursor file(1) type
+
+# qr'.\.(mim|b64|bhx|hqx|xxe|uu|uue)$'i,  # banned extension - WinZip vulnerab.
+);
+# See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262631
+# and http://www.cknow.com/vtutor/vtextensions.htm
+
+
+# ENVELOPE SENDER SOFT-WHITELISTING / SOFT-BLACKLISTING
+
+@score_sender_maps = ({ # a by-recipient hash lookup table,
+                        # results from all matching recipient tables are summed
+
+# ## per-recipient personal tables  (NOTE: positive: black, negative: white)
+# 'user1@example.com'  => [{'bla-mobile.press@example.com' => 10.0}],
+# 'user3@example.com'  => [{'.ebay.com'                 => -3.0}],
+# 'user4@example.com'  => [{'cleargreen@cleargreen.com' => -7.0,
+#                           '.cleargreen.com'           => -5.0}],
+
+  ## site-wide opinions about senders (the '.' matches any recipient)
+  '.' => [  # the _first_ matching sender determines the score boost
+
+   new_RE(  # regexp-type lookup table, just happens to be all soft-blacklist
+    [qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou)@'i         => 5.0],
+    [qr'^(greatcasino|investments|lose_weight_today|market\.alert)@'i=> 5.0],
+    [qr'^(money2you|MyGreenCard|new\.tld\.registry|opt-out|opt-in)@'i=> 5.0],
+    [qr'^(optin|saveonlsmoking2002k|specialoffer|specialoffers)@'i   => 5.0],
+    [qr'^(stockalert|stopsnoring|wantsome|workathome|yesitsfree)@'i  => 5.0],
+    [qr'^(your_friend|greatoffers)@'i                                => 5.0],
+    [qr'^(inkjetplanet|marketopt|MakeMoney)\d*@'i                    => 5.0],
+   ),
+
+#  read_hash("/var/amavis/sender_scores_sitewide"),
+
+   { # a hash-type lookup table (associative array)
+     'nobody@cert.org'                        => -3.0,
+     'cert-advisory@us-cert.gov'              => -3.0,
+     'owner-alert@iss.net'                    => -3.0,
+     'slashdot@slashdot.org'                  => -3.0,
+     'securityfocus.com'                      => -3.0,
+     'ntbugtraq@listserv.ntbugtraq.com'       => -3.0,
+     'security-alerts@linuxsecurity.com'      => -3.0,
+     'mailman-announce-admin@python.org'      => -3.0,
+     'amavis-user-admin@lists.sourceforge.net'=> -3.0,
+     'amavis-user-bounces@lists.sourceforge.net' => -3.0,
+     'spamassassin.apache.org'                => -3.0,
+     'notification-return@lists.sophos.com'   => -3.0,
+     'owner-postfix-users@postfix.org'        => -3.0,
+     'owner-postfix-announce@postfix.org'     => -3.0,
+     'owner-sendmail-announce@lists.sendmail.org'   => -3.0,
+     'sendmail-announce-request@lists.sendmail.org' => -3.0,
+     'donotreply@sendmail.org'                => -3.0,
+     'ca+envelope@sendmail.org'               => -3.0,
+     'noreply@freshmeat.net'                  => -3.0,
+     'owner-technews@postel.acm.org'          => -3.0,
+     'ietf-123-owner@loki.ietf.org'           => -3.0,
+     'cvs-commits-list-admin@gnome.org'       => -3.0,
+     'rt-users-admin@lists.fsck.com'          => -3.0,
+     'clp-request@comp.nus.edu.sg'            => -3.0,
+     'surveys-errors@lists.nua.ie'            => -3.0,
+     'emailnews@genomeweb.com'                => -5.0,
+     'yahoo-dev-null@yahoo-inc.com'           => -3.0,
+     'returns.groups.yahoo.com'               => -3.0,
+     'clusternews@linuxnetworx.com'           => -3.0,
+     lc('lvs-users-admin@LinuxVirtualServer.org')    => -3.0,
+     lc('owner-textbreakingnews@CNNIMAIL12.CNN.COM') => -5.0,
+
+     # soft-blacklisting (positive score)
+     'sender@example.net'                     =>  3.0,
+     '.example.net'                           =>  1.0,
+
+   },
+  ],  # end of site-wide tables
+});
+
+
+@decoders = (
+  ['mail', \&do_mime_decode],
+  ['asc',  \&do_ascii],
+  ['uue',  \&do_ascii],
+  ['hqx',  \&do_ascii],
+  ['ync',  \&do_ascii],
+  ['F',    \&do_uncompress, ['unfreeze','freeze -d','melt','fcat'] ],
+  ['Z',    \&do_uncompress, ['uncompress','gzip -d','zcat'] ],
+  ['gz',   \&do_uncompress,  'gzip -d'],
+  ['gz',   \&do_gunzip],
+  ['bz2',  \&do_uncompress,  'bzip2 -d'],
+  ['lzo',  \&do_uncompress,  'lzop -d'],
+  ['rpm',  \&do_uncompress, ['rpm2cpio.pl','rpm2cpio'] ],
+  ['cpio', \&do_pax_cpio,   ['pax','gcpio','cpio'] ],
+  ['tar',  \&do_pax_cpio,   ['pax','gcpio','cpio'] ],
+  ['deb',  \&do_ar,          'ar'],
+# ['a',    \&do_ar,          'ar'],  # unpacking .a seems an overkill
+  ['zip',  \&do_unzip],
+  ['7z',   \&do_7zip,       ['7zr','7za','7z'] ],
+  ['rar',  \&do_unrar,      ['rar','unrar'] ],
+  ['arj',  \&do_unarj,      ['arj','unarj'] ],
+  ['arc',  \&do_arc,        ['nomarch','arc'] ],
+  ['zoo',  \&do_zoo,        ['zoo','unzoo'] ],
+  ['lha',  \&do_lha,         'lha'],
+# ['doc',  \&do_ole,         'ripole'],
+  ['cab',  \&do_cabextract,  'cabextract'],
+  ['tnef', \&do_tnef_ext,    'tnef'],
+  ['tnef', \&do_tnef],
+# ['sit',  \&do_unstuff,     'unstuff'],  # broken/unsafe decoder
+  ['exe',  \&do_executable, ['rar','unrar'], 'lha', ['arj','unarj'] ],
+);
+
+
+@av_scanners = (
+
+# ### http://www.clanfield.info/sophie/ (http://www.vanja.com/tools/sophie/)
+# ['Sophie',
+#   \&ask_daemon, ["{}/\n", '/var/run/sophie'],
+#   qr/(?x)^ 0+ ( : | [\000\r\n]* $)/,  qr/(?x)^ 1 ( : | [\000\r\n]* $)/,
+#   qr/(?x)^ [-+]? \d+ : (.*?) [\000\r\n]* $/ ],
+
+# ### http://www.csupomona.edu/~henson/www/projects/SAVI-Perl/
+# ['Sophos SAVI', \&sophos_savi ],
+
+ ### http://www.clamav.net/
+ ['ClamAV-clamd',
+   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd"],
+   qr/\bOK$/, qr/\bFOUND$/,
+   qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
+ # NOTE: run clamd under the same user as amavisd, or run it under its own
+ #   uid such as clamav, add user clamav to the amavis group, and then add
+ #   AllowSupplementaryGroups to clamd.conf;
+ # NOTE: match socket name (LocalSocket) in clamav.conf to the socket name in
+ #   this entry; when running chrooted one may prefer socket "$MYHOME/clamd".
+
+# ### http://www.clamav.net/ and CPAN  (memory-hungry! clamd is preferred)
+# # note that Mail::ClamAV requires perl to be build with threading!
+# ['Mail::ClamAV', \&ask_clamav, "*", [0], [1], qr/^INFECTED: (.+)/],
+
+# ### http://www.openantivirus.org/
+# ['OpenAntiVirus ScannerDaemon (OAV)',
+#   \&ask_daemon, ["SCAN {}\n", '127.0.0.1:8127'],
+#   qr/^OK/, qr/^FOUND: /, qr/^FOUND: (.+)/ ],
+
+# ### http://www.vanja.com/tools/trophie/
+# ['Trophie',
+#   \&ask_daemon, ["{}/\n", '/var/run/trophie'],
+#   qr/(?x)^ 0+ ( : | [\000\r\n]* $)/,  qr/(?x)^ 1 ( : | [\000\r\n]* $)/,
+#   qr/(?x)^ [-+]? \d+ : (.*?) [\000\r\n]* $/ ],
+
+# ### http://www.grisoft.com/
+# ['AVG Anti-Virus',
+#   \&ask_daemon, ["SCAN {}\n", '127.0.0.1:55555'],
+#   qr/^200/, qr/^403/, qr/^403 .*?: ([^\r\n]+)/ ],
+
+# ### http://www.f-prot.com/
+# ['FRISK F-Prot Daemon',
+#   \&ask_daemon,
+#   ["GET {}/*?-dumb%20-archive%20-packed HTTP/1.0\r\n\r\n",
+#     ['127.0.0.1:10200','127.0.0.1:10201','127.0.0.1:10202',
+#      '127.0.0.1:10203','127.0.0.1:10204'] ],
+#   qr/(?i)<summary[^>]*>clean<\/summary>/,
+#   qr/(?i)<summary[^>]*>infected<\/summary>/,
+#   qr/(?i)<name>(.+)<\/name>/ ],
+
+# ### http://www.sald.com/, http://www.dials.ru/english/, http://www.drweb.ru/
+# ['DrWebD', \&ask_daemon,   # DrWebD 4.31 or later
+#   [pack('N',1).  # DRWEBD_SCAN_CMD
+#    pack('N',0x00280001).   # DONT_CHANGEMAIL, IS_MAIL, RETURN_VIRUSES
+#    pack('N',     # path length
+#      length("$TEMPBASE/amavis-yyyymmddTHHMMSS-xxxxx/parts/pxxx")).
+#    '{}/*'.       # path
+#    pack('N',0).  # content size
+#    pack('N',0),
+#    '/var/drweb/run/drwebd.sock',
+#  # '/var/amavis/var/run/drwebd.sock',   # suitable for chroot
+#  # '/usr/local/drweb/run/drwebd.sock',  # FreeBSD drweb ports default
+#  # '127.0.0.1:3000',                    # or over an inet socket
+#   ],
+#   qr/\A\x00[\x10\x11][\x00\x10]\x00/s,         # IS_CLEAN,EVAL_KEY; SKIPPED
+#   qr/\A\x00[\x00\x01][\x00\x10][\x20\x40\x80]/s, # KNOWN_V,UNKNOWN_V,V._MODIF
+#   qr/\A.{12}(?:infected with )?([^\x00]+)\x00/s,
+# ],
+# # NOTE: If using amavis-milter, change length to:
+# # length("$TEMPBASE/amavis-milter-xxxxxxxxxxxxxx/parts/pxxx").
+
+  ### http://www.kaspersky.com/  (kav4mailservers)
+  ['KasperskyLab AVP - aveclient',
+    ['/usr/local/kav/bin/aveclient','/usr/local/share/kav/bin/aveclient',
+     '/opt/kav/5.5/kav4mailservers/bin/aveclient','aveclient'],
+    '-p /var/run/aveserver -s {}/*',
+    [0,3,6,8], qr/\b(INFECTED|SUSPICION|SUSPICIOUS)\b/,
+    qr/(?:INFECTED|WARNING|SUSPICION|SUSPICIOUS) (.+)/,
+  ],
+  # NOTE: one may prefer [0],[2,3,4,5], depending on how suspicious,
+  # currupted or protected archives are to be handled
+
+  ### http://www.kaspersky.com/
+  ['KasperskyLab AntiViral Toolkit Pro (AVP)', ['avp'],
+    '-* -P -B -Y -O- {}', [0,3,6,8], [2,4],    # any use for -A -K   ?
+    qr/infected: (.+)/,
+    sub {chdir('/opt/AVP') or die "Can't chdir to AVP: $!"},
+    sub {chdir($TEMPBASE) or die "Can't chdir back to $TEMPBASE $!"},
+  ],
+
+  ### The kavdaemon and AVPDaemonClient have been removed from Kasperky
+  ### products and replaced by aveserver and aveclient
+  ['KasperskyLab AVPDaemonClient',
+    [ '/opt/AVP/kavdaemon',       'kavdaemon',
+      '/opt/AVP/AvpDaemonClient', 'AvpDaemonClient',
+      '/opt/AVP/AvpTeamDream',    'AvpTeamDream',
+      '/opt/AVP/avpdc', 'avpdc' ],
+    "-f=$TEMPBASE {}", [0,8], [3,4,5,6], qr/infected: ([^\r\n]+)/ ],
+    # change the startup-script in /etc/init.d/kavd to:
+    #   DPARMS="-* -Y -dl -f=/var/amavis /var/amavis"
+    #   (or perhaps:   DPARMS="-I0 -Y -* /var/amavis" )
+    # adjusting /var/amavis above to match your $TEMPBASE.
+    # The '-f=/var/amavis' is needed if not running it as root, so it
+    # can find, read, and write its pid file, etc., see 'man kavdaemon'.
+    # defUnix.prf: there must be an entry "*/var/amavis" (or whatever
+    #   directory $TEMPBASE specifies) in the 'Names=' section.
+    # cd /opt/AVP/DaemonClients; configure; cd Sample; make
+    # cp AvpDaemonClient /opt/AVP/
+    # su - vscan -c "${PREFIX}/kavdaemon ${DPARMS}"
+
+  ### http://www.centralcommand.com/
+  ['CentralCommand Vexira (new) vascan',
+    ['vascan','/usr/lib/Vexira/vascan'],
+    "-a s --timeout=60 --temp=$TEMPBASE -y $QUARANTINEDIR ".
+    "--log=/var/log/vascan.log {}",
+    [0,3], [1,2,5],
+    qr/(?x)^\s* (?:virus|iworm|macro|mutant|sequence|trojan)\ found:\ ( [^\]\s']+ )\ \.\.\.\ / ],
+    # Adjust the path of the binary and the virus database as needed.
+    # 'vascan' does not allow to have the temp directory to be the same as
+    # the quarantine directory, and the quarantine option can not be disabled.
+    # If $QUARANTINEDIR is not used, then another directory must be specified
+    # to appease 'vascan'. Move status 3 to the second list if password
+    # protected files are to be considered infected.
+
+  ### http://www.avira.com/
+  ### Avira AntiVir (formerly H+BEDV) or (old) CentralCommand Vexira Antivirus
+  ['Avira AntiVir', ['antivir','vexira'],
+    '--allfiles -noboot -nombr -rs -s -z {}', [0], qr/ALERT:|VIRUS:/,
+    qr/(?x)^\s* (?: ALERT: \s* (?: \[ | [^']* ' ) |
+         (?i) VIRUS:\ .*?\ virus\ '?) ( [^\]\s']+ )/ ],
+    # NOTE: if you only have a demo version, remove -z and add 214, as in:
+    #  '--allfiles -noboot -nombr -rs -s {}', [0,214], qr/ALERT:|VIRUS:/,
+
+  ### http://www.commandsoftware.com/
+  ['Command AntiVirus for Linux', 'csav',
+    '-all -archive -packed {}', [50], [51,52,53],
+    qr/Infection: (.+)/ ],
+
+  ### http://www.symantec.com/
+  ['Symantec CarrierScan via Symantec CommandLineScanner',
+    'cscmdline', '-a scan -i 1 -v -s 127.0.0.1:7777 {}',
+    qr/^Files Infected:\s+0$/, qr/^Infected\b/,
+    qr/^(?:Info|Virus Name):\s+(.+)/ ],
+
+  ### http://www.symantec.com/
+  ['Symantec AntiVirus Scan Engine',
+    'savsecls', '-server 127.0.0.1:7777 -mode scanrepair -details -verbose {}',
+    [0], qr/^Infected\b/,
+    qr/^(?:Info|Virus Name):\s+(.+)/ ],
+    # NOTE: check options and patterns to see which entry better applies
+
+  ### http://www.f-secure.com/products/anti-virus/  version 4.65
+   ['F-Secure Antivirus for Linux servers',
+    ['/opt/f-secure/fsav/bin/fsav', 'fsav'],
+    '--delete=no --disinf=no --rename=no --archive=yes --auto=yes '.
+    '--dumb=yes --list=no --mime=yes {}', [0], [3,6,8],
+    qr/(?:infection|Infected|Suspected): (.+)/ ],
+
+# ### http://www.avast.com/
+# ['avast! Antivirus daemon',
+#   \&ask_daemon,	# greets with 220, terminate with QUIT
+#   ["SCAN {}\015\012QUIT\015\012", '/var/run/avast4/mailscanner.sock'],
+#   qr/\t\[\+\]/, qr/\t\[L\]\t/, qr/\t\[L\]\t([^[ \t\015\012]+)/ ],
+
+# ### http://www.avast.com/
+# ['avast! Antivirus - Client/Server Version', 'avastlite',
+#   '-a /var/run/avast4/mailscanner.sock -n {}', [0], [1],
+#   qr/\t\[L\]\t([^[ \t\015\012]+)/ ],
+
+  ['CAI InoculateIT', 'inocucmd',  # retired product
+    '-sec -nex {}', [0], [100],
+    qr/was infected by virus (.+)/ ],
+  # see: http://www.flatmtn.com/computer/Linux-Antivirus_CAI.html
+
+  ### http://www3.ca.com/Solutions/Product.asp?ID=156  (ex InoculateIT)
+  ['CAI eTrust Antivirus', 'etrust-wrapper',
+    '-arc -nex -spm h {}', [0], [101],
+    qr/is infected by virus: (.+)/ ],
+    # NOTE: requires suid wrapper around inocmd32; consider flag: -mod reviewer
+    # see http://marc.theaimsgroup.com/?l=amavis-user&m=109229779912783
+
+  ### http://mks.com.pl/english.html
+  ['MkS_Vir for Linux (beta)', ['mks32','mks'],
+    '-s {}/*', [0], [1,2],
+    qr/--[ \t]*(.+)/ ],
+
+  ### http://mks.com.pl/english.html
+  ['MkS_Vir daemon', 'mksscan',
+    '-s -q {}', [0], [1..7],
+    qr/^... (\S+)/ ],
+
+# ### http://www.nod32.com/,  version v2.52 and above
+# ['ESET NOD32 for Linux Mail servers',
+#   ['/opt/eset/nod32/bin/nod32cli', 'nod32cli'],
+#    '--subdir --files -z --sfx --rtp --adware --unsafe --pattern --heur '.
+#    '-w -a --action-on-infected=accept --action-on-uncleanable=accept '.
+#    '--action-on-notscanned=accept {}',
+#   [0,3], [1,2], qr/virus="([^"]+)"/ ],
+
+  ### http://www.eset.com/, version v2.7
+  ['ESET NOD32 Linux Mail Server - command line interface',
+    ['/usr/bin/nod32cli', '/opt/eset/nod32/bin/nod32cli', 'nod32cli'],
+    '--subdir {}', [0], [1,2], qr/virus="([^"]+)"/ ],
+
+  ## http://www.nod32.com/,  NOD32LFS version 2.5 and above
+  ['ESET NOD32 for Linux File servers',
+    ['/opt/eset/nod32/sbin/nod32','nod32'],
+    '--files -z --mail --sfx --rtp --adware --unsafe --pattern --heur '.
+    '-w -a --action=1 -b {}',
+    [0], [1,10], qr/^object=.*, virus="(.*?)",/ ],
+
+# Experimental, based on posting from Rado Dibarbora (Dibo) on 2002-05-31
+# ['ESET Software NOD32 Client/Server (NOD32SS)',
+#   \&ask_daemon2,    # greets with 200, persistent, terminate with QUIT
+#   ["SCAN {}/*\r\n", '127.0.0.1:8448' ],
+#   qr/^200 File OK/, qr/^201 /, qr/^201 (.+)/ ],
+
+  ### http://www.norman.com/products_nvc.shtml
+  ['Norman Virus Control v5 / Linux', 'nvcc',
+    '-c -l:0 -s -u -temp:$TEMPBASE {}', [0,10,11], [1,2,14],
+    qr/(?i).* virus in .* -> \'(.+)\'/ ],
+
+  ### http://www.pandasoftware.com/
+  ['Panda CommandLineSecure 9 for Linux',
+    ['/opt/pavcl/usr/bin/pavcl','pavcl'],
+    '-auto -aex -heu -cmp -nbr -nor -nos -eng -nob {}',
+    qr/Number of files infected[ .]*: 0+(?!\d)/,
+    qr/Number of files infected[ .]*: 0*[1-9]/,
+    qr/Found virus :\s*(\S+)/ ],
+  # NOTE: for efficiency, start the Panda in resident mode with 'pavcl -tsr'
+  # before starting amavisd - the bases are then loaded only once at startup.
+  # To reload bases in a signature update script:
+  #   /opt/pavcl/usr/bin/pavcl -tsr -ulr; /opt/pavcl/usr/bin/pavcl -tsr
+  # Please review other options of pavcl, for example:
+  #  -nomalw, -nojoke, -nodial, -nohackt, -nospyw, -nocookies
+
+# ### http://www.pandasoftware.com/
+# ['Panda Antivirus for Linux', ['pavcl'],
+#   '-TSR -aut -aex -heu -cmp -nbr -nor -nso -eng {}',
+#   [0], [0x10, 0x30, 0x50, 0x70, 0x90, 0xB0, 0xD0, 0xF0],
+#   qr/Found virus :\s*(\S+)/ ],
+
+# GeCAD AV technology is acquired by Microsoft; RAV has been discontinued.
+# Check your RAV license terms before fiddling with the following two lines!
+# ['GeCAD RAV AntiVirus 8', 'ravav',
+#   '--all --archive --mail {}', [1], [2,3,4,5], qr/Infected: (.+)/ ],
+# # NOTE: the command line switches changed with scan engine 8.5 !
+# # (btw, assigning stdin to /dev/null causes RAV to fail)
+
+  ### http://www.nai.com/
+  ['NAI McAfee AntiVirus (uvscan)', 'uvscan',
+    '--secure -rv --mime --summary --noboot - {}', [0], [13],
+    qr/(?x) Found (?:
+        \ the\ (.+)\ (?:virus|trojan)  |
+        \ (?:virus|trojan)\ or\ variant\ ([^ ]+)  |
+        :\ (.+)\ NOT\ a\ virus)/,
+  # sub {$ENV{LD_PRELOAD}='/lib/libc.so.6'},
+  # sub {delete $ENV{LD_PRELOAD}},
+  ],
+  # NOTE1: with RH9: force the dynamic linker to look at /lib/libc.so.6 before
+  # anything else by setting environment variable LD_PRELOAD=/lib/libc.so.6
+  # and then clear it when finished to avoid confusing anything else.
+  # NOTE2: to treat encrypted files as viruses replace the [13] with:
+  #  qr/^\s{5,}(Found|is password-protected|.*(virus|trojan))/
+
+  ### http://www.virusbuster.hu/en/
+  ['VirusBuster', ['vbuster', 'vbengcl'],
+    "{} -ss -i '*' -log=$MYHOME/vbuster.log", [0], [1],
+    qr/: '(.*)' - Virus/ ],
+  # VirusBuster Ltd. does not support the daemon version for the workstation
+  # engine (vbuster-eng-1.12-linux-i386-libc6.tgz) any longer. The names of
+  # binaries, some parameters AND return codes have changed (from 3 to 1).
+  # See also the new Vexira entry 'vascan' which is possibly related.
+
+# ### http://www.virusbuster.hu/en/
+# ['VirusBuster (Client + Daemon)', 'vbengd',
+#   '-f -log scandir {}', [0], [3],
+#   qr/Virus found = (.*);/ ],
+# # HINT: for an infected file it always returns 3,
+# # although the man-page tells a different story
+
+  ### http://www.cyber.com/
+  ['CyberSoft VFind', 'vfind',
+    '--vexit {}/*', [0], [23], qr/##==>>>> VIRUS ID: CVDL (.+)/,
+  # sub {$ENV{VSTK_HOME}='/usr/lib/vstk'},
+  ],
+
+  ### http://www.avast.com/
+  ['avast! Antivirus', ['/usr/bin/avastcmd','avastcmd'],
+    '-a -i -n -t=A {}', [0], [1], qr/\binfected by:\s+([^ \t\n\[\]]+)/ ],
+
+  ### http://www.ikarus-software.com/
+  ['Ikarus AntiVirus for Linux', 'ikarus',
+    '{}', [0], [40], qr/Signature (.+) found/ ],
+
+  ### http://www.bitdefender.com/
+  ['BitDefender', 'bdc',
+    '--arc --mail {}', qr/^Infected files *:0+(?!\d)/,
+    qr/^(?:Infected files|Identified viruses|Suspect files) *:0*[1-9]/,
+    qr/(?:suspected|infected): (.*)(?:\033|$)/ ],
+  # consider also: --all --nowarn --alev=15 --flev=15.  The --all argument may
+  # not apply to your version of bdc, check documentation and see 'bdc --help'
+
+  ### ArcaVir for Linux and Unix http://www.arcabit.pl/
+  ['ArcaVir for Linux', ['arcacmd','arcacmd.static'],
+    '-v 1 -summary 0 -s {}', [0], [1,2],
+    qr/(?:VIR|WIR):[ \t]*(.+)/ ],
+
+# ['File::Scan', sub {Amavis::AV::ask_av(sub{
+#   use File::Scan; my($fn)=@_;
+#   my($f)=File::Scan->new(max_txt_size=>0, max_bin_size=>0);
+#   my($vname) = $f->scan($fn);
+#   $f->error ? (2,"Error: ".$f->error)
+#   : ($vname ne '') ? (1,"$vname FOUND") : (0,"Clean")}, @_) },
+#   ["{}/*"], [0], [1], qr/^(.*) FOUND$/ ],
+
+# ### fully-fledged checker for JPEG marker segments of invalid length
+# ['check-jpeg',
+#   sub { use JpegTester (); Amavis::AV::ask_av(\&JpegTester::test_jpeg, @_) },
+#   ["{}/*"], undef, [1], qr/^(bad jpeg: .*)$/ ],
+# # NOTE: place file JpegTester.pm somewhere where Perl can find it,
+# #       for example in /usr/local/lib/perl5/site_perl
+
+);
+
+
+@av_scanners_backup = (
+
+  ### http://www.clamav.net/   - backs up clamd or Mail::ClamAV
+  ['ClamAV-clamscan', 'clamscan',
+    "--stdout --no-summary -r --tempdir=$TEMPBASE {}",
+    [0], qr/:.*\sFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
+
+  ### http://www.f-prot.com/   - backs up F-Prot Daemon
+  ['FRISK F-Prot Antivirus', ['f-prot','f-prot.sh'],
+    '-dumb -archive -packed {}', [0,8], [3,6],   # or: [0], [3,6,8],
+    qr/(?:Infection:|security risk named) (.+)|\s+contains\s+(.+)$/ ],
+
+  ### http://www.trendmicro.com/   - backs up Trophie
+  ['Trend Micro FileScanner', ['/etc/iscan/vscan','vscan'],
+    '-za -a {}', [0], qr/Found virus/, qr/Found virus (.+) in/ ],
+
+  ### http://www.sald.com/, http://drweb.imshop.de/   - backs up DrWebD
+  ['drweb - DrWeb Antivirus',  # security LHA hole in Dr.Web 4.33 and earlier
+    ['/usr/local/drweb/drweb', '/opt/drweb/drweb', 'drweb'],
+    '-path={} -al -go -ot -cn -upn -ok-',
+    [0,32], [1,9,33], qr' infected (?:with|by)(?: virus)? (.*)$'],
+
+   ### http://www.kaspersky.com/
+   ['Kaspersky Antivirus v5.5',
+     ['/opt/kaspersky/kav4fs/bin/kav4fs-kavscanner',
+      '/opt/kav/5.5/kav4unix/bin/kavscanner',
+      '/opt/kav/5.5/kav4mailservers/bin/kavscanner', 'kavscanner'],
+     '-i0 -xn -xp -mn -R -ePASBME {}/*', [0,10,15], [5,20,21,25],
+     qr/(?:INFECTED|WARNING|SUSPICION|SUSPICIOUS) (.*)/ ,
+#    sub {chdir('/opt/kav/bin') or die "Can't chdir to kav: $!"},
+#    sub {chdir($TEMPBASE) or die "Can't chdir back to $TEMPBASE $!"},
+   ],
+
+# Commented out because the name 'sweep' clashes with Debian and FreeBSD
+# package/port of an audio editor. Make sure the correct 'sweep' is found
+# in the path when enabling.
+#
+# ### http://www.sophos.com/   - backs up Sophie or SAVI-Perl
+# ['Sophos Anti Virus (sweep)', 'sweep',
+#   '-nb -f -all -rec -ss -sc -archive -cab -mime -oe -tnef '.
+#   '--no-reset-atime {}',
+#   [0,2], qr/Virus .*? found/,
+#   qr/^>>> Virus(?: fragment)? '?(.*?)'? found/,
+# ],
+# # other options to consider: -idedir=/usr/local/sav
+
+# always succeeds (uncomment to consider mail clean if all other scanners fail)
+# ['always-clean', sub {0}],
+
+);
+
+
+@bypass_virus_checks_maps = (
+   \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
+
+@bypass_spam_checks_maps = (
+   \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re);
+
+#   
+# Database connection settings
+#
+
+@lookup_sql_dsn =
+   ( ['DBI:mysql:database={mysql_server_database};host={mysql_server_ip};port={mysql_server_port}', '{mysql_server_ispconfig_user}', '{mysql_server_ispconfig_password}'] );
+
+# @storage_sql_dsn = @lookup_sql_dsn;  # none, same, or separate database
+#$sql_select_policy = 'SELECT "Y" as local FROM mail_domain WHERE CONCAT("@",domain) IN (%k)';
+# $banned_files_quarantine_method = 'sql';
+# $spam_quarantine_method         = 'sql';
+
+#
+# SQL Select statements
+#
+
+$sql_select_policy =
+   'SELECT *,spamfilter_users.id'.
+   ' FROM spamfilter_users LEFT JOIN spamfilter_policy ON spamfilter_users.policy_id=spamfilter_policy.id'.
+   ' WHERE spamfilter_users.email IN (%k) ORDER BY spamfilter_users.priority DESC';
+
+
+$sql_select_white_black_list = 'SELECT wb FROM spamfilter_wblist'.
+    ' WHERE (spamfilter_wblist.rid=?) AND (spamfilter_wblist.email IN (%k))' .
+    ' ORDER BY spamfilter_wblist.priority DESC';
+
+#
+# Quarantine settings
+#
+
+$final_virus_destiny = D_BOUNCE;
+$final_spam_destiny = D_DISCARD;
+$final_banned_destiny = D_BOUNCE;
+$final_bad_header_destiny = D_DISCARD;
+
+#
+# Disable spam and virus notifications for the admin user.
+# Can be overridden by the policies in mysql
+#
+
+$virus_admin = undef;
+$spam_admin = undef;
+
+
+#
+# Enable Logging
+#
+
+$DO_SYSLOG = 1;
+$LOGFILE = "/var/log/amavis.log";  # (defaults to empty, no log)
+
+$log_level = 5;                # (defaults to 0)
+
+
+1;  # insure a defined return
diff --git a/install/tpl/opensuse_pureftpd_conf.master b/install/tpl/opensuse_pureftpd_conf.master
new file mode 100644
index 0000000000..f0d2f8c828
--- /dev/null
+++ b/install/tpl/opensuse_pureftpd_conf.master
@@ -0,0 +1,447 @@
+
+############################################################
+#                                                          #
+#         Configuration file for pure-ftpd wrappers        #
+#                                                          #
+############################################################
+
+# If you want to run Pure-FTPd with this configuration   
+# instead of command-line options, please run the
+# following command :
+#
+# /usr/sbin/pure-config.pl /usr/etc/pure-ftpd.conf
+#
+# Please don't forget to have a look at documentation at
+# http://www.pureftpd.org/documentation.shtml for a complete list of
+# options.
+
+# Cage in every user in his home directory
+
+ChrootEveryone              yes
+
+
+
+# If the previous option is set to "no", members of the following group
+# won't be caged. Others will be. If you don't want chroot()ing anyone,
+# just comment out ChrootEveryone and TrustedGID.
+
+# TrustedGID                    100
+
+
+
+# Turn on compatibility hacks for broken clients
+
+BrokenClientsCompatibility  no
+
+
+
+# Maximum number of simultaneous users
+
+MaxClientsNumber            10
+
+
+
+# Fork in background
+
+Daemonize                   yes
+
+
+
+# Maximum number of sim clients with the same IP address
+
+MaxClientsPerIP             3
+
+
+
+# If you want to log all client commands, set this to "yes".
+# This directive can be duplicated to also log server responses.
+
+VerboseLog                  no
+
+
+# Allow dot-files
+AllowDotFiles               yes
+
+
+# List dot-files even when the client doesn't send "-a".
+
+DisplayDotFiles             yes
+
+
+
+# Don't allow authenticated users - have a public anonymous FTP only.
+
+AnonymousOnly               no
+
+
+
+# Disallow anonymous connections. Only allow authenticated users.
+
+NoAnonymous                 yes
+
+
+
+# Syslog facility (auth, authpriv, daemon, ftp, security, user, local*)
+# The default facility is "ftp". "none" disables logging.
+
+SyslogFacility              ftp
+
+
+
+# Display fortune cookies
+
+# FortunesFile              /usr/share/fortune/zippy
+
+
+
+# Don't resolve host names in log files. Logs are less verbose, but 
+# it uses less bandwidth. Set this to "yes" on very busy servers or
+# if you don't have a working DNS.
+
+DontResolve                 yes
+
+
+
+# Maximum idle time in minutes (default = 15 minutes)
+
+MaxIdleTime                 15
+
+
+
+# LDAP configuration file (see README.LDAP)
+
+# LDAPConfigFile                /etc/pure-ftpd/pureftpd-ldap.conf
+
+
+
+# MySQL configuration file (see README.MySQL)
+
+MySQLConfigFile               /etc/pure-ftpd/db/mysql.conf
+
+
+# Postgres configuration file (see README.PGSQL)
+
+# PGSQLConfigFile               /etc/pure-ftpd/pureftpd-pgsql.conf
+
+
+# PureDB user database (see README.Virtual-Users)
+
+# PureDB                        /etc/pure-ftpd/pureftpd.pdb
+
+
+# Path to pure-authd socket (see README.Authentication-Modules)
+
+# ExtAuth                       /var/run/ftpd.sock
+
+
+
+# If you want to enable PAM authentication, uncomment the following line
+
+# PAMAuthentication             yes
+
+
+
+# If you want simple Unix (/etc/passwd) authentication, uncomment this
+
+# UnixAuthentication            yes
+
+
+
+# Please note that LDAPConfigFile, MySQLConfigFile, PAMAuthentication and
+# UnixAuthentication can be used only once, but they can be combined
+# together. For instance, if you use MySQLConfigFile, then UnixAuthentication,
+# the SQL server will be asked. If the SQL authentication fails because the
+# user wasn't found, another try # will be done with /etc/passwd and
+# /etc/shadow. If the SQL authentication fails because the password was wrong,
+# the authentication chain stops here. Authentication methods are chained in
+# the order they are given. 
+
+
+
+# 'ls' recursion limits. The first argument is the maximum number of
+# files to be displayed. The second one is the max subdirectories depth
+
+LimitRecursion              2000 8
+
+
+
+# Are anonymous users allowed to create new directories ?
+
+AnonymousCanCreateDirs      no
+
+
+
+# If the system is more loaded than the following value,
+# anonymous users aren't allowed to download.
+
+MaxLoad                     4
+
+
+
+# Port range for passive connections replies. - for firewalling.
+
+# PassivePortRange          30000 50000
+
+
+
+# Force an IP address in PASV/EPSV/SPSV replies. - for NAT.
+# Symbolic host names are also accepted for gateways with dynamic IP
+# addresses.
+
+# ForcePassiveIP                192.168.0.1
+
+
+
+# Upload/download ratio for anonymous users.
+
+# AnonymousRatio                1 10
+
+
+
+# Upload/download ratio for all users.
+# This directive superscedes the previous one.
+
+# UserRatio                 1 10
+
+
+
+# Disallow downloading of files owned by "ftp", ie.
+# files that were uploaded but not validated by a local admin.
+
+AntiWarez                   yes
+
+
+
+# IP address/port to listen to (default=all IP and port 21).
+
+# Bind                      127.0.0.1,21
+
+
+
+# Maximum bandwidth for anonymous users in KB/s
+
+# AnonymousBandwidth            8
+
+
+
+# Maximum bandwidth for *all* users (including anonymous) in KB/s
+# Use AnonymousBandwidth *or* UserBandwidth, both makes no sense.
+
+# UserBandwidth             8
+
+
+
+# File creation mask. <umask for files>:<umask for dirs> .
+# 177:077 if you feel paranoid.
+
+Umask                       177:077
+
+
+
+# Minimum UID for an authenticated user to log in.
+
+MinUID                      40
+
+
+
+# Allow FXP transfers for authenticated users.
+
+AllowUserFXP                no
+
+
+
+# Allow anonymous FXP for anonymous and non-anonymous users.
+
+AllowAnonymousFXP           no
+
+
+
+# Users can't delete/write files beginning with a dot ('.')
+# even if they own them. If TrustedGID is enabled, this group
+# will have access to dot-files, though.
+
+ProhibitDotFilesWrite       yes
+
+
+
+# Prohibit *reading* of files beginning with a dot (.history, .ssh...)
+
+ProhibitDotFilesRead        no
+
+
+
+# Never overwrite files. When a file whoose name already exist is uploaded,
+# it get automatically renamed to file.1, file.2, file.3, ...
+
+AutoRename                  yes
+
+
+
+# Disallow anonymous users to upload new files (no = upload is allowed)
+
+AnonymousCantUpload         yes
+
+
+
+# Only connections to this specific IP address are allowed to be
+# non-anonymous. You can use this directive to open several public IPs for
+# anonymous FTP, and keep a private firewalled IP for remote administration.
+# You can also only allow a non-routable local IP (like 10.x.x.x) to
+# authenticate, and keep a public anon-only FTP server on another IP.
+
+#TrustedIP                  10.1.1.1
+
+
+
+# If you want to add the PID to every logged line, uncomment the following
+# line.
+
+#LogPID                     yes
+
+
+
+# Create an additional log file with transfers logged in a Apache-like format :
+# fw.c9x.org - jedi [13/Dec/1975:19:36:39] "GET /ftp/linux.tar.bz2" 200 21809338
+# This log file can then be processed by www traffic analyzers.
+
+# AltLog                     clf:/var/log/pureftpd.log
+
+
+
+# Create an additional log file with transfers logged in a format optimized
+# for statistic reports.
+
+# AltLog                     stats:/var/log/pureftpd.log
+
+
+
+# Create an additional log file with transfers logged in the standard W3C
+# format (compatible with most commercial log analyzers)
+
+# AltLog                     w3c:/var/log/pureftpd.log
+
+
+
+# Disallow the CHMOD command. Users can't change perms of their files.
+
+#NoChmod                     yes
+
+
+
+# Allow users to resume and upload files, but *NOT* to delete them.
+
+#KeepAllFiles                yes
+
+
+
+# Automatically create home directories if they are missing
+
+#CreateHomeDir               yes
+
+
+
+# Enable virtual quotas. The first number is the max number of files.
+# The second number is the max size of megabytes.
+# So 1000:10 limits every user to 1000 files and 10 Mb.
+
+#Quota                       1000:10
+
+
+
+# If your pure-ftpd has been compiled with standalone support, you can change
+# the location of the pid file. The default is /var/run/pure-ftpd.pid
+
+#PIDFile                     /var/run/pure-ftpd.pid
+
+
+
+# If your pure-ftpd has been compiled with pure-uploadscript support,
+# this will make pure-ftpd write info about new uploads to
+# /var/run/pure-ftpd.upload.pipe so pure-uploadscript can read it and
+# spawn a script to handle the upload.
+
+#CallUploadScript yes
+
+
+
+# This option is useful with servers where anonymous upload is 
+# allowed. As /var/ftp is in /var, it save some space and protect 
+# the log files. When the partition is more that X percent full,
+# new uploads are disallowed.
+
+MaxDiskUsage               99
+
+
+
+# Set to 'yes' if you don't want your users to rename files.
+
+NoRename                  yes
+
+
+
+# Be 'customer proof' : workaround against common customer mistakes like
+# 'chmod 0 public_html', that are valid, but that could cause ignorant
+# customers to lock their files, and then keep your technical support busy
+# with silly issues. If you're sure all your users have some basic Unix
+# knowledge, this feature is useless. If you're a hosting service, enable it.
+
+CustomerProof              yes
+
+
+
+# Per-user concurrency limits. It will only work if the FTP server has
+# been compiled with --with-peruserlimits (and this is the case on
+# most binary distributions) .
+# The format is : <max sessions per user>:<max anonymous sessions>
+# For instance, 3:20 means that the same authenticated user can have 3 active
+# sessions max. And there are 20 anonymous sessions max.
+
+# PerUserLimits            3:20
+
+
+
+# When a file is uploaded and there is already a previous version of the file
+# with the same name, the old file will neither get removed nor truncated.
+# Upload will take place in a temporary file and once the upload is complete,
+# the switch to the new version will be atomic. For instance, when a large PHP
+# script is being uploaded, the web server will still serve the old version and
+# immediatly switch to the new one as soon as the full file will have been
+# transfered. This option is incompatible with virtual quotas.
+
+# NoTruncate               yes
+
+
+
+# This option can accept three values :
+# 0 : disable SSL/TLS encryption layer (default).
+# 1 : accept both traditional and encrypted sessions.
+# 2 : refuse connections that don't use SSL/TLS security mechanisms,
+#     including anonymous sessions.
+# Do _not_ uncomment this blindly. Be sure that :
+# 1) Your server has been compiled with SSL/TLS support (--with-tls),
+# 2) A valid certificate is in place,
+# 3) Only compatible clients will log in.
+
+# TLS                      1
+
+
+
+# Listen only to IPv4 addresses in standalone mode (ie. disable IPv6)
+# By default, both IPv4 and IPv6 are enabled.
+
+# IPV4Only                 yes
+
+
+
+# Listen only to IPv6 addresses in standalone mode (ie. disable IPv4)
+# By default, both IPv4 and IPv6 are enabled.
+
+# IPV6Only                 yes
+
+# UTF-8 support for file names (RFC 2640)
+# Define charset of the server filesystem and optionnally the default charset
+# for remote clients if they don't use UTF-8.
+# Works only if pure-ftpd has been compiled with --with-rfc2640
+
+# FileSystemCharset	big5
+# ClientCharset		big5
diff --git a/install/update.php b/install/update.php
index 781f134b02..f56a928472 100644
--- a/install/update.php
+++ b/install/update.php
@@ -249,7 +249,7 @@ if($reconfigure_services_answer == 'yes') {
 	system("/etc/init.d/courier-pop-ssl restart");
 	system("/etc/init.d/apache2 restart");
 	system("/etc/init.d/pure-ftpd-mysql restart");
-	system("/etc/init.d/mydns restart");
+	system("/etc/init.d/mydns restart &> /dev/null");
 }
 
 echo "Update finished.\n";
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index a681b1d287..3348390863 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -12,6 +12,13 @@
 	ErrorDocument 405 /error/methodNotAllowed.html
 	ErrorDocument 500 /error/internalServerError.html
 	ErrorDocument 503 /error/overloaded.html
+	
+    <Directory <tmpl_var name='web_document_root'>/>
+        Options None
+        AllowOverride Indexes AuthConfig Limit FileInfo
+        Order allow,deny
+        Allow from all
+    </Directory>
 
 <tmpl_if name='alias'>
     ServerAlias <tmpl_var name='alias'>
-- 
GitLab