diff --git a/install/dist/lib/centos_base.lib.php b/install/dist/lib/centos_base.lib.php
index 0fe988439d8098c255bf216489ab6e0053d99e2e..8c71db34a66531ec2cecc8f496ccb2113e4253d1 100644
--- a/install/dist/lib/centos_base.lib.php
+++ b/install/dist/lib/centos_base.lib.php
@@ -83,31 +83,28 @@ class installer_centos extends installer_dist {
 
 		$config_dir = $conf['postfix']['config_dir'];
 
-		// Adding amavis-services to the master.cf file if the service does not already exists
-		$add_amavis = !$this->get_postfix_service('amavis','unix');
-		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
-		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
-
-		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
-			//* backup master.cf
-			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
-			// adjust amavis-config
-			if($add_amavis) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10025) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10027) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-		}
+		// Adding amavis-services to the master.cf file
+
+		// backup master.cf
+		if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
+
+		// first remove the old service definitions
+		$this->remove_postfix_service('amavis','unix');
+		$this->remove_postfix_service('127.0.0.1:10025','inet');
+		$this->remove_postfix_service('127.0.0.1:10027','inet');
+
+		// then add them back
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
 
 		removeLine('/etc/sysconfig/freshclam', 'FRESHCLAM_DELAY=disabled-warn   # REMOVE ME', 1);
 		replaceLine('/etc/freshclam.conf', 'Example', '# Example', 1);
diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php
index 2e46ed16d351ae9bf906c588e8f39a36bd40989c..71809ac81ea0ec084a5dfa83031e3bb2e7859da2 100644
--- a/install/dist/lib/fedora.lib.php
+++ b/install/dist/lib/fedora.lib.php
@@ -330,31 +330,28 @@ class installer_dist extends installer_base {
 
 		$config_dir = $conf['postfix']['config_dir'];
 
-		// Adding amavis-services to the master.cf file if the service does not already exists
-		$add_amavis = !$this->get_postfix_service('amavis','unix');
-		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
-		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
-
-		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
-			//* backup master.cf
-			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
-			// adjust amavis-config
-			if($add_amavis) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10025) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10027) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-		}
+		// Adding amavis-services to the master.cf file
+
+		// backup master.cf
+		if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
+
+		// first remove the old service definitions
+		$this->remove_postfix_service('amavis','unix');
+		$this->remove_postfix_service('127.0.0.1:10025','inet');
+		$this->remove_postfix_service('127.0.0.1:10027','inet');
+
+		// then add them back
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
 
 		removeLine('/etc/sysconfig/freshclam', 'FRESHCLAM_DELAY=disabled-warn   # REMOVE ME', 1);
 		replaceLine('/etc/freshclam.conf', 'Example', '# Example', 1);
diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php
index 83a4b5ffafee0b140530913f8c9bde449dad0b04..ebb742a3683e1c64b72cbc7e477223a1527928a8 100644
--- a/install/dist/lib/gentoo.lib.php
+++ b/install/dist/lib/gentoo.lib.php
@@ -444,31 +444,28 @@ class installer extends installer_base
 
 		$config_dir = $conf['postfix']['config_dir'];
 
-		// Adding amavis-services to the master.cf file if the service does not already exists
-		$add_amavis = !$this->get_postfix_service('amavis','unix');
-		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
-		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
-
-		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
-			//* backup master.cf
-			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
-			// adjust amavis-config
-			if($add_amavis) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10025) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10027) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-		}
+		// Adding amavis-services to the master.cf file
+
+		// backup master.cf
+		if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
+
+		// first remove the old service definitions
+		$this->remove_postfix_service('amavis','unix');
+		$this->remove_postfix_service('127.0.0.1:10025','inet');
+		$this->remove_postfix_service('127.0.0.1:10027','inet');
+
+		// then add them back
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
 
 		//* Add the clamav user to the amavis group
 		exec('usermod -a -G amavis clamav');
diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php
index 3effb1d10c8cc61af717601cdaece67e784e9444..7cc368a14e3fdab0351f06f6c088c9c1d6611257 100644
--- a/install/dist/lib/opensuse.lib.php
+++ b/install/dist/lib/opensuse.lib.php
@@ -513,31 +513,28 @@ class installer_dist extends installer_base {
 
 		$config_dir = $conf['postfix']['config_dir'];
 
-		// Adding amavis-services to the master.cf file if the service does not already exists
-		$add_amavis = !$this->get_postfix_service('amavis','unix');
-		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
-		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
-
-		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
-			//* backup master.cf
-			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
-			// adjust amavis-config
-			if($add_amavis) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10025) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10027) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-		}
+		// Adding amavis-services to the master.cf file
+
+		// backup master.cf
+		if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
+
+		// first remove the old service definitions
+		$this->remove_postfix_service('amavis','unix');
+		$this->remove_postfix_service('127.0.0.1:10025','inet');
+		$this->remove_postfix_service('127.0.0.1:10027','inet');
+
+		// then add them back
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
+
+		$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
+		af($config_dir.'/master.cf', $content);
+		unset($content);
 
 		// Add the clamav user to the vscan group
 		//exec('groupmod --add-user clamav vscan');
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index d5f3f6b6aadad22a94c6f373a04e24313afb9d87..eb69090579d393cff2dc639dda72401675df970d 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -788,7 +788,7 @@ class installer_base {
 					$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
 				}
 
-				$query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`) ON ?? TO ?@?";
+				$query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`, `rendered_zone`) ON ?? TO ?@?";
 				if ($verbose){
 					echo $query ."\n";
 				}
@@ -1107,7 +1107,7 @@ class installer_base {
 		$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
 		unset($server_ini_rec);
 
-		//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removeal after an update
+		//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removal after an update
 		$rbl_list = '';
 		if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
 			$rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list']));
@@ -1647,6 +1647,12 @@ class installer_base {
 	public function configure_amavis() {
 		global $conf;
 
+		//* These postconf commands will be executed on installation and update
+		$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
+		$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
+		$mail_server = ($server_ini_rec['mail_server']) ? true : false;
+		unset($server_ini_rec);
+
 		// amavisd user config file
 		$configfile = 'amavisd_user_config';
 		if(is_file($conf['amavis']['config_dir'].'/conf.d/50-user')) copy($conf['amavis']['config_dir'].'/conf.d/50-user', $conf['amavis']['config_dir'].'/50-user~');
@@ -1661,63 +1667,82 @@ class installer_base {
 		chmod($conf['amavis']['config_dir'].'/conf.d/50-user', 0640);
 		chgrp($conf['amavis']['config_dir'].'/conf.d/50-user', 'amavis');
 
-		// TODO: chmod and chown on the config file
-
-		// test if lmtp if available
-		$configure_lmtp = $this->get_postfix_service('lmtp','unix');
+		$config_dir = $conf['postfix']['config_dir'];
+		$quoted_config_dir = preg_quote($config_dir, '|');
 
-		// Adding the amavisd commands to the postfix configuration
-		// Add array for no error in foreach and maybe future options
-		$postconf_commands = array ();
+		$mail_config = $server_ini_array['mail'];
+		//* only change postfix config if amavisd is active filter
+		if($mail_server && $mail_config['content_filter'] === 'amavisd') {
+			// test if lmtp if available
+			$configure_lmtp = $this->get_postfix_service('lmtp','unix');
 
-		// Check for amavisd -> pure webserver with postfix for mailing without antispam
-		if ($conf['amavis']['installed']) {
-			$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
-			$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
-			$postconf_commands[] = 'receive_override_options = no_address_mappings';
-		}
+			// Adding the amavisd commands to the postfix configuration
+			$postconf_commands = array ();
 
-		// Make a backup copy of the main.cf file
-		copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
+			// Check for amavisd -> pure webserver with postfix for mailing without antispam
+			if ($conf['amavis']['installed']) {
+				$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
+				$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
+				$postconf_commands[] = 'receive_override_options = no_address_mappings';
+				$postconf_commands[] = 'address_verify_virtual_transport = smtp:[127.0.0.1]:10025';
+				$postconf_commands[] = 'address_verify_transport_maps = static:smtp:[127.0.0.1]:10025';
+			}
 
-		// 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");
-		}
+			$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
+			$new_options = array();
+			foreach ($options as $value) {
+				$value = trim($value);
+				if ($value == '') continue;
+				if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
+					continue;
+				}
+				$new_options[] = $value;
+			}
+			if ($configure_lmtp) {
+				for ($i = 0; isset($new_options[$i]); $i++) {
+					if ($new_options[$i] == 'reject_unlisted_recipient') {
+						array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf"));
+						break;
+					}
+				}
+				# postfix < 3.3 needs this when using reject_unverified_recipient:
+				if(version_compare($postfix_version, 3.3, '<')) {
+					$postconf_commands[] = "enable_original_recipient = yes";
+				}
+			}
+			$postconf_commands[] = "smtpd_recipient_restrictions = ".implode(", ", $new_options);
 
-		$config_dir = $conf['postfix']['config_dir'];
+			// Make a backup copy of the main.cf file
+			copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~2');
 
-		// Adding amavis-services to the master.cf file if the service does not already exists
-//		$add_amavis = !$this->get_postfix_service('amavis','unix');
-//		$add_amavis_10025 = !$this->get_postfix_service('127.0.0.1:10025','inet');
-//		$add_amavis_10027 = !$this->get_postfix_service('127.0.0.1:10027','inet');
-		//*TODO: check templates against existing postfix-services to make sure we use the template
+			// 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");
+			}
 
-		// Or just remove the old service definitions and add them again?
-		$add_amavis = $this->remove_postfix_service('amavis','unix');
-		$add_amavis_10025 = $this->remove_postfix_service('127.0.0.1:10025','inet');
-		$add_amavis_10027 = $this->remove_postfix_service('127.0.0.1:10027','inet');
+			// Adding amavis-services to the master.cf file
 
-		if ($add_amavis || $add_amavis_10025 || $add_amavis_10027) {
-			//* backup master.cf
+			// backup master.cf
 			if(is_file($config_dir.'/master.cf')) copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
-			// adjust amavis-config
-			if($add_amavis) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10025) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-			}
-			if ($add_amavis_10027) {
-				$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
-				af($config_dir.'/master.cf', $content);
-				unset($content);
-    		}
+
+			// first remove the old service definitions
+			$this->remove_postfix_service('amavis','unix');
+			$this->remove_postfix_service('127.0.0.1:10025','inet');
+			$this->remove_postfix_service('127.0.0.1:10027','inet');
+
+			// then add them back
+			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis.master', 'tpl/master_cf_amavis.master');
+			af($config_dir.'/master.cf', $content);
+			unset($content);
+
+			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10025.master', 'tpl/master_cf_amavis10025.master');
+			af($config_dir.'/master.cf', $content);
+			unset($content);
+
+			$content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/master_cf_amavis10027.master', 'tpl/master_cf_amavis10027.master');
+			af($config_dir.'/master.cf', $content);
+			unset($content);
 		}
 
 		// Add the clamav user to the amavis group
@@ -1747,14 +1772,21 @@ class installer_base {
 		global $conf;
 
 		//* These postconf commands will be executed on installation and update
-		$server_ini_rec = $this->db->queryOneRecord("SELECT config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
+		$server_ini_rec = $this->db->queryOneRecord("SELECT mail_server, config FROM ?? WHERE server_id = ?", $conf["mysql"]["database"] . '.server', $conf['server_id']);
 		$server_ini_array = ini_to_array(stripslashes($server_ini_rec['config']));
+		$mail_server = ($server_ini_rec['mail_server']) ? true : false;
 		unset($server_ini_rec);
 
+		$config_dir = $conf['postfix']['config_dir'];
+		$quoted_config_dir = preg_quote($config_dir, '|');
+
 		$mail_config = $server_ini_array['mail'];
-		if($mail_config['content_filter'] === 'rspamd') {
-			exec("postconf -X 'receive_override_options'");
-			exec("postconf -X 'content_filter'");
+		//* only change postfix config if rspamd is active filter
+		if($mail_server && $mail_config['content_filter'] === 'rspamd') {
+			exec("postconf -X receive_override_options");
+			exec("postconf -X content_filter");
+			exec("postconf -X address_verify_virtual_transport");
+			exec("postconf -X address_verify_transport_maps");
 
 			exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
 			exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
@@ -1805,6 +1837,9 @@ class installer_base {
 				if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
 					continue;
 				}
+				if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
+					continue;
+				}
 				$new_options[] = $value;
 			}
 			exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..db4870ad663415a4eb1e7fa85d1fa09417690739 100644
--- a/install/sql/incremental/upd_dev_collection.sql
+++ b/install/sql/incremental/upd_dev_collection.sql
@@ -0,0 +1,19 @@
+-- create mail_relay_domain and load with current domains from mail_transport table
+CREATE TABLE IF NOT EXISTS `mail_relay_domain` (
+	  `relay_domain_id` bigint(20) NOT NULL AUTO_INCREMENT,
+	  `sys_userid` int(11) NOT NULL DEFAULT '0',
+	  `sys_groupid` int(11) NOT NULL DEFAULT '0',
+	  `sys_perm_user` varchar(5) DEFAULT NULL,
+	  `sys_perm_group` varchar(5) DEFAULT NULL,
+	  `sys_perm_other` varchar(5) DEFAULT NULL,
+	  `server_id` int(11) NOT NULL DEFAULT '0',
+	  `domain` varchar(255) DEFAULT NULL,
+	  `access` varchar(255) NOT NULL DEFAULT 'OK',
+	  `active` varchar(255) NOT NULL DEFAULT 'y',
+	  PRIMARY KEY (`relay_domain_id`),
+	  UNIQUE KEY `domain` (`domain`, `server_id`)
+	) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+INSERT INTO `mail_relay_domain` SELECT NULL, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_id`, `domain`, 'OK', `active` FROM `mail_transport` WHERE `domain` NOT LIKE '%@%' AND `domain` LIKE '%.%' GROUP BY `domain`, `server_id`;
+
+ALTER TABLE `dns_soa` ADD `rendered_zone` MEDIUMTEXT NULL AFTER `dnssec_info`;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 4d61c38d8f56712160c8ba9bc8ec9a31813d3ee3..ec6596bc779e4274d5612273e5f9fa96fd9a27cd 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -635,6 +635,7 @@ CREATE TABLE `dns_soa` (
   `dnssec_algo` SET('NSEC3RSASHA1','ECDSAP256SHA256') NOT NULL DEFAULT 'ECDSAP256SHA256',
   `dnssec_last_signed` BIGINT NOT NULL DEFAULT '0',
   `dnssec_info` TEXT NULL,
+  `rendered_zone` MEDIUMTEXT NULL,
   PRIMARY KEY  (`id`),
   UNIQUE KEY `origin` (`origin`),
   KEY `active` (`active`)
@@ -970,6 +971,27 @@ CREATE TABLE `mail_mailinglist` (
 
 -- --------------------------------------------------------
 
+--
+-- Table structure for Table `mail_relay_domain`
+--
+
+CREATE TABLE IF NOT EXISTS `mail_relay_domain` (
+  `relay_domain_id` bigint(20) NOT NULL AUTO_INCREMENT,
+  `sys_userid` int(11) NOT NULL DEFAULT '0',
+  `sys_groupid` int(11) NOT NULL DEFAULT '0',
+  `sys_perm_user` varchar(5) DEFAULT NULL,
+  `sys_perm_group` varchar(5) DEFAULT NULL,
+  `sys_perm_other` varchar(5) DEFAULT NULL,
+  `server_id` int(11) NOT NULL DEFAULT '0',
+  `domain` varchar(255) DEFAULT NULL,
+  `access` varchar(255) NOT NULL DEFAULT 'OK',
+  `active` varchar(255) NOT NULL DEFAULT 'y',
+  PRIMARY KEY (`relay_domain_id`),
+  UNIQUE KEY `domain` (`domain`, `server_id`)
+) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+-- --------------------------------------------------------
+
 --
 -- Table structure for Table `mail_relay_recipient`
 --
diff --git a/install/tpl/master_cf_amavis.master b/install/tpl/master_cf_amavis.master
index 243f28a288dc2e5f27a54f79422a9b5f48571d76..a565f1a1bb50977d8d945e1efcf3b07b641c617d 100644
--- a/install/tpl/master_cf_amavis.master
+++ b/install/tpl/master_cf_amavis.master
@@ -2,5 +2,5 @@
 amavis unix - - - - 2 smtp
         -o smtp_data_done_timeout=1200
         -o smtp_send_xforward_command=yes
-		-o smtp_bind_address=
+        -o smtp_bind_address=
 
diff --git a/install/tpl/master_cf_amavis10025.master b/install/tpl/master_cf_amavis10025.master
index 6dee892264d3d6f5491fecb104a0242f079cda88..68d4561494b0568c7b4bbac4e6d51ad13c1f66f2 100644
--- a/install/tpl/master_cf_amavis10025.master
+++ b/install/tpl/master_cf_amavis10025.master
@@ -14,4 +14,6 @@
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
         -o smtp_send_xforward_command=yes
         -o disable_dns_lookups=yes
+        -o address_verify_virtual_transport=$virtual_transport
+        -o address_verify_transport_maps=$transport_maps
 
diff --git a/install/tpl/master_cf_amavis10027.master b/install/tpl/master_cf_amavis10027.master
index 640902d52e109a76d206cb72123b7cf1ea65e9d0..d3a07a8bce45d1e2c415f1a6085323faa9066261 100644
--- a/install/tpl/master_cf_amavis10027.master
+++ b/install/tpl/master_cf_amavis10027.master
@@ -13,7 +13,9 @@
         -o strict_rfc821_envelopes=yes
         -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
         -o smtp_send_xforward_command=yes
-	    -o milter_default_action=accept
-    	-o milter_macro_daemon_name=ORIGINATING
         -o disable_dns_lookups=yes
+        -o address_verify_virtual_transport=$virtual_transport
+        -o address_verify_transport_maps=$transport_maps
+        -o milter_default_action=accept
+        -o milter_macro_daemon_name=ORIGINATING
 
diff --git a/install/tpl/mysql-virtual_relaydomains.cf.master b/install/tpl/mysql-virtual_relaydomains.cf.master
index 5ce2db6954429b96b9b4437f2cd9831cb002bc21..c27596d1e75d56e522ad5c40a67399af406cec29 100644
--- a/install/tpl/mysql-virtual_relaydomains.cf.master
+++ b/install/tpl/mysql-virtual_relaydomains.cf.master
@@ -2,4 +2,4 @@ user = {mysql_server_ispconfig_user}
 password = {mysql_server_ispconfig_password}
 dbname = {mysql_server_database}
 hosts = {mysql_server_ip}
-query = select domain from mail_transport where domain = '%s' and active = 'y' and server_id = {server_id}
+query = select domain from mail_relay_domain where domain = '%s' and active = 'y' and server_id = {server_id}
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index 36d48d913e420b365a021a43559d0129c1b6a8ea..8799e1f34c7efec3ec6e375659ea31b1ef31f833 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -58,6 +58,7 @@ mailbox_size_limit=0
 message_size_limit=0
 mailbox_quota_stats=y
 realtime_blackhole_list=zen.spamhaus.org
+overquota_notify_threshold=90
 overquota_notify_admin=y
 overquota_notify_client=y
 overquota_notify_freq=7
@@ -118,9 +119,11 @@ connect_userid_to_webid_start=10000
 web_folder_protection=y
 php_ini_check_minutes=1
 overtraffic_disable_web=y
+overquota_notify_threshold=90
 overquota_notify_admin=y
 overquota_notify_client=y
 overquota_notify_freq=7
+overquota_db_notify_threshold=90
 overquota_db_notify_admin=y
 overquota_db_notify_client=y
 overquota_notify_onok=n
diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php
index 286d6f6c57d6e30d72b4b869b15a0648477e7a3b..cad598043593bdddb82befe954ab665e428b2528 100644
--- a/interface/lib/classes/remote.d/mail.inc.php
+++ b/interface/lib/classes/remote.d/mail.inc.php
@@ -60,7 +60,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$primary_id = $this->insertQuery('../mail/form/mail_domain.tform.php', $client_id, $params);
+		$primary_id = $this->insertQuery('../mail/form/mail_domain.tform.php', $client_id, $params, 'mail:mail_domain:on_after_insert');
 		return $primary_id;
 	}
 
@@ -71,7 +71,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->updateQuery('../mail/form/mail_domain.tform.php', $client_id, $primary_id, $params);
+		$affected_rows = $this->updateQuery('../mail/form/mail_domain.tform.php', $client_id, $primary_id, $params, 'mail:mail_domain:on_after_update');
 		return $affected_rows;
 	}
 
@@ -82,7 +82,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->deleteQuery('../mail/form/mail_domain.tform.php', $primary_id);
+		$affected_rows = $this->deleteQuery('../mail/form/mail_domain.tform.php', $primary_id, 'mail:mail_domain:on_after_delete');
 		return $affected_rows;
 	}
 
@@ -222,7 +222,7 @@ class remoting_mail extends remoting {
 		if (!isset($params['gid'])) $params['gid'] = -1;
 		if (!isset($params['maildir_format'])) $params['maildir_format'] = 'maildir';
 
-		$mailuser_id = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params);
+		$mailuser_id = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params, 'mail:mail_user:on_after_insert');
 		return $mailuser_id;
 	}
 
@@ -245,7 +245,7 @@ class remoting_mail extends remoting {
 			return false;
 		}
 
-		$affected_rows = $this->updateQuery('../mail/form/mail_user.tform.php', $client_id, $primary_id, $params);
+		$affected_rows = $this->updateQuery('../mail/form/mail_user.tform.php', $client_id, $primary_id, $params, 'mail:mail_user:on_after_update');
 		return $affected_rows;
 	}
 
@@ -258,7 +258,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->deleteQuery('../mail/form/mail_user.tform.php', $primary_id);
+		$affected_rows = $this->deleteQuery('../mail/form/mail_user.tform.php', $primary_id, 'mail:mail_user:on_after_delete');
 		return $affected_rows;
 	}
 
@@ -413,7 +413,7 @@ class remoting_mail extends remoting {
 		}
 		unset($tmp);
 
-		$affected_rows = $this->insertQuery('../mail/form/mail_alias.tform.php', $client_id, $params);
+		$affected_rows = $this->insertQuery('../mail/form/mail_alias.tform.php', $client_id, $params, 'mail:mail_alias:on_after_insert');
 		return $affected_rows;
 	}
 
@@ -435,7 +435,7 @@ class remoting_mail extends remoting {
 		}
 		unset($tmp);
 
-		$affected_rows = $this->updateQuery('../mail/form/mail_alias.tform.php', $client_id, $primary_id, $params);
+		$affected_rows = $this->updateQuery('../mail/form/mail_alias.tform.php', $client_id, $primary_id, $params, 'mail:mail_alias:on_after_update');
 		return $affected_rows;
 	}
 
@@ -446,7 +446,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->deleteQuery('../mail/form/mail_alias.tform.php', $primary_id);
+		$affected_rows = $this->deleteQuery('../mail/form/mail_alias.tform.php', $primary_id, 'mail:mail_alias:on_after_delete');
 		return $affected_rows;
 	}
 
@@ -472,7 +472,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->insertQuery('../mail/form/mail_forward.tform.php', $client_id, $params);
+		$affected_rows = $this->insertQuery('../mail/form/mail_forward.tform.php', $client_id, $params, 'mail:mail_forward:on_after_insert');
 		return $affected_rows;
 	}
 
@@ -484,7 +484,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->updateQuery('../mail/form/mail_forward.tform.php', $client_id, $primary_id, $params);
+		$affected_rows = $this->updateQuery('../mail/form/mail_forward.tform.php', $client_id, $primary_id, $params, 'mail:mail_forward:on_after_update');
 		return $affected_rows;
 	}
 
@@ -496,7 +496,7 @@ class remoting_mail extends remoting {
 			throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.');
 			return false;
 		}
-		$affected_rows = $this->deleteQuery('../mail/form/mail_forward.tform.php', $primary_id);
+		$affected_rows = $this->deleteQuery('../mail/form/mail_forward.tform.php', $primary_id, 'mail:mail_forward:on_after_delete');
 		return $affected_rows;
 	}
 
@@ -1110,4 +1110,4 @@ class remoting_mail extends remoting {
 
 }
 
-?>
+?>
\ No newline at end of file
diff --git a/interface/lib/classes/validate_mail_relay_domain.inc.php b/interface/lib/classes/validate_mail_relay_domain.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..44e13998a4af1ed529c02e62ffd27dae582ccb75
--- /dev/null
+++ b/interface/lib/classes/validate_mail_relay_domain.inc.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+Copyright (c) 2007, Till Brehm, projektfarm Gmbh
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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 validate_mail_relay_domain {
+
+	function get_error($errmsg) {
+		global $app;
+
+		if(isset($app->tform->wordbook[$errmsg])) {
+			return $app->tform->wordbook[$errmsg]."<br>\r\n";
+		} else {
+			return $errmsg."<br>\r\n";
+		}
+	}
+
+	/* Validator function for checking the 'domain' of a mail relay domain */
+	function validate_domain($field_name, $field_value, $validator) {
+		global $app, $conf;
+
+		if(isset($app->remoting_lib->primary_id)) {
+			$id = $app->remoting_lib->primary_id;
+		} else {
+			$id = $app->tform->primary_id;
+		}
+
+		// mail_relay_domain.domain must be unique per server
+		$sql = "SELECT relay_domain_id, domain FROM mail_relay_domain WHERE domain = ? AND server_id = ? AND relay_domain_id != ?";
+		$domain_check = $app->db->queryOneRecord($sql, $field_value, $app->tform_actions->dataRecord['server_id'], $id);
+
+		if($domain_check) return $this->get_error('domain_error_unique');
+	}
+
+}
diff --git a/interface/lib/config.inc.php b/interface/lib/config.inc.php
index c5d14d79cdbdb02d98e2a1129d91871101170258..c492680513e0553fe00499adf670725a714d6fc7 100644
--- a/interface/lib/config.inc.php
+++ b/interface/lib/config.inc.php
@@ -159,4 +159,7 @@ define('LOGLEVEL_DEBUG', 0);
 define('LOGLEVEL_WARN', 1);
 define('LOGLEVEL_ERROR', 2);
 
+//** Admin IP whitelist file
+$conf['admin_ip_whitelist_file'] = '/usr/local/ispconfig/security/admin_ip.whitelist';
+
 ?>
diff --git a/interface/lib/lang/ar.lng b/interface/lib/lang/ar.lng
index 2763f8e82b62ca71763dcba6434898d7eb1f1fac..c2bc19a6b9f483c11d8fe2e5bcc48ac2af5ef109 100644
--- a/interface/lib/lang/ar.lng
+++ b/interface/lib/lang/ar.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/bg.lng b/interface/lib/lang/bg.lng
index 94dfaa8ad19b9f45499558418abcb46ea7cb49de..e0a0bfcdaba846f50de030d2bc1c07d7849eb154 100644
--- a/interface/lib/lang/bg.lng
+++ b/interface/lib/lang/bg.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Изтрий XMPP потребител';
 $wb['unlimited_txt'] = 'Неограничен';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/br.lng b/interface/lib/lang/br.lng
index e47df8250d24614216a07587ee96874ad4d9426c..7e78ddaf364953e5d0f567aa6bf63384c8ef513b 100644
--- a/interface/lib/lang/br.lng
+++ b/interface/lib/lang/br.lng
@@ -172,3 +172,4 @@ $wb['select_master_directive_snippet_txt'] = 'Diretiva mestre de trechos de cód
 $wb['unlimited_txt'] = 'Ilimitado';
 $wb['server_id_0_error_txt'] = 'Por favor, selecione um servidor válido. O ID do servidor deve ser > 0.';
 $wb['datalog_changes_close_txt'] = 'Fechar';
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/ca.lng b/interface/lib/lang/ca.lng
index c57185fd108c8efb9df79f46b0b1acd786b73844..308aba545bfb2fffbfdb63b2076988f51e91f7fa 100644
--- a/interface/lib/lang/ca.lng
+++ b/interface/lib/lang/ca.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Illimité';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/cz.lng b/interface/lib/lang/cz.lng
index 04ad86178c2f46e50b7f9b0fd1e5015c0b72de02..84ce72a4c0bc98a423932e90904306ee9256fcf4 100644
--- a/interface/lib/lang/cz.lng
+++ b/interface/lib/lang/cz.lng
@@ -172,3 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Smazat XMPP uživatele';
 $wb['unlimited_txt'] = 'Neomezený';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/de.lng b/interface/lib/lang/de.lng
index 11a5e21a5d2ef0f62e26d18627c4b0cab444da93..38e9c2b40c04df1deaea832f89681ea96ed1b5d2 100644
--- a/interface/lib/lang/de.lng
+++ b/interface/lib/lang/de.lng
@@ -172,4 +172,4 @@ $wb['select_master_directive_snippet_txt'] = 'Master Direktiven Schnipsel';
 $wb['unlimited_txt'] = 'unlimitiert';
 $wb['server_id_0_error_txt'] = 'Bitte Server auswählen. Server ID muss > als 0 sein.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/dk.lng b/interface/lib/lang/dk.lng
index 9d09f1dc8dd97691652d4f1353d2fc9ae9490300..de52b0e704f00f5c6b9d1808ff09ad6845203aa7 100644
--- a/interface/lib/lang/dk.lng
+++ b/interface/lib/lang/dk.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Ubegrænset';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/el.lng b/interface/lib/lang/el.lng
index 31829d5f937f3b5effcfc0a26974a8298a82cf70..42d991401d696eeef8a1b9e0ed9720438ac70884 100644
--- a/interface/lib/lang/el.lng
+++ b/interface/lib/lang/el.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Απεριόριστα';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/en.lng b/interface/lib/lang/en.lng
index dbffc95b8c9bdcb6a821b6038fa40c72ee35131b..57c8d1f79f88ac69ced6a397e5bb5dd8fe7d5806 100644
--- a/interface/lib/lang/en.lng
+++ b/interface/lib/lang/en.lng
@@ -173,4 +173,4 @@ $wb['select_master_directive_snippet_txt'] = 'Master Directive Snippets';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/es.lng b/interface/lib/lang/es.lng
index 3a421e7af51352f0c7e1be5b2e8d1bc0b7e6a301..2d120a2b97603a0d962508aa425e9158272c4baf 100644
--- a/interface/lib/lang/es.lng
+++ b/interface/lib/lang/es.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Borrar usuario XMPP';
 $wb['unlimited_txt'] = 'Ilimitado';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Cerrar';
-?>
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/fi.lng b/interface/lib/lang/fi.lng
index f6648e88c6bcc0a07ca3e187f6bf3aea32ce780a..7974914e0e9eab89775f76fdbad6febbbaa166f9 100644
--- a/interface/lib/lang/fi.lng
+++ b/interface/lib/lang/fi.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/fr.lng b/interface/lib/lang/fr.lng
index 15e8294e0c91aa97a15e19774432a0464a8a5d2c..b4bb837e7df140a132009910c64221a5ab227d3c 100644
--- a/interface/lib/lang/fr.lng
+++ b/interface/lib/lang/fr.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Illimité';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/hr.lng b/interface/lib/lang/hr.lng
index fdb09cbff53d220195ae9b313dba6aea71c86aad..bef42f1814ce5d93bc603c69d31b3cb630b7faeb 100644
--- a/interface/lib/lang/hr.lng
+++ b/interface/lib/lang/hr.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'neograničeno';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/hu.lng b/interface/lib/lang/hu.lng
index 8e65d4c97416c77f9964c24afc0d0bbd5e96f3dd..e3913462fe0adc3a0152e4c39425d62bfb634dbf 100644
--- a/interface/lib/lang/hu.lng
+++ b/interface/lib/lang/hu.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Korlátlan';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/id.lng b/interface/lib/lang/id.lng
index 693ca49015657476fd703df309c8a45f8dd2cd4c..aea01a061486780e671c2d12e03f1e95cc18b866 100644
--- a/interface/lib/lang/id.lng
+++ b/interface/lib/lang/id.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Tak terbatas';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/it.lng b/interface/lib/lang/it.lng
index 1333cc907f541947ec262ecedf708e01985281a0..ff08d6f6337a6fdf84ed4b6befc103344e12b1e1 100644
--- a/interface/lib/lang/it.lng
+++ b/interface/lib/lang/it.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Elimina utente XMPP';
 $wb['unlimited_txt'] = 'illimitati';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Chiudi';
-?>
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/ja.lng b/interface/lib/lang/ja.lng
index 2d24f9a1f70ab5bbdbebd7d53927546ffd52153c..7235de393e3c7d4a7878eeb13554b791f048084f 100644
--- a/interface/lib/lang/ja.lng
+++ b/interface/lib/lang/ja.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/nl.lng b/interface/lib/lang/nl.lng
index 3af436ca485348404bc1c3bde176ac4356b9246f..54e7045e612ff200bad7be702f0ddd74141f3e29 100644
--- a/interface/lib/lang/nl.lng
+++ b/interface/lib/lang/nl.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Ongelimiteerd';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Sluiten';
-?>
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/pl.lng b/interface/lib/lang/pl.lng
index 4a1cd0384e1c8b5f2042bfc954630fc97ec43a1b..ccd3347324793d50ead081987c6f3d1c49ee55ba 100644
--- a/interface/lib/lang/pl.lng
+++ b/interface/lib/lang/pl.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'nielimitowane';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/pt.lng b/interface/lib/lang/pt.lng
index 86d4442c42d2f31eb4d6d83359ce2a30db1cc9af..e2dc2f72acba3a877f0463fff46f38b4931641c1 100644
--- a/interface/lib/lang/pt.lng
+++ b/interface/lib/lang/pt.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/ro.lng b/interface/lib/lang/ro.lng
index 4f032832eb92c4b26c261892e3ca6a1268a42e79..6a9f596a0b74fd64d85099ce0f8b3ed941421407 100644
--- a/interface/lib/lang/ro.lng
+++ b/interface/lib/lang/ro.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/ru.lng b/interface/lib/lang/ru.lng
index 2d18c9f628a418d3e3232819798e0ff14d0364ca..dca0c7a53e4cb9fc8cfaf82529d6fb6f9358efe8 100644
--- a/interface/lib/lang/ru.lng
+++ b/interface/lib/lang/ru.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Удалить пользователя XMP
 $wb['unlimited_txt'] = 'Безлимитный';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/se.lng b/interface/lib/lang/se.lng
index 5e8b3c7123a96af9a3e5697bbc3855cea19bc668..2d3c38fd3892654599a4b616b23755062d4d70b0 100644
--- a/interface/lib/lang/se.lng
+++ b/interface/lib/lang/se.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Obegränsat';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/sk.lng b/interface/lib/lang/sk.lng
index cab3ea1f8f9b8017ca6b92747e5eb5ef062e5640..d8e06d1ab3a1c024260ee1fc3fed89f00f35d8e8 100644
--- a/interface/lib/lang/sk.lng
+++ b/interface/lib/lang/sk.lng
@@ -172,4 +172,4 @@ $wb['datalog_status_d_xmpp_user'] = 'Delete XMPP user';
 $wb['unlimited_txt'] = 'Unlimited';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/lib/lang/tr.lng b/interface/lib/lang/tr.lng
index 041c8d71030e856a9e93ba18bb90a145eb4bfbdc..ec5f1bfd930ecd2d3de74f48b3ddcb48f3440511 100644
--- a/interface/lib/lang/tr.lng
+++ b/interface/lib/lang/tr.lng
@@ -173,4 +173,4 @@ $wb['select_master_directive_snippet_txt'] = 'Ana Komut Parçaları';
 $wb['unlimited_txt'] = 'Sınırsız';
 $wb['server_id_0_error_txt'] = 'Please select a valid Server. Server ID must be > 0.';
 $wb['datalog_changes_close_txt'] = 'Close';
-?>
\ No newline at end of file
+$wb['non_admin_error'] = 'Requires administrator level permissions';
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index 47a48a3c279e2bf438a3efeb796debed358b1293..a7947ba147c07e5ee88bb059783aa63cf27eac82 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -740,6 +740,18 @@ $form["tabs"]['mail'] = array(
 			'default' => 'y',
 			'value' => array(0 => 'n', 1 => 'y')
 		),
+		'overquota_notify_threshold' => array(
+			'datatype' => 'INTEGER',
+			'formtype' => 'TEXT',
+			'default' => '90',
+			'validators' => array(
+				0 => array('type' => 'NOTEMPTY', 'errmsg' => 'overquota_notify_threshold_error'),
+				1 => array('type' => 'RANGE',	'range' => '0:100',	'errmsg' => 'overquota_notify_threshold_error'),
+			),
+			'value' => '',
+			'width' => '20',
+			'maxlength' => '3'
+		),
 		'overquota_notify_admin' => array(
 			'datatype' => 'VARCHAR',
 			'formtype' => 'CHECKBOX',
@@ -1082,6 +1094,18 @@ $form["tabs"]['web'] = array(
 			'default' => 'y',
 			'value' => array(0 => 'n', 1 => 'y')
 		),
+		'overquota_notify_threshold' => array(
+			'datatype' => 'INTEGER',
+			'formtype' => 'TEXT',
+			'default' => '90',
+			'validators' => array(
+				0 => array('type' => 'NOTEMPTY', 'errmsg' => 'overquota_notify_threshold_error'),
+				1 => array('type' => 'RANGE',	'range' => '0:100',	'errmsg' => 'overquota_notify_threshold_error'),
+			),
+			'value' => '',
+			'width' => '20',
+			'maxlength' => '3'
+		),
 		'overquota_notify_admin' => array(
 			'datatype' => 'VARCHAR',
 			'formtype' => 'CHECKBOX',
@@ -1094,6 +1118,18 @@ $form["tabs"]['web'] = array(
 			'default' => 'y',
 			'value' => array(0 => 'n', 1 => 'y')
 		),
+		'overquota_db_notify_threshold' => array(
+			'datatype' => 'INTEGER',
+			'formtype' => 'TEXT',
+			'default' => '90',
+			'validators' => array(
+				0 => array('type' => 'NOTEMPTY', 'errmsg' => 'overquota_notify_threshold_error'),
+				1 => array('type' => 'RANGE',	'range' => '0:100',	'errmsg' => 'overquota_notify_threshold_error'),
+			),
+			'value' => '',
+			'width' => '20',
+			'maxlength' => '3'
+		),
 		'overquota_db_notify_admin' => array(
 			'datatype' => 'VARCHAR',
 			'formtype' => 'CHECKBOX',
diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php
index c7d15ffcf4ddfcb6a7a125a732c539e050f1d68d..bce858b5221a274487ec81b03b0d778b6474c8c5 100644
--- a/interface/web/admin/form/system_config.tform.php
+++ b/interface/web/admin/form/system_config.tform.php
@@ -481,6 +481,12 @@ $form["tabs"]['dns'] = array (
 			'value'  => '',
 			'name'  => 'default_slave_dnsserver'
 		),
+		'dns_show_zoneexport' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'CHECKBOX',
+			'default' => 'n',
+			'value'  => array(0 => 'n', 1 => 'y')
+		),
 		//#################################
 		// END Datatable fields
 		//#################################
diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng
index ac03605279d769d3b8c8d2be21bcb84b43b8e687..fe494f4bd7a7405edd331a7e01b492422b48dc50 100644
--- a/interface/web/admin/lib/lang/ar_server_config.lng
+++ b/interface/web/admin/lib/lang/ar_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/ar_system_config.lng b/interface/web/admin/lib/lang/ar_system_config.lng
index 5d21ab4c2e93e8bf0fd713516481429a36d9d97c..a10274c670519674f336c0406f855cec6df4eb87 100644
--- a/interface/web/admin/lib/lang/ar_system_config.lng
+++ b/interface/web/admin/lib/lang/ar_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng
index b9d6e648cedeb6b0666b8112acb93b5a0b9fe838..837d254dac6ed24d0c6e51fcc510d714ebd7ac2e 100644
--- a/interface/web/admin/lib/lang/bg_server_config.lng
+++ b/interface/web/admin/lib/lang/bg_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/bg_system_config.lng b/interface/web/admin/lib/lang/bg_system_config.lng
index 1b8d10541d05febec539338ac21a0fc9eda0e6ae..898020365f07503859375268e1d0d7940c72e513 100644
--- a/interface/web/admin/lib/lang/bg_system_config.lng
+++ b/interface/web/admin/lib/lang/bg_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng
index ac551c588cd5917247c1bce3b1eb3a4991d0affc..7c08431fdb01595b9a5bb65fbaf00eac00c25a40 100644
--- a/interface/web/admin/lib/lang/br_server_config.lng
+++ b/interface/web/admin/lib/lang/br_server_config.lng
@@ -200,6 +200,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Enviar notificação de tráfego excedido
 $wb['overtraffic_notify_client_txt'] = 'Enviar notificação de tráfego excedido para o cliente';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Por favor, insira nomes de host válidos para RBLs.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Enviar alerta da cota para o administrador';
 $wb['overquota_notify_client_txt'] = 'Enviar alerta da cota para o cliente';
 $wb['overquota_notify_onok_txt'] = 'Enviar mensagem da cota para o cliente';
@@ -223,6 +225,7 @@ $wb['v6_prefix_length'] = 'O prefixo é muito longo de acordo com as definiçõe
 $wb['backup_dir_is_mount_txt'] = 'O diretório de backup está montando?';
 $wb['backup_dir_mount_cmd_txt'] = 'Comando mount, se o diretório não está montado';
 $wb['backup_delete_txt'] = 'Remover backups de domínios/site';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Enviar alerta da cota do Banco de Dados para o administrador';
 $wb['overquota_db_notify_client_txt'] = 'Enviar alerta da cota do Banco de Dados para o cliente';
 $wb['monitor_system_updates_txt'] = 'Verificar por atualizações do sistema';
diff --git a/interface/web/admin/lib/lang/br_system_config.lng b/interface/web/admin/lib/lang/br_system_config.lng
index 6cf3bf58bbb6ef0be3f8a84f780270eef09b8957..1fb510ace046206ee404107ca32e9eef74068469 100644
--- a/interface/web/admin/lib/lang/br_system_config.lng
+++ b/interface/web/admin/lib/lang/br_system_config.lng
@@ -106,3 +106,4 @@ $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
 $wb['monitor_key_txt'] = 'Senha do Monitor';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng
index 25ed761836cafb2f1216212c3582bfe3c6abcd29..2ced57478adecf979ddbda18878f8b81d51df338 100644
--- a/interface/web/admin/lib/lang/ca_server_config.lng
+++ b/interface/web/admin/lib/lang/ca_server_config.lng
@@ -196,6 +196,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -219,6 +221,7 @@ $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_is_mount_txt'] = 'Backup directory is a mount?';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['monitor_system_updates_txt'] = 'Check for Linux updates';
diff --git a/interface/web/admin/lib/lang/ca_system_config.lng b/interface/web/admin/lib/lang/ca_system_config.lng
index 9f9f3622884342a93ed6088ee9c4956ec9eaa782..68ca245f3dd26e85b9d45701d86f5de19d3de13e 100644
--- a/interface/web/admin/lib/lang/ca_system_config.lng
+++ b/interface/web/admin/lib/lang/ca_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng
index 6da8dfc0bb4989c6a7e179417fdc1afe7693f1f7..590a8d9796ecf1e651bc541df9b4f26f434ee022 100644
--- a/interface/web/admin/lib/lang/cz_server_config.lng
+++ b/interface/web/admin/lib/lang/cz_server_config.lng
@@ -179,6 +179,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Při překročení limitu přenesených d
 $wb['overtraffic_notify_client_txt'] = 'Při překročení limitu přenesených dat, poslat oznámení klientovi';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Poslat varování o překročení nebo vyčerpání kvót adminovi';
 $wb['overquota_notify_client_txt'] = 'Poslat varování o překročení nebo vyčerpání kvót klientovi';
 $wb['overquota_notify_onok_txt'] = 'Poslat zprávu klientovi, že kvóta je již v pořádku';
@@ -269,6 +271,7 @@ $wb['vhost_rewrite_v6_txt'] = 'Rewrite IPv6 on Mirror';
 $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Odstranit zálohy pokud byla smazána doména/webové stránky';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Poslat varování o překročení nebo vyčerpání DB kvót adminovi';
 $wb['overquota_db_notify_client_txt'] = 'Poslat varování o překročení nebo vyčerpání DB kvót klientovi';
 $wb['php_handler_txt'] = 'Výchozí PHP obslužná rutina';
diff --git a/interface/web/admin/lib/lang/cz_system_config.lng b/interface/web/admin/lib/lang/cz_system_config.lng
index 23dbc9c41efa0b41775599e1a73a7d1a8e939957..c6f45e7d46319e764172fd4081017c5b71b9892e 100644
--- a/interface/web/admin/lib/lang/cz_system_config.lng
+++ b/interface/web/admin/lib/lang/cz_system_config.lng
@@ -106,3 +106,4 @@ $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
 $wb['monitor_key_txt'] = 'Monitor keyword';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng
index d0b43059c47cf52c0dea5cc5f5363007d7c5edb2..557d313704a558575ff125d1274cec0cd8438aa1 100644
--- a/interface/web/admin/lib/lang/de_server_config.lng
+++ b/interface/web/admin/lib/lang/de_server_config.lng
@@ -199,6 +199,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Ãœberschreiten des Datentransfer Limits a
 $wb['overtraffic_notify_client_txt'] = 'Ãœberschreiten des Datentransfer Limits an den Kunden senden';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Bitte geben Sie gültige RBL-Hostnamen an.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Quota-Warnungen an den Administrator senden';
 $wb['overquota_notify_client_txt'] = 'Quota-Warnungen an den Kunden senden';
 $wb['overquota_notify_onok_txt'] = 'Meldung an den Kunden senden, wenn Belegung wieder ok';
@@ -276,6 +278,7 @@ $wb['cron_init_script_error_regex'] = 'Invalid cron init script.';
 $wb['crontab_dir_error_regex'] = 'Invalid crontab directory.';
 $wb['cron_wget_error_regex'] = 'Invalid cron wget path.';
 $wb['network_filesystem_txt'] = 'Netzwerk-Dateisystem';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Datenbank-Quota-Warnungen an den Administrator senden';
 $wb['overquota_db_notify_client_txt'] = 'Datenbank-Quota-Warnungen an den Kunden senden';
 $wb['php_ini_check_minutes_txt'] = 'Prüfe php.ini alle X Minuten auf Änderungen';
diff --git a/interface/web/admin/lib/lang/de_system_config.lng b/interface/web/admin/lib/lang/de_system_config.lng
index 7d372a820e9a56e1ce54ca429c6c2ea28d24ca86..328124f6e72e33c0a0cadb6ab3d0a3b9546ef885 100644
--- a/interface/web/admin/lib/lang/de_system_config.lng
+++ b/interface/web/admin/lib/lang/de_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng
index b1ebcec391b4c26a45b1ee7edc204c1b85242560..ccf12bc3e2e0bd75d6aabd9452c8bec10cf240b3 100644
--- a/interface/web/admin/lib/lang/dk_server_config.lng
+++ b/interface/web/admin/lib/lang/dk_server_config.lng
@@ -182,6 +182,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send over-trafik meddelelse til admin';
 $wb['overtraffic_notify_client_txt'] = 'Send over-trafik meddelelse til kunde';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Angiv gyldige RBL værtsnavne.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send kvote advarsler til admin';
 $wb['overquota_notify_client_txt'] = 'Send kvote advarsler til kunde';
 $wb['overquota_notify_onok_txt'] = 'Send kvote ok meddelelse til kunde';
@@ -272,6 +274,7 @@ $wb['vhost_rewrite_v6_txt'] = 'Rewrite IPv6 on Mirror';
 $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/dk_system_config.lng b/interface/web/admin/lib/lang/dk_system_config.lng
index 18160789a9d8bb83152ba44547c8ae35fe521326..71533e77d0469e26624c1fd33b9c09e1028163dd 100644
--- a/interface/web/admin/lib/lang/dk_system_config.lng
+++ b/interface/web/admin/lib/lang/dk_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng
index b147f15e5c98954b23c73b43148a5a74362f366a..468560c7513e1aa4d72c735d40076caa3d619f81 100644
--- a/interface/web/admin/lib/lang/el_server_config.lng
+++ b/interface/web/admin/lib/lang/el_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['vhost_rewrite_v6_txt'] = 'Rewrite IPv6 on Mirror';
 $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/el_system_config.lng b/interface/web/admin/lib/lang/el_system_config.lng
index 7e2df97a492f642c466fc3a0095564329f75f4e3..f64df47bc949ca1bb6ca3e571994878e3f79dd51 100644
--- a/interface/web/admin/lib/lang/el_system_config.lng
+++ b/interface/web/admin/lib/lang/el_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng
index 4125b2648ea4f13786b613c2ab55ac5fd11d1db1..0d09d4222a320288ed9a31fc2fd4d65eff564de5 100644
--- a/interface/web/admin/lib/lang/en_server_config.lng
+++ b/interface/web/admin/lib/lang/en_server_config.lng
@@ -206,6 +206,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -229,6 +231,7 @@ $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_is_mount_txt'] = 'Backup directory is a mount?';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['monitor_system_updates_txt'] = 'Check for Linux updates';
diff --git a/interface/web/admin/lib/lang/en_system_config.lng b/interface/web/admin/lib/lang/en_system_config.lng
index 7db4270c128013516c6135c817198d9c30257c06..2f32d4feaaf743d705907aeaa3b3cf8b15027820 100644
--- a/interface/web/admin/lib/lang/en_system_config.lng
+++ b/interface/web/admin/lib/lang/en_system_config.lng
@@ -106,4 +106,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng
index 67e77efac87b1dd937896a43e163e5e790bd3232..7b1364b2ac2de60810da8b6b62baef1892d567bd 100644
--- a/interface/web/admin/lib/lang/es_server_config.lng
+++ b/interface/web/admin/lib/lang/es_server_config.lng
@@ -187,8 +187,11 @@ $wb['nginx_vhost_conf_enabled_dir_error_empty'] = 'El directorio de configuraci
 $wb['nginx_vhost_conf_enabled_dir_error_regex'] = 'El directorio de configuración para Vhost habilitados de Nginx es inválido.';
 $wb['nginx_vhost_conf_enabled_dir_txt'] = 'Directorio de configuración de host virtual de Nginx habilitado';
 $wb['no_notifications_txt'] = 'Sin notificaciones';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Enviar advertencias de cuota de base de datos al administrador';
 $wb['overquota_db_notify_client_txt'] = 'Enviar advertencias de cuota de base de datos a los clientes';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Enviar advertencias de cuota excedida al administrador';
 $wb['overquota_notify_client_txt'] = 'Enviar advertencias de cuota excedida al cliente';
 $wb['overquota_notify_freq_note_txt'] = '0 = enviar mensaje solo una vez, sin volver a notificar';
diff --git a/interface/web/admin/lib/lang/es_system_config.lng b/interface/web/admin/lib/lang/es_system_config.lng
index 92633c160114e1721e48245bcc078cc6bf7bc6c6..471975be4330c60dee4291ae405b35df501e82ac 100644
--- a/interface/web/admin/lib/lang/es_system_config.lng
+++ b/interface/web/admin/lib/lang/es_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng
index dac02a14b7ee502d9c91a121d7a238ffc96c6c66..8dc41ff17dc16bc1a16b0dc32746d7ca5ce24e7c 100644
--- a/interface/web/admin/lib/lang/fi_server_config.lng
+++ b/interface/web/admin/lib/lang/fi_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/fi_system_config.lng b/interface/web/admin/lib/lang/fi_system_config.lng
index 1a124440574379e02b7ac3a80ed90905f40ed01c..30dd462a2955f13f0dae5234697d1dd71e8950dc 100644
--- a/interface/web/admin/lib/lang/fi_system_config.lng
+++ b/interface/web/admin/lib/lang/fi_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng
index 0599b8bbed10b9bd886338f09bb65205f2b4887d..9aecf3ba2158b9d575631dcf4b85d6f2d8456e90 100644
--- a/interface/web/admin/lib/lang/fr_server_config.lng
+++ b/interface/web/admin/lib/lang/fr_server_config.lng
@@ -181,6 +181,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -271,6 +273,7 @@ $wb['vhost_rewrite_v6_txt'] = 'Rewrite IPv6 on Mirror';
 $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/fr_system_config.lng b/interface/web/admin/lib/lang/fr_system_config.lng
index a79bf9dafd7ce3b7ed37118e23cffcdd7f9dc2bf..ac606922a05896fd791d5aa7b85abbde0bfe34ca 100644
--- a/interface/web/admin/lib/lang/fr_system_config.lng
+++ b/interface/web/admin/lib/lang/fr_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng
index e0894ceb82916b2a2b95c0889bfca6baaed23ade..5d81f21d24f6c403b16733734af956092eca80d4 100644
--- a/interface/web/admin/lib/lang/hr_server_config.lng
+++ b/interface/web/admin/lib/lang/hr_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['network_filesystem_txt'] = 'Network Filesystem';
 $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/hr_system_config.lng b/interface/web/admin/lib/lang/hr_system_config.lng
index 7a3426eff580f77e0e1cf684913b60f5b084e61f..0f29ae0c0c5ad6c90d8c8fb7355ad51f7ecfe4e2 100644
--- a/interface/web/admin/lib/lang/hr_system_config.lng
+++ b/interface/web/admin/lib/lang/hr_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng
index 97774f9ecd77c17812d7c3e4612a935b967ca053..e1c69b610c8b4065a9b7c48810f0ce9d8391150b 100644
--- a/interface/web/admin/lib/lang/hu_server_config.lng
+++ b/interface/web/admin/lib/lang/hu_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/hu_system_config.lng b/interface/web/admin/lib/lang/hu_system_config.lng
index 5fb8f7cd6e54e364cbd43b31e3f369e9bbfe8f75..1258e6acfe878a90df09079f58d7f995ea93ab6c 100644
--- a/interface/web/admin/lib/lang/hu_system_config.lng
+++ b/interface/web/admin/lib/lang/hu_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng
index 814e963f649938d4cf6a88cb871844a7d0186b98..e871616ffefbfa59bbe5c22b45f871122b889c42 100644
--- a/interface/web/admin/lib/lang/id_server_config.lng
+++ b/interface/web/admin/lib/lang/id_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/id_system_config.lng b/interface/web/admin/lib/lang/id_system_config.lng
index b1df781b7646c5b729a4eb6d19d1b64076e3552b..60eff076d378caabe62bd41685391a509a484e51 100644
--- a/interface/web/admin/lib/lang/id_system_config.lng
+++ b/interface/web/admin/lib/lang/id_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng
index f9e30f39374728b73ef67c587d8c84c625117e68..c485bd00a1505d1becba183cfa0ca8a8f47071d7 100644
--- a/interface/web/admin/lib/lang/it_server_config.lng
+++ b/interface/web/admin/lib/lang/it_server_config.lng
@@ -181,6 +181,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Trasmetti notifiche superamento traffico
 $wb['overtraffic_notify_client_txt'] = 'Trasmetti notifiche superamento traffico al cliente';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Per cortesia specificare nomi host RBL validi.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Trasmetti allarmi quota ad admin';
 $wb['overquota_notify_client_txt'] = 'Trasmetti allarmi quota al cliente';
 $wb['overquota_notify_onok_txt'] = 'Trasmetti messaggio quota ok al cliente';
@@ -271,6 +273,7 @@ $wb['vhost_rewrite_v6_txt'] = 'Rewrite IPv6 on Mirror';
 $wb['v6_prefix_length'] = 'Prefix too long according to defined IPv6 ';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
 $wb['backup_delete_txt'] = 'Delete backups on domain/website delete';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/it_system_config.lng b/interface/web/admin/lib/lang/it_system_config.lng
index ddfc072ff2653d987596d44d76ba9949ec0621a6..f77dc6806160ab19c9a12ab2a04ac1c62530b9ac 100644
--- a/interface/web/admin/lib/lang/it_system_config.lng
+++ b/interface/web/admin/lib/lang/it_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng
index 52ac44a351d9a35a9d25376c288d5225892ae266..2547989627517075656227a02e3fd031ec7beb1a 100644
--- a/interface/web/admin/lib/lang/ja_server_config.lng
+++ b/interface/web/admin/lib/lang/ja_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/ja_system_config.lng b/interface/web/admin/lib/lang/ja_system_config.lng
index 8ff20d13cade7b51fdf9d77603fe15f7e4a9c635..b5601ea8009d3c3032dfb493b0de4c9b95466f1b 100644
--- a/interface/web/admin/lib/lang/ja_system_config.lng
+++ b/interface/web/admin/lib/lang/ja_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng
index e9e412b609e1fd6acb6c4374268a3346e1898cd4..ac24a8b5f945033b2f27a436277d652541a032be 100644
--- a/interface/web/admin/lib/lang/nl_server_config.lng
+++ b/interface/web/admin/lib/lang/nl_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/nl_system_config.lng b/interface/web/admin/lib/lang/nl_system_config.lng
index 0caa9228e08fda0e5dbb84ce29a66704ba2a9e1d..107c42395ecf2420d7f2f3f0a00a9e30cc96b033 100644
--- a/interface/web/admin/lib/lang/nl_system_config.lng
+++ b/interface/web/admin/lib/lang/nl_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng
index f9d43d3bfd8e09a3f0e86c1dda8d219f6bbceb51..d5e0dbe0f6a24689ac27b0e750aa6d6d94703e59 100644
--- a/interface/web/admin/lib/lang/pl_server_config.lng
+++ b/interface/web/admin/lib/lang/pl_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Prześlij informacje o przekroczeniu tran
 $wb['overtraffic_notify_client_txt'] = 'Prześlij informacje o przekroczeniu transferu do klienta';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/pl_system_config.lng b/interface/web/admin/lib/lang/pl_system_config.lng
index 92b167c60d8c60ba4f19082d4c49a21da2b3a085..1bb20987655cb6a7e836797904aa0258b4285c35 100644
--- a/interface/web/admin/lib/lang/pl_system_config.lng
+++ b/interface/web/admin/lib/lang/pl_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng
index 468413a1deab53236c67c84e6e51018e5709fd03..85011d112f19bbca663b77c89dabdb1d6b6e93fd 100644
--- a/interface/web/admin/lib/lang/pt_server_config.lng
+++ b/interface/web/admin/lib/lang/pt_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/pt_system_config.lng b/interface/web/admin/lib/lang/pt_system_config.lng
index 491aa6272c75a24b0710fb9e04ead319a9288c25..41becdf5cbb95f563a2816bb7e5c4aa7d7c222c2 100644
--- a/interface/web/admin/lib/lang/pt_system_config.lng
+++ b/interface/web/admin/lib/lang/pt_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng
index e20fb9ee9f5ecc75ea9ad8da2a475878bc0c9f1d..95bf27a4f19551432d873bd201828b38cbfc7d60 100644
--- a/interface/web/admin/lib/lang/ro_server_config.lng
+++ b/interface/web/admin/lib/lang/ro_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/ro_system_config.lng b/interface/web/admin/lib/lang/ro_system_config.lng
index fc268d22410452399e5fc8e62a5e36243deaf951..2fc1a00b5699762a99e3a2d165c45644fd62042e 100644
--- a/interface/web/admin/lib/lang/ro_system_config.lng
+++ b/interface/web/admin/lib/lang/ro_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng
index 1799b075f49fd9155b07b7cc667f8fd9cc161f9e..6ebd4ebe0ea06e68ba45a9c9dd83d1bdca776711 100644
--- a/interface/web/admin/lib/lang/ru_server_config.lng
+++ b/interface/web/admin/lib/lang/ru_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Присылать уведомление
 $wb['overtraffic_notify_client_txt'] = 'Присылать уведомление трафика клиенту';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Пожалуйста, укажите действительные имена хостов RBL.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Присылать предупреждения квоты администратору';
 $wb['overquota_notify_client_txt'] = 'Присылать предупреждения квоты клиенту';
 $wb['overquota_notify_onok_txt'] = 'Присылать сообщение квоты ОК клиенту';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Отключить сообщения bind9 дл
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost включен';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Отключить мониторинг MongoDB';
 $wb['backup_dir_mount_cmd_txt'] = 'Выполните команду монтирования, если каталог резервного копирования не установлен';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Присылать предупреждения квоты DB администратору';
 $wb['overquota_db_notify_client_txt'] = 'Присылать предупреждения квоты DB клиенту';
 $wb['php_handler_txt'] = 'Обработчик PHP по умолчанию';
diff --git a/interface/web/admin/lib/lang/ru_system_config.lng b/interface/web/admin/lib/lang/ru_system_config.lng
index ae12c4b4c1682d4b63b38159635896325dafce5d..d829d1ca97d642054958057b433a1b45132a0ac7 100644
--- a/interface/web/admin/lib/lang/ru_system_config.lng
+++ b/interface/web/admin/lib/lang/ru_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng
index fe3c2e923401b8d1a9ce1e76ef870513e5c3f30d..99b1f714fa83743933d183b0f6cc1fc074b1c97c 100644
--- a/interface/web/admin/lib/lang/se_server_config.lng
+++ b/interface/web/admin/lib/lang/se_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/se_system_config.lng b/interface/web/admin/lib/lang/se_system_config.lng
index fa302c344aa1531d3e2fc0e7863ec5823088b601..fa67bc2bc9265801ba2deb04cafd3bac98cb6137 100644
--- a/interface/web/admin/lib/lang/se_system_config.lng
+++ b/interface/web/admin/lib/lang/se_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng
index bc7f9f514bdb25db6f112c4bef47c44a7817530d..7fa947a4b01aac5f1c5c69a008ddf39048f6a223 100644
--- a/interface/web/admin/lib/lang/sk_server_config.lng
+++ b/interface/web/admin/lib/lang/sk_server_config.lng
@@ -193,6 +193,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Send overtraffic notification to admin';
 $wb['overtraffic_notify_client_txt'] = 'Send overtraffic notification to client';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Please specify valid RBL hostnames.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Send quota warnings to admin';
 $wb['overquota_notify_client_txt'] = 'Send quota warnings to client';
 $wb['overquota_notify_onok_txt'] = 'Send quota ok message to client';
@@ -273,6 +275,7 @@ $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN';
 $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled';
 $wb['do_not_try_rescue_mongodb_txt'] = 'Disable MongoDB monitoring';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount command, if backup directory not mounted';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Send DB quota warnings to admin';
 $wb['overquota_db_notify_client_txt'] = 'Send DB quota warnings to client';
 $wb['php_handler_txt'] = 'Default PHP Handler';
diff --git a/interface/web/admin/lib/lang/sk_system_config.lng b/interface/web/admin/lib/lang/sk_system_config.lng
index 6735e91c53f82691edd308d6d07b8723f1f0296c..317b435eae569d8a3ba79e707d3ba33276d80b4f 100644
--- a/interface/web/admin/lib/lang/sk_system_config.lng
+++ b/interface/web/admin/lib/lang/sk_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng
index 0d0c84f2c73f873cb7dffb245c8deeb9e1ce2b22..565b7b1f48ef480f562ea612362243bec3aaf64f 100644
--- a/interface/web/admin/lib/lang/tr_server_config.lng
+++ b/interface/web/admin/lib/lang/tr_server_config.lng
@@ -200,6 +200,8 @@ $wb['overtraffic_notify_admin_txt'] = 'Trafik Aşımı Bildirimi Yöneticiye Gö
 $wb['overtraffic_notify_client_txt'] = 'Trafik Aşımı Bildirimi Müşteriye Gönderilsin';
 $wb['overtraffic_disable_web_txt'] = 'Disable websites that exceed traffic limit';
 $wb['rbl_error_regex'] = 'Lütfen geçerli RBL sunucu adları yazın.';
+$wb['overquota_notify_threshold_txt'] = 'Quota warning usage level';
+$wb['overquota_notify_threshold_error'] = 'Quota warning usage level must be between 0-100%';
 $wb['overquota_notify_admin_txt'] = 'Kota Uyarıları Yöneticiye Gönderilsin';
 $wb['overquota_notify_client_txt'] = 'Kota Uyarıları Müşteriye Gönderilsin';
 $wb['overquota_notify_onok_txt'] = 'Kota Tamam İletisi Müşteriye Gönderilsin';
@@ -223,6 +225,7 @@ $wb['v6_prefix_length'] = 'Ön ek tanımlanmış IPv6 adresine göre çok uzun '
 $wb['backup_dir_is_mount_txt'] = 'Yedek Klasörü Takılı mı?';
 $wb['backup_dir_mount_cmd_txt'] = 'Mount komutu, yedek klasörü takılı değil ise';
 $wb['backup_delete_txt'] = 'Etki alanı ya da web sitesi silindiğinde yedekler de silinsin';
+$wb['overquota_db_notify_threshold_txt'] = 'DB quota warning usage level';
 $wb['overquota_db_notify_admin_txt'] = 'Veritabanı Kotası Bildirimleri Yöneticiye Gönderilsin';
 $wb['overquota_db_notify_client_txt'] = 'Veritabanı Kotası Bildirimleri Müşteriye Gönderilsin';
 $wb['monitor_system_updates_txt'] = 'Linux Güncellemeleri Denetlensin';
diff --git a/interface/web/admin/lib/lang/tr_system_config.lng b/interface/web/admin/lib/lang/tr_system_config.lng
index b767101e22a67448d6d91d193b70c69f02da1450..a6e6299375f1820031bb7181429ab0d52358b992 100644
--- a/interface/web/admin/lib/lang/tr_system_config.lng
+++ b/interface/web/admin/lib/lang/tr_system_config.lng
@@ -105,4 +105,5 @@ $wb['show_support_messages_txt'] = 'Show message function in help module';
 $wb['show_aps_menu_txt'] = 'Show APS menu';
 $wb['show_aps_menu_note_txt'] = 'APS will be removed from the panel in the near future.';
 $wb['show_aps_menu_note_url_txt'] = 'Click here for more information.';
+$wb['dns_show_zoneexport_txt'] = 'Show zone export.';
 ?>
diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm
index 0eac9889610954e97e4a5575eb7dc4a543e5e0f6..d23a23a59cd998984660055106df4d92327bdb56 100644
--- a/interface/web/admin/templates/server_config_mail_edit.htm
+++ b/interface/web/admin/templates/server_config_mail_edit.htm
@@ -146,6 +146,11 @@
                     {tmpl_var name='mailbox_quota_stats'}
                 </div>
             </div>
+            <div class="form-group">
+                <label for="overquota_notify_threshold" class="col-sm-3 control-label">{tmpl_var name='overquota_notify_threshold_txt'}</label>
+                <div class="col-sm-6"><input type="text" name="overquota_notify_threshold" id="overquota_notify_threshold" value="{tmpl_var name='overquota_notify_threshold'}" class="form-control" /></div>
+                <div class="col-sm-3 input-sm">%</div>
+            </div>
             <div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='overquota_notify_admin_txt'}</label>
                 <div class="col-sm-9">
diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm
index ca1d54344cbf9e50baaf6dd21c37afbbcd69928f..5cf5c43a75826bce63f1c089366bf87bb3383fec 100644
--- a/interface/web/admin/templates/server_config_web_edit.htm
+++ b/interface/web/admin/templates/server_config_web_edit.htm
@@ -144,6 +144,11 @@
                 <div class="col-sm-9">
                     {tmpl_var name='overtraffic_disable_web'}
                 </div>
+            </div>
+            <div class="form-group">
+                <label for="overquota_notify_threshold" class="col-sm-3 control-label">{tmpl_var name='overquota_notify_threshold_txt'}</label>
+                <div class="col-sm-6"><input type="text" name="overquota_notify_threshold" id="overquota_notify_threshold" value="{tmpl_var name='overquota_notify_threshold'}" class="form-control" /></div>
+                <div class="col-sm-3 input-sm">%</div>
             </div>
 			<div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='overquota_notify_admin_txt'}</label>
@@ -156,6 +161,11 @@
                 <div class="col-sm-9">
                     {tmpl_var name='overquota_notify_client'}
                 </div>
+            </div>
+            <div class="form-group">
+                <label for="overquota_db_notify_threshold" class="col-sm-3 control-label">{tmpl_var name='overquota_db_notify_threshold_txt'}</label>
+                <div class="col-sm-6"><input type="text" name="overquota_db_notify_threshold" id="overquota_db_notify_threshold" value="{tmpl_var name='overquota_db_notify_threshold'}" class="form-control" /></div>
+                <div class="col-sm-3 input-sm">%</div>
             </div>
 			<div class="form-group">
 				<label class="col-sm-3 control-label">{tmpl_var name='overquota_db_notify_admin_txt'}</label>
diff --git a/interface/web/admin/templates/system_config_dns_edit.htm b/interface/web/admin/templates/system_config_dns_edit.htm
index f3d0b20dda12fb2d620bdac076b83babde8a22cf..9636b4a26114d517adcf7c50a127401961b54fa8 100644
--- a/interface/web/admin/templates/system_config_dns_edit.htm
+++ b/interface/web/admin/templates/system_config_dns_edit.htm
@@ -11,10 +11,18 @@
 		{tmpl_var name='default_dnsserver'}
 	</select></div>
 </div>
+
+<div class="form-group">
+  <label class="col-sm-3 control-label">{tmpl_var name=dns_show_zoneexport_txt'}</label>
+  <div class="col-sm-9">
+    {tmpl_var name='dns_show_zoneexport'}
+  </div>
+</div>
+
             
 <input type="hidden" name="id" value="{tmpl_var name='id'}">
             
 <div class="clear"><div class="right">
     <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="admin/system_config_edit.php">{tmpl_var name='btn_save_txt'}</button>
     <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="admin/users_list.php">{tmpl_var name='btn_cancel_txt'}</button>
-</div></div>
\ No newline at end of file
+</div></div>
diff --git a/interface/web/capp.php b/interface/web/capp.php
index 5d49fe80d7b8d33807c50214daf0719bffe70026..71d3d9ba35c79e0da5b2a84097276f9a644476d0 100644
--- a/interface/web/capp.php
+++ b/interface/web/capp.php
@@ -31,45 +31,37 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 require_once '../lib/config.inc.php';
 require_once '../lib/app.inc.php';
 
+include_once 'common.php';
+
 //* Import module variable
 $mod = $_REQUEST["mod"];
 //* If we click on a search result, load that one instead of the module's start page
 $redirect = (isset($_REQUEST["redirect"]) ? $_REQUEST["redirect"] : '');
 
 //* Check if user is logged in
-if($_SESSION["s"]["user"]['active'] != 1) {
+if ($_SESSION["s"]["user"]['active'] != 1) {
 	die("URL_REDIRECT: /index.php");
 	//die();
 }
 
-if(!preg_match("/^[a-z]{2,20}$/i", $mod)) die('module name contains unallowed chars.');
-if($redirect != '' && !preg_match("/^[a-z0-9]+\/[a-z0-9_\.\-]+\?id=[0-9]{1,9}(\&type=[a-z0-9_\.\-]+)?$/i", $redirect)) die('redirect contains unallowed chars.');
+if (!preg_match("/^[a-z]{2,20}$/i", $mod)) die('module name contains unallowed chars.');
+if ($redirect != '' && !preg_match("/^[a-z0-9]+\/[a-z0-9_\.\-]+\?id=[0-9]{1,9}(\&type=[a-z0-9_\.\-]+)?$/i", $redirect)) die('redirect contains unallowed chars.');
 
 //* Check if user may use the module.
 $user_modules = explode(",", $_SESSION["s"]["user"]["modules"]);
 
-if(!in_array($mod, $user_modules)) $app->error($app->lng(301));
+if (!in_array($mod, $user_modules)) $app->error($app->lng(301));
 
 //* Load module configuration into the session.
-if(is_file($mod."/lib/module.conf.php")) {
+if (is_file($mod."/lib/module.conf.php")) {
 	include_once $mod."/lib/module.conf.php";
 
-	$menu_dir = ISPC_WEB_PATH.'/' . $mod . '/lib/menu.d';
-
-	if (is_dir($menu_dir)) {
-		if ($dh = opendir($menu_dir)) {
-			//** Go through all files in the menu dir
-			while (($file = readdir($dh)) !== false) {
-				if ($file != '.' && $file != '..' && substr($file, -9, 9) == '.menu.php' && $file != 'dns_resync.menu.php') {
-					include_once $menu_dir . '/' . $file;
-				}
-			}
-		}
-	}
+	$menu_dir = ISPC_WEB_PATH.'/'.$mod.'/lib/menu.d';
+	include_menu_dir_files($menu_dir);
 
 	$_SESSION["s"]["module"] = $module;
 	session_write_close();
-	if($redirect == ''){
+	if ($redirect == '') {
 		echo "HEADER_REDIRECT:".$_SESSION["s"]["module"]["startpage"];
 	} else {
 		//* If we click on a search result, load that one instead of the module's start page
diff --git a/interface/web/common.php b/interface/web/common.php
new file mode 100644
index 0000000000000000000000000000000000000000..2713ed4ed6e68732340961da34667deb04cc10f3
--- /dev/null
+++ b/interface/web/common.php
@@ -0,0 +1,53 @@
+<?php
+
+/*
+Copyright (c) 2007, 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.
+*/
+
+/*
+  Some common helper functions which can be reused throughout the project.
+*/
+
+/**
+ * Includes all the menu files from the menu dir.
+ * @param string $menu_dir Path to the menu dir
+ * @return void
+ */
+function include_menu_dir_files($menu_dir)
+{
+	if (is_dir($menu_dir)) {
+		if ($dh = opendir($menu_dir)) {
+			//** Go through all files in the menu dir
+			while (($file = readdir($dh)) !== false) {
+				if ($file != '.' && $file != '..' && substr($file, -9, 9) == '.menu.php' && $file != 'dns_resync.menu.php') {
+					include_once $menu_dir.'/'.$file;
+				}
+			}
+		}
+	}
+}
+
diff --git a/interface/web/dns/form/dns_soa.tform.php b/interface/web/dns/form/dns_soa.tform.php
index b9e402f4412e94ca36d863c4aed79c8ca1b0b055..6259cceddb12fe8b511eba64533cf4ccb75f0c6e 100644
--- a/interface/web/dns/form/dns_soa.tform.php
+++ b/interface/web/dns/form/dns_soa.tform.php
@@ -323,6 +323,21 @@ $form["tabs"]['dns_soa'] = array (
 	)
 );
 
+$sys_config = $app->getconf->get_global_config('dns');
+if($sys_config['dns_show_zoneexport'] == 'y') {
+	$form["tabs"]['dns_rendered_zone'] = array (
+		'title'  => "Zone rendering",
+		'width'  => 100,
+		'template'  => "templates/dns_soa_rendered.htm",
+		'fields'  => array (
+			'rendered_zone' => array (
+				'datatype' => 'TEXT',
+				'formtype' => 'TEXTAREA',
+			),
+		)
+	);
+}
+
 // show update acl to admins only.
 if(!$app->auth->is_admin()) unset($form["tabs"]['dns_soa']['fields']['update_acl']);
 
diff --git a/interface/web/dns/lib/lang/ar_dns_soa.lng b/interface/web/dns/lib/lang/ar_dns_soa.lng
index 0d90b7091b8554e3e20237442748a30bc2a35adf..4333c3793aa1c144ce4f9da6a0d823700b6e1fa2 100644
--- a/interface/web/dns/lib/lang/ar_dns_soa.lng
+++ b/interface/web/dns/lib/lang/ar_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/bg_dns_soa.lng b/interface/web/dns/lib/lang/bg_dns_soa.lng
index 4cd3c705ac3e185889c2611ce48b86ce8c797545..c1e57edf8b9ffa60b9e6f7ae306a1ebeae2184d7 100644
--- a/interface/web/dns/lib/lang/bg_dns_soa.lng
+++ b/interface/web/dns/lib/lang/bg_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/br_dns_soa.lng b/interface/web/dns/lib/lang/br_dns_soa.lng
index 81b2bb24c75482c3d97bdb8868f20e7abd9ebde9..e6c8982de0259df07f2d979f0b62bf6abf9fa241 100644
--- a/interface/web/dns/lib/lang/br_dns_soa.lng
+++ b/interface/web/dns/lib/lang/br_dns_soa.lng
@@ -42,3 +42,5 @@ $wb['error_not_allowed_server_id'] = 'O servidor selecionado não é permitido p
 $wb['soa_cannot_be_changed_txt'] = 'A zona (SOA) não pode ser modificada. Por favor, contate o administrador se deseja modificar esta zona.';
 $wb['configuration_error_txt'] = 'ERRO DE CONFIGURAÇÃO';
 $wb['dnssec_algo_txt'] = 'Algoritmo DNSSEC';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
diff --git a/interface/web/dns/lib/lang/ca_dns_soa.lng b/interface/web/dns/lib/lang/ca_dns_soa.lng
index ee2fdb07b64c3a188cca64d12fe20b6129c21f69..2ac84a17df977e720a5b2fe752d30f6a7396ba16 100644
--- a/interface/web/dns/lib/lang/ca_dns_soa.lng
+++ b/interface/web/dns/lib/lang/ca_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/cz_dns_soa.lng b/interface/web/dns/lib/lang/cz_dns_soa.lng
index ef6fdf82d82578aa871a058e9f0c421c85c74f47..73c2582117a039a345323bb3b50d63b2b06b9937 100644
--- a/interface/web/dns/lib/lang/cz_dns_soa.lng
+++ b/interface/web/dns/lib/lang/cz_dns_soa.lng
@@ -42,3 +42,5 @@ $wb['error_not_allowed_server_id'] = 'Vybraný server není pro tento účet pov
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algoritmus';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
diff --git a/interface/web/dns/lib/lang/de_dns_soa.lng b/interface/web/dns/lib/lang/de_dns_soa.lng
index 14897b24e45fd86dbca1e4ddfc95d3317c6aae4b..7338e154338c1a8bd2978c4c3fc5cbbb40a83913 100644
--- a/interface/web/dns/lib/lang/de_dns_soa.lng
+++ b/interface/web/dns/lib/lang/de_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden.
 $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithmus';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/dk_dns_soa.lng b/interface/web/dns/lib/lang/dk_dns_soa.lng
index a4ff50f14fa3f705e59b6ba19472bf8bd5f7ad5d..6759024041b91aa1c83db92fcd9503cb7b029639 100644
--- a/interface/web/dns/lib/lang/dk_dns_soa.lng
+++ b/interface/web/dns/lib/lang/dk_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/el_dns_soa.lng b/interface/web/dns/lib/lang/el_dns_soa.lng
index a22c9de41306f88350baf780d72e9deb38f2eedc..4ceed78dc9ebc0e515b048a91fb768c6d92ab0d6 100644
--- a/interface/web/dns/lib/lang/el_dns_soa.lng
+++ b/interface/web/dns/lib/lang/el_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/en_dns_soa.lng b/interface/web/dns/lib/lang/en_dns_soa.lng
index 7f42b9f27a2bce96cf42fdf50ee21781d16d60d2..a5f1adfae5cc688659c98937fcb3c7c6947fa51d 100644
--- a/interface/web/dns/lib/lang/en_dns_soa.lng
+++ b/interface/web/dns/lib/lang/en_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/es_dns_soa.lng b/interface/web/dns/lib/lang/es_dns_soa.lng
index b1484e749a0258b43ed279ca159226a451badb81..b1061373f509e8a120d4d4b5232a7f842f39dcae 100644
--- a/interface/web/dns/lib/lang/es_dns_soa.lng
+++ b/interface/web/dns/lib/lang/es_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['xfer_error_regex'] = 'Notificar también a: Por favor, usa una dirección I
 $wb['xfer_txt'] = 'Permitir transferencia de zonas a<br />estas IP (lista separada por comas)';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/fi_dns_soa.lng b/interface/web/dns/lib/lang/fi_dns_soa.lng
index d90de950b023047916574a12286dc17570db3798..36f95abab06a827df30a77fc7cd2b60e850defae 100644
--- a/interface/web/dns/lib/lang/fi_dns_soa.lng
+++ b/interface/web/dns/lib/lang/fi_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/fr_dns_soa.lng b/interface/web/dns/lib/lang/fr_dns_soa.lng
index d2449c323e9a95cb966fd7f9497699a7044f51db..dd66dc19865e0b8e60eb97f05e65ca360e2e1be4 100644
--- a/interface/web/dns/lib/lang/fr_dns_soa.lng
+++ b/interface/web/dns/lib/lang/fr_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/hr_dns_soa.lng b/interface/web/dns/lib/lang/hr_dns_soa.lng
index d738ff1e184cb52628d8aa105c16cc92503a60bb..5d88b4708746e0673fcd66bb4f40cd4e863a7a91 100644
--- a/interface/web/dns/lib/lang/hr_dns_soa.lng
+++ b/interface/web/dns/lib/lang/hr_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/hu_dns_soa.lng b/interface/web/dns/lib/lang/hu_dns_soa.lng
index 38d3272f0448e154954de2ef7d0c8e24864ddc60..fdabdd99c295582fdd02d1400400ab3fbd872dd9 100644
--- a/interface/web/dns/lib/lang/hu_dns_soa.lng
+++ b/interface/web/dns/lib/lang/hu_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/id_dns_soa.lng b/interface/web/dns/lib/lang/id_dns_soa.lng
index 2c1842e6f2e92647311df5fb13a6733739c817de..d6cb9d78dae561d91607469c4a31f27138d6888f 100644
--- a/interface/web/dns/lib/lang/id_dns_soa.lng
+++ b/interface/web/dns/lib/lang/id_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/it_dns_soa.lng b/interface/web/dns/lib/lang/it_dns_soa.lng
index 714c6c70566c3af03ee5395ccc5790a8b86273c9..56dfd03daac943c9ec5f360da979e0b3d6889c32 100644
--- a/interface/web/dns/lib/lang/it_dns_soa.lng
+++ b/interface/web/dns/lib/lang/it_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/ja_dns_soa.lng b/interface/web/dns/lib/lang/ja_dns_soa.lng
index a2e5e20c7158043476967e5cbda49544a7abf3fa..70d9414d26630f1e1ec4bd5ad1ca55c99b549fce 100644
--- a/interface/web/dns/lib/lang/ja_dns_soa.lng
+++ b/interface/web/dns/lib/lang/ja_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/nl_dns_soa.lng b/interface/web/dns/lib/lang/nl_dns_soa.lng
index 2b2b734e3ba778d49b6ebf661741e34d89565596..fda742cf148adb12a11d72467e04746023e14ed4 100644
--- a/interface/web/dns/lib/lang/nl_dns_soa.lng
+++ b/interface/web/dns/lib/lang/nl_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format ter referentie en export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, er is nog geen data beschikbaar.';
 ?>
diff --git a/interface/web/dns/lib/lang/pl_dns_soa.lng b/interface/web/dns/lib/lang/pl_dns_soa.lng
index 7502a592372707764358fde63333b8ef0938ee9d..d83e0aeeb0e18a392e71238fa021436365166b0e 100644
--- a/interface/web/dns/lib/lang/pl_dns_soa.lng
+++ b/interface/web/dns/lib/lang/pl_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/pt_dns_soa.lng b/interface/web/dns/lib/lang/pt_dns_soa.lng
index 7d4c692855ed4a70dcc01e7d1026ce7e48bd2fa5..e1e8490b7d04fde56e5dbd625410c6bb753bfdcd 100644
--- a/interface/web/dns/lib/lang/pt_dns_soa.lng
+++ b/interface/web/dns/lib/lang/pt_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/ro_dns_soa.lng b/interface/web/dns/lib/lang/ro_dns_soa.lng
index f1125b698158d055447ecff1240a4c6cac481d0c..87382ffa6fb46947058476641213235176e4ded6 100644
--- a/interface/web/dns/lib/lang/ro_dns_soa.lng
+++ b/interface/web/dns/lib/lang/ro_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/ru_dns_soa.lng b/interface/web/dns/lib/lang/ru_dns_soa.lng
index f6043010d4e021d4d677e6fca002456e924cb3f3..36a4c89cdf10d503eb5b1ca05b8d3b2626167dfe 100644
--- a/interface/web/dns/lib/lang/ru_dns_soa.lng
+++ b/interface/web/dns/lib/lang/ru_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'Выбранный сервер не до
 $wb['soa_cannot_be_changed_txt'] = 'Зона (SOA) не может быть изменена. Пожалуйста, обратитесь к администратору, чтобы изменить зону.';
 $wb['configuration_error_txt'] = 'ОШИБКА КОНФИГУРАЦИИ';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/se_dns_soa.lng b/interface/web/dns/lib/lang/se_dns_soa.lng
index a27181699d12d5055b734d6478207d47f4655571..0e9732b43e2c25c4745f44b5a81aa75eedc736b7 100644
--- a/interface/web/dns/lib/lang/se_dns_soa.lng
+++ b/interface/web/dns/lib/lang/se_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/sk_dns_soa.lng b/interface/web/dns/lib/lang/sk_dns_soa.lng
index a03b15d47773e0897b30e3b430a77e5a4a4defa5..115df5672527784714a3b563744077d0d9ff42ac 100644
--- a/interface/web/dns/lib/lang/sk_dns_soa.lng
+++ b/interface/web/dns/lib/lang/sk_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for thi
 $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.';
 $wb['configuration_error_txt'] = 'CONFIGURATION ERROR';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/lib/lang/tr_dns_soa.lng b/interface/web/dns/lib/lang/tr_dns_soa.lng
index e5d55678cbd42f76353d2923d1c5d252c9c6d81a..fc1bc60a82aa95bbd9451f246b3ccf7e9c918529 100644
--- a/interface/web/dns/lib/lang/tr_dns_soa.lng
+++ b/interface/web/dns/lib/lang/tr_dns_soa.lng
@@ -42,4 +42,6 @@ $wb['error_not_allowed_server_id'] = 'Seçilmiş sunucuda bu hesap kullanılamaz
 $wb['soa_cannot_be_changed_txt'] = 'Bölge (SOA) değiştirilemez. Lütfen bölgeyi değiştirmek için yöneticiniz ile görüşün.';
 $wb['configuration_error_txt'] = 'YAPILANDIRMA SORUNU';
 $wb['dnssec_algo_txt'] = 'DNSSEC Algorithm';
+$wb['rendered_zone_txt'] = 'Bind zone format for reference and export.';
+$wb['rendered_zone_unavailable_txt'] = 'Sorry, no data is available yet.';
 ?>
diff --git a/interface/web/dns/templates/dns_soa_rendered.htm b/interface/web/dns/templates/dns_soa_rendered.htm
new file mode 100644
index 0000000000000000000000000000000000000000..31f1d925a5627a305f8a1f4319e490fb499db1a8
--- /dev/null
+++ b/interface/web/dns/templates/dns_soa_rendered.htm
@@ -0,0 +1,12 @@
+
+{tmpl_if name='rendered_zone'}
+    {tmpl_var name='rendered_zone_txt'}
+    <pre>{tmpl_var name='rendered_zone'}</pre>
+{tmpl_else}
+    {tmpl_var name='rendered_zone_unavailable_txt'}
+{/tmpl_if}
+
+<div class="pnl_formsarea">
+    <input type="hidden" name="id" value="{tmpl_var name='id'}">
+</div>
+
diff --git a/interface/web/login/index.php b/interface/web/login/index.php
index 70c3dbe055c3d56299a09682ab757492190a3ced..2bcb380d95b75a406c913b9cd7a2261ddee67cd4 100644
--- a/interface/web/login/index.php
+++ b/interface/web/login/index.php
@@ -28,297 +28,393 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-require_once '../../lib/config.inc.php';
-require_once '../../lib/app.inc.php';
+/**
+ * @param app $app
+ * @param $error
+ * @param $conf
+ * @param $module
+ * @return void
+ */
+function process_login_request(app $app, &$error, $conf, $module)
+{
+	//** Check variables
+	if (!preg_match("/^[\w\.\-\_\@]{1,128}$/", $app->functions->idn_encode($_POST['username']))) $error = $app->lng('user_regex_error');
+	if (!preg_match("/^.{1,256}$/i", $_POST['password'])) $error = $app->lng('pw_error_length');
 
-// Check if we have an active users ession and no login_as.
-if($_SESSION['s']['user']['active'] == 1 && @$_POST['login_as'] != 1) {
-	header('Location: /index.php');
-	die();
-}
+	//** importing variables
+	$ip = md5($_SERVER['REMOTE_ADDR']);
+	$username = $_POST['username'];
+	$password = $_POST['password'];
+	$loginAs = false;
+	$time = time();
 
-$app->uses('tpl');
-$app->tpl->newTemplate('main_login.tpl.htm');
-$app->tpl->setInclude('content_tpl', 'templates/index.htm');
+	if ($username == '' || $password == '' || $error != '') {
+		//* Username or password empty
+		if ($error == '') $error = $app->lng('error_user_password_empty');
+		$app->plugin->raiseEvent('login_empty', $username);
+		return;
+	}
 
-$error = '';
+	$loginAs = is_login_as($app, $username, $password);
 
-$app->load_language_file('web/login/lib/lang/'.$conf["language"].'.lng');
+	//* Check if there are already wrong logins
+	$sql = "SELECT * FROM `attempts_login` WHERE `ip`= ? AND  `login_time` > (NOW() - INTERVAL 1 MINUTE) LIMIT 1";
+	$alreadyfailed = $app->db->queryOneRecord($sql, $ip);
 
-// Maintenance mode
-$maintenance_mode = false;
-$maintenance_mode_error = '';
-$server_config_array = $app->getconf->get_global_config('misc');
-if($app->is_under_maintenance()) {
-	$maintenance_mode = true;
-	$maintenance_mode_error = $app->lng('error_maintenance_mode');
-}
+	//* too many failed logins
+	if ($alreadyfailed['times'] > 5) {
+		$error = $app->lng('error_user_too_many_logins');
+		return;
+	}
 
-//* Login Form was sent
-if(count($_POST) > 0) {
+	$user = validate_and_fetch_user($app, $username, $password, $loginAs, $conf);
 
-	//** Check variables
-	if(!preg_match("/^[\w\.\-\_\@]{1,128}$/", $app->functions->idn_encode($_POST['username']))) $error = $app->lng('user_regex_error');
-	if(!preg_match("/^.{1,256}$/i", $_POST['password'])) $error = $app->lng('pw_error_length');
+	if ($user) {
+		if ($user['active'] != 1) {
+			$error = $app->lng('error_user_blocked');
+			return;
+		}
 
-	//** importing variables
-	$ip = md5($_SERVER['REMOTE_ADDR']);
-	$username = $_POST['username'];
-	$password = $_POST['password'];
-	$loginAs  = false;
-	$time = time();
+		// Maintenance mode - allow logins only when maintenance mode is off or if the user is admin
+		if ($app->is_under_maintenance() && $user['typ'] != 'admin') return;
 
-	if($username != '' && $password != '' && $error == '') {
-		/*
-		 *  Check, if there is a "login as" instead of a "normal" login
-		 */
-		if (isset($_SESSION['s']['user']) && $_SESSION['s']['user']['active'] == 1){
-			/*
-			 * only the admin or reseller can "login as" so if the user is NOT an admin or reseller, we
-			 * open the startpage (after killing the old session), so the user
-			 * is logout and has to start again!
-			 */
-			if ($_SESSION['s']['user']['typ'] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) {
-				/*
-				 * The actual user is NOT a admin or reseller, but maybe he
-				 * has logged in as "normal" user before...
-				 */
+		if ($user['typ'] == 'admin' && !is_admin_ip_whitelisted($_SERVER['REMOTE_ADDR'], $conf)) {
+			// TODO: if it's not a security risk (information disclosure) to
+			// let the user know they are not whitelisted, then change this
+			// error message to a more appropriate one
+			$error = $app->lng('error_user_password_incorrect');
+			return;
+		}
 
-				if (isset($_SESSION['s_old'])&& ($_SESSION['s_old']['user']['typ'] == 'admin' || $app->auth->has_clients($_SESSION['s_old']['user']['userid']))){
-					/* The "old" user is admin or reseller, so everything is ok
-					 * if he is reseller, we need to check if he logs in to one of his clients
-					 */
-					if($_SESSION['s_old']['user']['typ'] != 'admin') {
-
-						/* this is the one currently logged in (normal user) */
-						$old_client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
-						$old_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $old_client_group_id);
-
-						/* this is the reseller, that shall be re-logged in */
-						$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
-						$tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
-						$client_group_id = $app->functions->intval($tmp['default_group']);
-						$tmp_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
-
-						if(!$tmp_client || $old_client["parent_client_id"] != $tmp_client["client_id"] || $tmp["default_group"] != $_SESSION["s_old"]["user"]["default_group"] ) {
-							die("You don't have the right to 'login as' this user!");
-						}
-						unset($old_client);
-						unset($tmp_client);
-						unset($tmp);
-					}
-				}
-				else {
-					die("You don't have the right to 'login as'!");
-				}
-			} elseif($_SESSION['s']['user']['typ'] != 'admin' && (!isset($_SESSION['s_old']['user']) || $_SESSION['s_old']['user']['typ'] != 'admin')) {
-				/* a reseller wants to 'login as', we need to check if he is allowed to */
-				$res_client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
-				$res_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $res_client_group_id);
-
-				/* this is the user the reseller wants to 'login as' */
-				$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
-				$tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
-				$tmp_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $tmp["default_group"]);
-
-				if(!$tmp || $tmp_client["parent_client_id"] != $res_client["client_id"]) {
-					die("You don't have the right to login as this user!");
-				}
-				unset($res_client);
-				unset($tmp);
-				unset($tmp_client);
+		// User login right, so attempts can be deleted
+		$sql = "DELETE FROM `attempts_login` WHERE `ip`=?";
+		$app->db->query($sql, $ip);
+		$user = $app->db->toLower($user);
+
+		if ($loginAs) $oldSession = $_SESSION['s'];
+
+		// Session regenerate causes login problems on some systems, see Issue #3827
+		// Set session_regenerate_id to no in security settings, it you encounter
+		// this problem.
+		$app->uses('getconf');
+		$security_config = $app->getconf->get_security_config('permissions');
+		if (isset($security_config['session_regenerate_id']) && $security_config['session_regenerate_id'] == 'yes') {
+			if (!$loginAs) session_regenerate_id(true);
+		}
+		$_SESSION = array();
+		if ($loginAs) $_SESSION['s_old'] = $oldSession; // keep the way back!
+		$_SESSION['s']['user'] = $user;
+		$_SESSION['s']['user']['theme'] = isset($user['app_theme']) ? $user['app_theme'] : 'default';
+		$_SESSION['s']['language'] = $app->functions->check_language($user['language']);
+		$_SESSION["s"]['theme'] = $_SESSION['s']['user']['theme'];
+		if ($loginAs) $_SESSION['s']['plugin_cache'] = $_SESSION['s_old']['plugin_cache'];
+
+		if (is_file(ISPC_WEB_PATH.'/'.$_SESSION['s']['user']['startmodule'].'/lib/module.conf.php')) {
+			include_once $app->functions->check_include_path(ISPC_WEB_PATH.'/'.$_SESSION['s']['user']['startmodule'].'/lib/module.conf.php');
+			$menu_dir = ISPC_WEB_PATH.'/'.$_SESSION['s']['user']['startmodule'].'/lib/menu.d';
+			include_menu_dir_files($menu_dir);
+			$_SESSION['s']['module'] = $module;
+		}
+		// check if the user theme is valid
+		if ($_SESSION['s']['user']['theme'] != 'default') {
+			$tmp_path = ISPC_THEMES_PATH."/".$_SESSION['s']['user']['theme'];
+			if (!@is_dir($tmp_path) || !@file_exists($tmp_path."/ispconfig_version") || trim(file_get_contents($tmp_path."/ispconfig_version")) != ISPC_APP_VERSION) {
+				// fall back to default theme if this one is not compatible with current ispc version
+				$_SESSION['s']['user']['theme'] = 'default';
+				$_SESSION['s']['theme'] = 'default';
+				$_SESSION['show_error_msg'] = $app->lng('theme_not_compatible');
 			}
-			$loginAs = true;
+		}
 
+		$app->plugin->raiseEvent('login', $username);
+
+		//* Save successful login message to var
+		$authlog = 'Successful login for user \''.$username.'\' from '.$_SERVER['REMOTE_ADDR'].' at '.date('Y-m-d H:i:s').' with session ID '.session_id();
+		$authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a');
+		fwrite($authlog_handle, $authlog."\n");
+		fclose($authlog_handle);
+
+		/*
+		* We need LOGIN_REDIRECT instead of HEADER_REDIRECT to load the
+		* new theme, if the logged-in user has another
+		*/
+
+		if ($loginAs) {
+			echo 'LOGIN_REDIRECT:'.$_SESSION['s']['module']['startpage'];
+			exit;
 		} else {
-			/* normal login */
-			$loginAs = false;
+			header('Location: ../index.php');
+			die();
 		}
+	} else {
+		if (!$alreadyfailed['times']) {
+			//* user login the first time wrong
+			$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
+			$app->db->query($sql, $ip);
+		} elseif ($alreadyfailed['times'] >= 1) {
+			//* update times wrong
+			$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? AND `login_time` < NOW() ORDER BY `login_time` DESC LIMIT 1";
+			$app->db->query($sql, $ip);
+		}
+		//* Incorrect login - Username and password incorrect
+		$error = $app->lng('error_user_password_incorrect');
+		if ($app->db->errorMessage != '') $error .= '<br />'.$app->db->errorMessage != '';
+
+		$app->plugin->raiseEvent('login_failed', $username);
+		//* Save failed login message to var
+		$authlog = 'Failed login for user \''.$username.'\' from '.$_SERVER['REMOTE_ADDR'].' at '.date('Y-m-d H:i:s');
+		$authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a');
+		fwrite($authlog_handle, $authlog."\n");
+		fclose($authlog_handle);
+	}
+}
+
+/**
+ * Checks if the given admin's IP address is whitelisted.
+ * @param string $ip
+ * @return bool
+ */
+function is_admin_ip_whitelisted($ip, $conf)
+{
+	// if there is no config value, we assume that webmaster doesn't use this feature
+	if (!isset($conf['admin_ip_whitelist_file'])) return true;
+
+	// if the file doesn't exist, we assume that webmaster doesn't use this feature
+	if (!file_exists($conf['admin_ip_whitelist_file'])) return true;
+
+	$file_lines = file($conf['admin_ip_whitelist_file']);
+
+	$matches = array_filter($file_lines, function($v) use ($ip) {
+		$line = trim($v);
+
+		// exclude empty lines and comments
+		if ($line === '' || $line[0] === '#') return false;
+
+		return ip_matches_cidr($ip, $line);
+	});
+
+	return count($matches) > 0;
+}
+
+// based on https://www.php.net/manual/en/ref.network.php (comments)
+/**
+ * Checks if the given IP address matches the given CIDR.
+ * @param $ip
+ * @param $cidr
 
-		//* Check if there are already wrong logins
-		$sql = "SELECT * FROM `attempts_login` WHERE `ip`= ? AND  `login_time` > (NOW() - INTERVAL 1 MINUTE) LIMIT 1";
-		$alreadyfailed = $app->db->queryOneRecord($sql, $ip);
+ * @return bool
+ */
+function ip_matches_cidr ($ip, $cidr) {
+	list ($net, $mask) = explode ('/', $cidr);
+	if (!$mask) $mask = 32;
 
-		//* too many failedlogins
-		if($alreadyfailed['times'] > 5) {
-			$error = $app->lng('error_user_too_many_logins');
+	$ip_net = ip2long ($net);
+	$ip_mask = ~((1 << (32 - $mask)) - 1);
+
+	$ip_ip = ip2long ($ip);
+
+	return (($ip_ip & $ip_mask) == ($ip_net & $ip_mask));
+}
+
+/**
+ * Validates user credentials and fetches the user if validation succeeded
+ * @param app $app
+ * @param $username
+ * @param $password
+ * @param $loginAs
+ * @param $conf
+ * @return array | bool
+ */
+function validate_and_fetch_user(app $app, $username, $password, $loginAs, $conf)
+{
+	if ($loginAs) {
+		$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
+		return $app->db->queryOneRecord($sql, (string)$username, (string)$password);
+	}
+
+	if (stristr($username, '@')) {
+		//* mailuser login
+		$sql = "SELECT * FROM mail_user WHERE login = ? or email = ?";
+		$mailuser = $app->db->queryOneRecord($sql, (string)$username, $app->functions->idn_encode($username));
+
+		return $mailuser
+			? build_fake_user($app, $username, $password, $mailuser, $conf)
+			: false;
+	}
+
+	//* normal cp user login
+	$sql = "SELECT * FROM sys_user WHERE USERNAME = ?";
+	$user = $app->db->queryOneRecord($sql, (string)$username);
+	if (!$user) return false;
+
+	$saved_password = stripslashes($user['passwort']);
+	if (substr($saved_password, 0, 1) == '$') {
+		//* The password is encrypted with crypt
+		return crypt(stripslashes($password), $saved_password) == $saved_password
+			? $user
+			: false;
+	}
+
+	//* The password is md5 encrypted
+	if (md5($password) != $saved_password) return false;
+
+	// update password with secure algo
+	$sql = 'UPDATE `sys_user` SET `passwort` = ? WHERE `username` = ?';
+	$app->db->query($sql, $app->auth->crypt_password($password), (string)$username);
+
+	return $user;
+}
+
+/**
+ * @param app $app
+ * @param $username
+ * @param $password
+ * @param array $mailuser
+ * @param array $user
+ * @param $conf
+ * @return array
+ */
+function build_fake_user(app $app, $username, $password, array $mailuser, $conf)
+{
+	$saved_password = stripslashes($mailuser['password']);
+	//* Check if mailuser password is correct
+	if (crypt(stripslashes($password), $saved_password) == $saved_password) {
+		//* Get the sys_user language of the client of the mailuser
+		$sys_user_lang = $app->db->queryOneRecord("SELECT language FROM sys_user WHERE default_group = ?", $mailuser['sys_groupid']);
+
+		//* we build a fake user here which has access to the mailuser module only and userid 0
+		$user = array();
+		$user['userid'] = 0;
+		$user['active'] = 1;
+		$user['startmodule'] = 'mailuser';
+		$user['modules'] = 'mailuser';
+		$user['typ'] = 'user';
+		$user['email'] = $mailuser['email'];
+		$user['username'] = $username;
+		if (is_array($sys_user_lang) && $sys_user_lang['language'] != '') {
+			$user['language'] = $sys_user_lang['language'];
 		} else {
+			$user['language'] = $conf['language'];
+		}
+		$user['theme'] = $conf['theme'];
+		$user['app_theme'] = $conf['theme'];
+		$user['mailuser_id'] = $mailuser['mailuser_id'];
+		$user['default_group'] = $mailuser['sys_groupid'];
+	}
 
-			if ($loginAs){
-				$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
-				$user = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
-			} else {
+	return $user;
+}
 
-				if(stristr($username, '@')) {
-					//* mailuser login
-					$sql = "SELECT * FROM mail_user WHERE login = ? or email = ?";
-					$mailuser = $app->db->queryOneRecord($sql, (string)$username, $app->functions->idn_encode($username));
-					$user = false;
-					if($mailuser) {
-						$saved_password = stripslashes($mailuser['password']);
-						//* Check if mailuser password is correct
-						if(crypt(stripslashes($password), $saved_password) == $saved_password) {
-							//* Get the sys_user language of the client of the mailuser
-							$sys_user_lang = $app->db->queryOneRecord("SELECT language FROM sys_user WHERE default_group = ?", $mailuser['sys_groupid'] );
-
-							//* we build a fake user here which has access to the mailuser module only and userid 0
-							$user = array();
-							$user['userid'] = 0;
-							$user['active'] = 1;
-							$user['startmodule'] = 'mailuser';
-							$user['modules'] = 'mailuser';
-							$user['typ'] = 'user';
-							$user['email'] = $mailuser['email'];
-							$user['username'] = $username;
-							if(is_array($sys_user_lang) && $sys_user_lang['language'] != '') {
-								$user['language'] = $sys_user_lang['language'];
-							} else {
-								$user['language'] = $conf['language'];
-							}
-							$user['theme'] = $conf['theme'];
-							$user['app_theme'] = $conf['theme'];
-							$user['mailuser_id'] = $mailuser['mailuser_id'];
-							$user['default_group'] = $mailuser['sys_groupid'];
-						}
-					}
-				} else {
-					//* normal cp user login
-					$sql = "SELECT * FROM sys_user WHERE USERNAME = ?";
-					$user = $app->db->queryOneRecord($sql, (string)$username);
-					if($user) {
-						$saved_password = stripslashes($user['passwort']);
-						if(substr($saved_password, 0, 1) == '$') {
-							//* The password is encrypted with crypt
-							if(crypt(stripslashes($password), $saved_password) != $saved_password) {
-								$user = false;
-							}
-						} else {
-							//* The password is md5 encrypted
-							if(md5($password) != $saved_password) {
-								$user = false;
-							} else {
-								// update password with secure algo
-								$sql = 'UPDATE `sys_user` SET `passwort` = ? WHERE `username` = ?';
-								$app->db->query($sql, $app->auth->crypt_password($password), (string)$username);
-							}
-						}
-					} else {
-						$user = false;
-					}
-				}
-			}
+/**
+ * Checks if there is a "login as" instead of a "normal" login
+ * @param app $app
+ * @param $username
+ * @param $password
+ * @return bool
+ */
+function is_login_as(app $app, $username, $password)
+{
+	if (isset($_SESSION['s']['user']) && $_SESSION['s']['user']['active'] == 1) {
+		/*
+		 * only the admin or reseller can "login as" so if the user is NOT an admin or reseller, we
+		 * open the startpage (after killing the old session), so the user
+		 * is logout and has to start again!
+		 */
+		if ($_SESSION['s']['user']['typ'] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) {
+			/*
+			 * The actual user is NOT a admin or reseller, but maybe he
+			 * has logged in as "normal" user before...
+			 */
+
+			if (isset($_SESSION['s_old']) && ($_SESSION['s_old']['user']['typ'] == 'admin' || $app->auth->has_clients($_SESSION['s_old']['user']['userid']))) {
+				/* The "old" user is admin or reseller, so everything is ok
+				 * if he is reseller, we need to check if he logs in to one of his clients
+				 */
+				if ($_SESSION['s_old']['user']['typ'] != 'admin') {
+
+					/* this is the one currently logged in (normal user) */
+					$old_client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+					$old_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $old_client_group_id);
 
-			if($user) {
-				if($user['active'] == 1) {
-					// Maintenance mode - allow logins only when maintenance mode is off or if the user is admin
-					if(!$app->is_under_maintenance() || $user['typ'] == 'admin'){
-
-						// User login right, so attempts can be deleted
-						$sql = "DELETE FROM `attempts_login` WHERE `ip`=?";
-						$app->db->query($sql, $ip);
-						$user = $app->db->toLower($user);
-
-						if ($loginAs) $oldSession = $_SESSION['s'];
-
-						// Session regenerate causes login problems on some systems, see Issue #3827
-						// Set session_regenerate_id to no in security settings, it you encounter
-						// this problem.
-						$app->uses('getconf');
-						$security_config = $app->getconf->get_security_config('permissions');
-						if(isset($security_config['session_regenerate_id']) && $security_config['session_regenerate_id'] == 'yes') {
-							if (!$loginAs) session_regenerate_id(true);
-						}
-						$_SESSION = array();
-						if ($loginAs) $_SESSION['s_old'] = $oldSession; // keep the way back!
-						$_SESSION['s']['user'] = $user;
-						$_SESSION['s']['user']['theme'] = isset($user['app_theme']) ? $user['app_theme'] : 'default';
-						$_SESSION['s']['language'] = $app->functions->check_language($user['language']);
-						$_SESSION["s"]['theme'] = $_SESSION['s']['user']['theme'];
-						if ($loginAs) $_SESSION['s']['plugin_cache'] = $_SESSION['s_old']['plugin_cache'];
-
-						if(is_file(ISPC_WEB_PATH . '/' . $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php')) {
-							include_once $app->functions->check_include_path(ISPC_WEB_PATH . '/' . $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php');
-							$menu_dir = ISPC_WEB_PATH.'/' . $_SESSION['s']['user']['startmodule'] . '/lib/menu.d';
-								if (is_dir($menu_dir)) {
-								if ($dh = opendir($menu_dir)) {
-									//** Go through all files in the menu dir
-									while (($file = readdir($dh)) !== false) {
-										if ($file != '.' && $file != '..' && substr($file, -9, 9) == '.menu.php' && $file != 'dns_resync.menu.php') {
-											include_once $menu_dir . '/' . $file;
-										}
-									}
-								}
-							}
-							$_SESSION['s']['module'] = $module;
-						}
-							// check if the user theme is valid
-						if($_SESSION['s']['user']['theme'] != 'default') {
-							$tmp_path = ISPC_THEMES_PATH."/".$_SESSION['s']['user']['theme'];
-							if(!@is_dir($tmp_path) || !@file_exists($tmp_path."/ispconfig_version") || trim(file_get_contents($tmp_path."/ispconfig_version")) != ISPC_APP_VERSION) {
-								// fall back to default theme if this one is not compatible with current ispc version
-								$_SESSION['s']['user']['theme'] = 'default';
-								$_SESSION['s']['theme'] = 'default';
-								$_SESSION['show_error_msg'] = $app->lng('theme_not_compatible');
-							}
-						}
-
-						$app->plugin->raiseEvent('login', $username);
-
-						//* Save successfull login message to var
-						$authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id();
-						$authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a');
-						fwrite($authlog_handle, $authlog ."\n");
-						fclose($authlog_handle);
-
-						/*
-						* We need LOGIN_REDIRECT instead of HEADER_REDIRECT to load the
-						* new theme, if the logged-in user has another
-						*/
-
-						if ($loginAs){
-							echo 'LOGIN_REDIRECT:'.$_SESSION['s']['module']['startpage'];
-							exit;
-						} else {
-							header('Location: ../index.php');
-							die();
-						}
+					/* this is the reseller, that shall be re-logged in */
+					$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
+					$tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
+					$client_group_id = $app->functions->intval($tmp['default_group']);
+					$tmp_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id);
+
+					if (!$tmp_client || $old_client["parent_client_id"] != $tmp_client["client_id"] || $tmp["default_group"] != $_SESSION["s_old"]["user"]["default_group"]) {
+						die("You don't have the right to 'login as' this user!");
 					}
-				} else {
-					$error = $app->lng('error_user_blocked');
+					unset($old_client);
+					unset($tmp_client);
+					unset($tmp);
 				}
 			} else {
-				if(!$alreadyfailed['times'] )
-				{
-					//* user login the first time wrong
-					$sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())";
-					$app->db->query($sql, $ip);
-				} elseif($alreadyfailed['times'] >= 1) {
-					//* update times wrong
-					$sql = "UPDATE `attempts_login` SET `times`=`times`+1, `login_time`=NOW() WHERE `ip` = ? AND `login_time` < NOW() ORDER BY `login_time` DESC LIMIT 1";
-					$app->db->query($sql, $ip);
-				}
-				//* Incorrect login - Username and password incorrect
-				$error = $app->lng('error_user_password_incorrect');
-				if($app->db->errorMessage != '') $error .= '<br />'.$app->db->errorMessage != '';
-
-				$app->plugin->raiseEvent('login_failed', $username);
-				//* Save failed login message to var
-				$authlog = 'Failed login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s');
-				$authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a');
-				fwrite($authlog_handle, $authlog ."\n");
-				fclose($authlog_handle);
+				die("You don't have the right to 'login as'!");
 			}
+		} elseif ($_SESSION['s']['user']['typ'] != 'admin' && (!isset($_SESSION['s_old']['user']) || $_SESSION['s_old']['user']['typ'] != 'admin')) {
+			/* a reseller wants to 'login as', we need to check if he is allowed to */
+			$res_client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+			$res_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $res_client_group_id);
+
+			/* this is the user the reseller wants to 'login as' */
+			$sql = "SELECT * FROM sys_user WHERE USERNAME = ? and PASSWORT = ?";
+			$tmp = $app->db->queryOneRecord($sql, (string)$username, (string)$password);
+			$tmp_client = $app->db->queryOneRecord("SELECT client.client_id, client.parent_client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $tmp["default_group"]);
+
+			if (!$tmp || $tmp_client["parent_client_id"] != $res_client["client_id"]) {
+				die("You don't have the right to login as this user!");
+			}
+			unset($res_client);
+			unset($tmp);
+			unset($tmp_client);
 		}
-		} else {
-		//* Username or password empty
-		if($error == '') $error = $app->lng('error_user_password_empty');
-			$app->plugin->raiseEvent('login_empty', $username);
+		$loginAs = true;
+
+	} else {
+		/* normal login */
+		$loginAs = false;
 	}
+
+	return $loginAs;
+}
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+include_once '../common.php';
+
+// Check if we have an active users session and no login_as.
+if ($_SESSION['s']['user']['active'] == 1 && @$_POST['login_as'] != 1) {
+	header('Location: /index.php');
+	die();
+}
+
+$app->uses('tpl');
+$app->tpl->newTemplate('main_login.tpl.htm');
+$app->tpl->setInclude('content_tpl', 'templates/index.htm');
+
+$error = '';
+
+$app->load_language_file('web/login/lib/lang/'.$conf["language"].'.lng');
+
+// Maintenance mode
+$maintenance_mode = false;
+$maintenance_mode_error = '';
+$server_config_array = $app->getconf->get_global_config('misc');
+if ($app->is_under_maintenance()) {
+	$maintenance_mode = true;
+	$maintenance_mode_error = $app->lng('error_maintenance_mode');
+}
+
+//* Login Form was sent
+if (count($_POST) > 0) {
+	process_login_request($app, $error, $conf, $module);
 }
 
-// Maintenance mode - show message when people try to log in and also when people are forcedly logged off
-if($maintenance_mode_error != '') $error = '<strong>'.$maintenance_mode_error.'</strong><br><br>'.$error;
-if($error != ''){
+// Maintenance mode - show message when people try to log in and also when people are forcibly logged off
+if ($maintenance_mode_error != '') $error = '<strong>'.$maintenance_mode_error.'</strong><br><br>'.$error;
+if ($error != '') {
 	$error = '<div class="box box_error">'.$error.'</div>';
 }
 
@@ -326,7 +422,7 @@ $app->load('getconf');
 $sys_config = $app->getconf->get_global_config('misc');
 
 $security_config = $app->getconf->get_security_config('permissions');
-if($security_config['password_reset_allowed'] == 'yes') {
+if ($security_config['password_reset_allowed'] == 'yes') {
 	$app->tpl->setVar('pw_lost_show', 1);
 } else {
 	$app->tpl->setVar('pw_lost_show', 0);
@@ -348,7 +444,7 @@ $app->tpl->setVar('current_theme', isset($_SESSION['s']['theme']) ? $_SESSION['s
 
 // Logo
 $logo = $app->db->queryOneRecord("SELECT * FROM sys_ini WHERE sysini_id = 1");
-if($logo['custom_logo'] != ''){
+if ($logo['custom_logo'] != '') {
 	$base64_logo_txt = $logo['custom_logo'];
 } else {
 	$base64_logo_txt = $logo['default_logo'];
@@ -361,12 +457,12 @@ $app->tpl->setVar('base64_logo_txt', $base64_logo_txt);
 
 // Title
 if (!empty($sys_config['company_name'])) {
-	$app->tpl->setVar('company_name', $sys_config['company_name']. ' :: ');
+	$app->tpl->setVar('company_name', $sys_config['company_name'].' :: ');
 }
 
 // Custom Login
 if ($sys_config['custom_login_text'] != '') {
-	 $custom_login = @($sys_config['custom_login_link'] != '')?'<a href="'.$sys_config['custom_login_link'].'" target="_blank">'.$sys_config['custom_login_text'].'</a>':$sys_config['custom_login_text'];
+	$custom_login = @($sys_config['custom_login_link'] != '') ? '<a href="'.$sys_config['custom_login_link'].'" target="_blank">'.$sys_config['custom_login_text'].'</a>' : $sys_config['custom_login_text'];
 }
 $app->tpl->setVar('custom_login', $custom_login);
 
diff --git a/interface/web/mail/form/mail_relay_domain.tform.php b/interface/web/mail/form/mail_relay_domain.tform.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e2523309deb99e75bece53334e23464748cd905
--- /dev/null
+++ b/interface/web/mail/form/mail_relay_domain.tform.php
@@ -0,0 +1,151 @@
+<?php
+
+/*
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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.
+*/
+
+/*
+	Form Definition
+
+	Tabledefinition
+
+	Datatypes:
+	- INTEGER (Forces the input to Int)
+	- DOUBLE
+	- CURRENCY (Formats the values to currency notation)
+	- VARCHAR (no format check, maxlength: 255)
+	- TEXT (no format check)
+	- DATE (Dateformat, automatic conversion to timestamps)
+
+	Formtype:
+	- TEXT (Textfield)
+	- TEXTAREA (Textarea)
+	- PASSWORD (Password textfield, input is not shown when edited)
+	- SELECT (Select option field)
+	- RADIO
+	- CHECKBOX
+	- CHECKBOXARRAY
+	- FILE
+
+	VALUE:
+	- Wert oder Array
+
+	Hint:
+	The ID field of the database table is not part of the datafield definition.
+	The ID field must be always auto incement (int or bigint).
+
+
+*/
+
+$form["title"]    = "mail_relay_domain_title";
+$form["description"]  = "";
+$form["name"]    = "mail_relay_domain";
+$form["action"]   = "mail_relay_domain_edit.php";
+$form["db_table"]  = "mail_relay_domain";
+$form["db_table_idx"] = "relay_domain_id";
+$form["db_history"]  = "yes";
+$form["tab_default"] = "relay_domain";
+$form["list_default"] = "mail_relay_domain_list.php";
+$form["auth"]   = 'yes'; // yes / no
+
+$form["auth_preset"]["userid"]  = 0; // 0 = id of the user, > 0 id must match with id of current user
+$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user
+$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete
+$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete
+
+$form["tabs"]['relay_domain'] = array (
+	'title'  => "tab_relay_domain_title",
+	'width'  => 100,
+	'template'  => "templates/mail_relay_domain_edit.htm",
+	'fields'  => array (
+		//#################################
+		// Begin Datatable fields
+		//#################################
+		'server_id' => array (
+			'datatype' => 'INTEGER',
+			'formtype' => 'SELECT',
+			'default' => '',
+			'datasource' => array (  'type' => 'SQL',
+				'querystring' => 'SELECT server_id,server_name FROM server WHERE mail_server = 1 AND mirror_server_id = 0 AND {AUTHSQL} ORDER BY server_name',
+				'keyfield'=> 'server_id',
+				'valuefield'=> 'server_name'
+			),
+			'value'  => ''
+		),
+		'domain' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'filters'   => array( 0 => array( 'event' => 'SAVE',
+					'type' => 'IDNTOASCII'),
+				1 => array( 'event' => 'SHOW',
+					'type' => 'IDNTOUTF8'),
+				2 => array( 'event' => 'SAVE',
+					'type' => 'TOLOWER'),
+				3 => array( 'event' => 'SAVE',
+					'type' => 'STRIPNL'),
+			),
+			'validators' => array (  0 => array ( 'type' => 'NOTEMPTY',
+					'errmsg' => 'domain_error_empty'),
+				1 => array ( 'type' => 'ISDOMAIN',
+					'errmsg' => 'domain_error_regex'),
+				2 => array ( 'type' => 'CUSTOM',
+					'class' => 'validate_mail_relay_domain',
+					'function' => 'validate_domain',
+					'errmsg' => 'domain_error_unique'),
+			),
+			'default' => '',
+			'value'  => '',
+			'width'  => '30',
+			'maxlength' => '255',
+		),
+		'access' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'filters'   => array(
+					0 => array( 'event' => 'SAVE',
+					'type' => 'STRIPTAGS'),
+					1 => array( 'event' => 'SAVE',
+					'type' => 'STRIPNL')
+			),
+			'default' => 'OK',
+			'value'  => 'OK',
+			'width'  => '30',
+			'maxlength' => '255'
+		),
+		'active' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'CHECKBOX',
+			'default' => 'y',
+			'value'  => array(0 => 'n', 1 => 'y')
+		),
+		//#################################
+		// END Datatable fields
+		//#################################
+	)
+);
+
diff --git a/interface/web/mail/lib/lang/ar_mail_relay_domain.lng b/interface/web/mail/lib/lang/ar_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e5296a9a9bba1dea5a068c7cef8187e5d4e51a4f
--- /dev/null
+++ b/interface/web/mail/lib/lang/ar_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Active';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/ar_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/ar_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e33b3bde4b1d93aca533bc9d806d4fe34e08dded
--- /dev/null
+++ b/interface/web/mail/lib/lang/ar_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Active';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/bg_mail_relay_domain.lng b/interface/web/mail/lib/lang/bg_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..0da8a0a2460de3082333bc0ba84fd1d2da82b416
--- /dev/null
+++ b/interface/web/mail/lib/lang/bg_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Сървър';
+$wb['active_txt'] = 'Активен';
+$wb['domain_txt'] = 'Домейн';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Полето с домейн е празно.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/bg_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/bg_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..be92be35babeb5e5c43977c820e2eec2813d5de7
--- /dev/null
+++ b/interface/web/mail/lib/lang/bg_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Активен';
+$wb['server_id_txt'] = 'Сървър';
+$wb['domain_txt'] = 'Домейн';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/br_mail_relay_domain.lng b/interface/web/mail/lib/lang/br_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..b992e63aa23c2efd58b3d8e1fc787f46170a43d1
--- /dev/null
+++ b/interface/web/mail/lib/lang/br_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Servidor';
+$wb['active_txt'] = 'Ativo';
+$wb['domain_txt'] = 'Domínio';
+$wb['domain_error_regex'] = 'O domínio é inválido.';
+$wb['domain_error_empty'] = 'O domínio está vazio.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/br_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/br_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..95cda7fde6bdaefa600c46fbd23cd9b8e4294a62
--- /dev/null
+++ b/interface/web/mail/lib/lang/br_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Ativo';
+$wb['server_id_txt'] = 'Servidor';
+$wb['domain_txt'] = 'Domínio';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'acesso';
diff --git a/interface/web/mail/lib/lang/ca_mail_relay_domain.lng b/interface/web/mail/lib/lang/ca_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..b6e9d8f2fbc31cb5774d3bfc99e8b949c7f26de3
--- /dev/null
+++ b/interface/web/mail/lib/lang/ca_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Serveur';
+$wb['active_txt'] = 'Actif';
+$wb['domain_txt'] = 'Domaine';
+$wb['domain_error_regex'] = 'Nom de domaine invalide.';
+$wb['domain_error_empty'] = 'Le domain est vide.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/ca_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/ca_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..771b9619745c862e78ca540c91b546a5ab76df36
--- /dev/null
+++ b/interface/web/mail/lib/lang/ca_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Actif';
+$wb['server_id_txt'] = 'Serveur';
+$wb['domain_txt'] = 'Domaine';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'accès';
diff --git a/interface/web/mail/lib/lang/cz_mail_relay_domain.lng b/interface/web/mail/lib/lang/cz_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e5563fd535103835a8617052885fddf4c527985c
--- /dev/null
+++ b/interface/web/mail/lib/lang/cz_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktivní';
+$wb['domain_txt'] = 'Doména';
+$wb['domain_error_regex'] = 'Neplatný název domény.';
+$wb['domain_error_empty'] = 'Doména je prázdná.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/cz_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/cz_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..1932abfa9f7b3e0dbc11763784256de8d243ec5e
--- /dev/null
+++ b/interface/web/mail/lib/lang/cz_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktivní';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Doména';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'Přístup';
diff --git a/interface/web/mail/lib/lang/de_mail_relay_domain.lng b/interface/web/mail/lib/lang/de_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..6c0456a2c242ba694164f33ba5f1b35b11b2e6dd
--- /dev/null
+++ b/interface/web/mail/lib/lang/de_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktiv';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Domain Name ist nicht gültig.';
+$wb['domain_error_empty'] = 'Domain ist leer.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/de_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/de_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..833a055963ee2389b0b93216ce1554142eef59ce
--- /dev/null
+++ b/interface/web/mail/lib/lang/de_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktiv';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'Zugriff';
diff --git a/interface/web/mail/lib/lang/dk_mail_relay_domain.lng b/interface/web/mail/lib/lang/dk_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..d993bcd4b1533a94bc33bdfdc0bca3d8d0ee4c00
--- /dev/null
+++ b/interface/web/mail/lib/lang/dk_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktiv';
+$wb['domain_txt'] = 'Domæne';
+$wb['domain_error_regex'] = 'Ugyldigt domæne name.';
+$wb['domain_error_empty'] = 'Domæne er tom.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/dk_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/dk_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..10479084bebd4e00c9c0220b645d09f9943e9cfa
--- /dev/null
+++ b/interface/web/mail/lib/lang/dk_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktiv';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domæne';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'adgang';
diff --git a/interface/web/mail/lib/lang/el_mail_relay_domain.lng b/interface/web/mail/lib/lang/el_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..6f6d698afacc6ea1070411cfc3a309f7012b42fc
--- /dev/null
+++ b/interface/web/mail/lib/lang/el_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Ενεργό';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Το όνομα domain δεν είναι έγκυρο/';
+$wb['domain_error_empty'] = 'Το Domain είναι άδειο.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/el_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/el_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..49e51052d156d81a93688a388194fd4257e99dcc
--- /dev/null
+++ b/interface/web/mail/lib/lang/el_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Ενεργός';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'πρόσβαση';
diff --git a/interface/web/mail/lib/lang/en_mail_relay_domain.lng b/interface/web/mail/lib/lang/en_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e5296a9a9bba1dea5a068c7cef8187e5d4e51a4f
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Active';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/en_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/en_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e33b3bde4b1d93aca533bc9d806d4fe34e08dded
--- /dev/null
+++ b/interface/web/mail/lib/lang/en_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Active';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/es_mail_relay_domain.lng b/interface/web/mail/lib/lang/es_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..848775dd2a892087f89beabd1c796ed344fcf0d2
--- /dev/null
+++ b/interface/web/mail/lib/lang/es_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Servidor';
+$wb['active_txt'] = 'Habilitado';
+$wb['domain_txt'] = 'Dominio';
+$wb['domain_error_regex'] = 'Nombre de dominio inválido.';
+$wb['domain_error_empty'] = 'El dominio está vacío.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/es_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/es_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..bb4c57042e80e5222c993ab39abef27f4ce01440
--- /dev/null
+++ b/interface/web/mail/lib/lang/es_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Habilitado';
+$wb['server_id_txt'] = 'Servidor';
+$wb['domain_txt'] = 'Dominio';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'acceso';
diff --git a/interface/web/mail/lib/lang/fi_mail_relay_domain.lng b/interface/web/mail/lib/lang/fi_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..37afab76cec7d2aef0b4fc91740bb130f303aa7d
--- /dev/null
+++ b/interface/web/mail/lib/lang/fi_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Palvelin';
+$wb['active_txt'] = 'Toiminnassa';
+$wb['domain_txt'] = 'Postiverkkotunnus';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/fi_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/fi_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..d43c485da6b8b0308a8fd59cfdfb4983513d64c9
--- /dev/null
+++ b/interface/web/mail/lib/lang/fi_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Toiminnassa';
+$wb['server_id_txt'] = 'Palvelin';
+$wb['domain_txt'] = 'Postiverkkotunnus';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'yhteys';
diff --git a/interface/web/mail/lib/lang/fr_mail_relay_domain.lng b/interface/web/mail/lib/lang/fr_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..b6e9d8f2fbc31cb5774d3bfc99e8b949c7f26de3
--- /dev/null
+++ b/interface/web/mail/lib/lang/fr_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Serveur';
+$wb['active_txt'] = 'Actif';
+$wb['domain_txt'] = 'Domaine';
+$wb['domain_error_regex'] = 'Nom de domaine invalide.';
+$wb['domain_error_empty'] = 'Le domain est vide.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/fr_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/fr_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..771b9619745c862e78ca540c91b546a5ab76df36
--- /dev/null
+++ b/interface/web/mail/lib/lang/fr_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Actif';
+$wb['server_id_txt'] = 'Serveur';
+$wb['domain_txt'] = 'Domaine';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'accès';
diff --git a/interface/web/mail/lib/lang/hr_mail_relay_domain.lng b/interface/web/mail/lib/lang/hr_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..c0d40b147cdd4b24fc9ffe87a6ab3cd0adc25954
--- /dev/null
+++ b/interface/web/mail/lib/lang/hr_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktivno';
+$wb['domain_txt'] = 'Domena';
+$wb['domain_error_regex'] = 'Neispravan naziv domene.';
+$wb['domain_error_empty'] = 'Domena je prazna.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/hr_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/hr_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..43f29ed453845c81bb91afb739524b8352c24cde
--- /dev/null
+++ b/interface/web/mail/lib/lang/hr_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktivno';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domena';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'pristup';
diff --git a/interface/web/mail/lib/lang/hu_mail_relay_domain.lng b/interface/web/mail/lib/lang/hu_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..0ad225ad5551d04f1e4facde8e0d07ab5157b246
--- /dev/null
+++ b/interface/web/mail/lib/lang/hu_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Szerver';
+$wb['active_txt'] = 'Aktív';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/hu_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/hu_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..286b7e5e9c24cb177d3ddc3a5881ac48e7cb6573
--- /dev/null
+++ b/interface/web/mail/lib/lang/hu_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktív';
+$wb['server_id_txt'] = 'Szerver';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/id_mail_relay_domain.lng b/interface/web/mail/lib/lang/id_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..042ebf0f628cad64f0b587506da7cd6ecabc548c
--- /dev/null
+++ b/interface/web/mail/lib/lang/id_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktif';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/id_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/id_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..3d632507c4d279517619759441c0e7ed4a72a92c
--- /dev/null
+++ b/interface/web/mail/lib/lang/id_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktif';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'Akses';
diff --git a/interface/web/mail/lib/lang/it_mail_relay_domain.lng b/interface/web/mail/lib/lang/it_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e5ea20d1005c5c4d159e519357235d148ea6b094
--- /dev/null
+++ b/interface/web/mail/lib/lang/it_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Attivo';
+$wb['domain_txt'] = 'Dominio';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain  vuoto.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/it_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/it_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..96f997fe6eccb41d99012fe80d25d8a318b9e412
--- /dev/null
+++ b/interface/web/mail/lib/lang/it_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Attivo';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Dominio';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/ja_mail_relay_domain.lng b/interface/web/mail/lib/lang/ja_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..ea66b94551477cee7f882d8f2f73f45a101f62e7
--- /dev/null
+++ b/interface/web/mail/lib/lang/ja_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Active';
+$wb['domain_txt'] = 'ドメイン';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/ja_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/ja_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..dceb86ee842b3839df4ad16b312435058ac504d1
--- /dev/null
+++ b/interface/web/mail/lib/lang/ja_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Active';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'ドメイン';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/nl_mail_relay_domain.lng b/interface/web/mail/lib/lang/nl_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e76ed68a5d2cb1eefbb8864f743b7986b5cf2cdd
--- /dev/null
+++ b/interface/web/mail/lib/lang/nl_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Actief';
+$wb['domain_txt'] = 'Domein';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/nl_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/nl_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..d25076fc2567ca61740ec68f5bb573bdabf8f8e3
--- /dev/null
+++ b/interface/web/mail/lib/lang/nl_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Actief';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domein';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'toegang';
diff --git a/interface/web/mail/lib/lang/pl_mail_relay_domain.lng b/interface/web/mail/lib/lang/pl_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..dc872f9242acd57a5d5eb8b8bad63465133c819b
--- /dev/null
+++ b/interface/web/mail/lib/lang/pl_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Serwer';
+$wb['active_txt'] = 'Aktywny';
+$wb['domain_txt'] = 'Domena';
+$wb['domain_error_regex'] = 'Nieprawidłowa nazwa domeny.';
+$wb['domain_error_empty'] = 'Domena jest pusta.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/pl_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/pl_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..2de57c6d2256732d3456ff0ef3e46a8152fe621c
--- /dev/null
+++ b/interface/web/mail/lib/lang/pl_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktywne';
+$wb['server_id_txt'] = 'Serwer';
+$wb['domain_txt'] = 'Domena';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'dostęp';
diff --git a/interface/web/mail/lib/lang/pt_mail_relay_domain.lng b/interface/web/mail/lib/lang/pt_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..a775995cde1f972e2487952c91cc92ca883dfce6
--- /dev/null
+++ b/interface/web/mail/lib/lang/pt_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Servidor';
+$wb['active_txt'] = 'Activo';
+$wb['domain_txt'] = 'Domínio';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/pt_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/pt_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..50b5422a17c4bd05274493c81154901223c48618
--- /dev/null
+++ b/interface/web/mail/lib/lang/pt_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Activo';
+$wb['server_id_txt'] = 'Servidor';
+$wb['domain_txt'] = 'Domínio';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'acesso';
diff --git a/interface/web/mail/lib/lang/ro_mail_relay_domain.lng b/interface/web/mail/lib/lang/ro_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e5296a9a9bba1dea5a068c7cef8187e5d4e51a4f
--- /dev/null
+++ b/interface/web/mail/lib/lang/ro_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Active';
+$wb['domain_txt'] = 'Domain';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/ro_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/ro_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..e33b3bde4b1d93aca533bc9d806d4fe34e08dded
--- /dev/null
+++ b/interface/web/mail/lib/lang/ro_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Active';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domain';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/ru_mail_relay_domain.lng b/interface/web/mail/lib/lang/ru_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..a80c439da8c5aaee5d26fd174da9879c48d3384d
--- /dev/null
+++ b/interface/web/mail/lib/lang/ru_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Сервер';
+$wb['active_txt'] = 'Активно';
+$wb['domain_txt'] = 'Домен';
+$wb['domain_error_regex'] = 'Некорректное имя домена.';
+$wb['domain_error_empty'] = 'Домен пустой.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/ru_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/ru_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..87705b7fd393ffcb99ba24510841a1b62fd5aa90
--- /dev/null
+++ b/interface/web/mail/lib/lang/ru_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Активно';
+$wb['server_id_txt'] = 'Сервер';
+$wb['domain_txt'] = 'Домен';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'доступ';
diff --git a/interface/web/mail/lib/lang/se_mail_relay_domain.lng b/interface/web/mail/lib/lang/se_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..d1890449c420b0557aec76ff0af7c8a5d7737064
--- /dev/null
+++ b/interface/web/mail/lib/lang/se_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Aktiv';
+$wb['domain_txt'] = 'Domän';
+$wb['domain_error_regex'] = 'Ogiltigt domännamn.';
+$wb['domain_error_empty'] = 'Domänfältet är tomt.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/se_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/se_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..a3f53e633f323c2e5085235c79d99e01e9ac2cce
--- /dev/null
+++ b/interface/web/mail/lib/lang/se_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Aktiv';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Domän';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'Ã¥tkomst';
diff --git a/interface/web/mail/lib/lang/sk_mail_relay_domain.lng b/interface/web/mail/lib/lang/sk_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..f63a9fd66302b0d7c2613703e9dd22a1a8cca1c4
--- /dev/null
+++ b/interface/web/mail/lib/lang/sk_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Server';
+$wb['active_txt'] = 'Active';
+$wb['domain_txt'] = 'Doména';
+$wb['domain_error_regex'] = 'Invalid domain name.';
+$wb['domain_error_empty'] = 'Domain is empty.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/sk_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/sk_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..2dbfd76db6ae199817e906c6be409394fd4a0b48
--- /dev/null
+++ b/interface/web/mail/lib/lang/sk_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Active';
+$wb['server_id_txt'] = 'Server';
+$wb['domain_txt'] = 'Doména';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'access';
diff --git a/interface/web/mail/lib/lang/tr_mail_relay_domain.lng b/interface/web/mail/lib/lang/tr_mail_relay_domain.lng
new file mode 100644
index 0000000000000000000000000000000000000000..cd4b38cf2a0db2cae791b8919d3f935657c398f4
--- /dev/null
+++ b/interface/web/mail/lib/lang/tr_mail_relay_domain.lng
@@ -0,0 +1,9 @@
+<?php
+$wb['mail_relay_domain_title'] = 'Email relay domain';
+$wb['tab_relay_domain_title'] = 'Relay domain';
+$wb['server_id_txt'] = 'Sunucu';
+$wb['active_txt'] = 'Etkin';
+$wb['domain_txt'] = 'Etki Alanı';
+$wb['domain_error_regex'] = 'Etki alanı geçersiz.';
+$wb['domain_error_empty'] = 'Etki alanı boş olamaz.';
+$wb['domain_error_unique'] = 'This Domain already exists as a mail relay domain on this server.';
diff --git a/interface/web/mail/lib/lang/tr_mail_relay_domain_list.lng b/interface/web/mail/lib/lang/tr_mail_relay_domain_list.lng
new file mode 100644
index 0000000000000000000000000000000000000000..eb93ca7e439cd5f8757bd4c873208ef5ffaaf88e
--- /dev/null
+++ b/interface/web/mail/lib/lang/tr_mail_relay_domain_list.lng
@@ -0,0 +1,7 @@
+<?php
+$wb['list_head_txt'] = 'Relay domains';
+$wb['active_txt'] = 'Etkin';
+$wb['server_id_txt'] = 'Sunucu';
+$wb['domain_txt'] = 'Etki Alanı';
+$wb['add_new_record_txt'] = 'Add new relay domain';
+$wb['access_txt'] = 'EriÅŸim';
diff --git a/interface/web/mail/lib/module.conf.php b/interface/web/mail/lib/module.conf.php
index 05910e6c461c160289857e75e83e619f5ef6ca2f..39fd5c36bbe01f9d6312f25d8a50b83ce916952a 100644
--- a/interface/web/mail/lib/module.conf.php
+++ b/interface/web/mail/lib/module.conf.php
@@ -73,7 +73,6 @@ if(! $app->auth->is_admin() && $app->auth->get_client_limit($userid, 'mail_wblis
 		'target'  => 'content',
 		'link'     => 'mail/mail_blacklist_list.php',
 		'html_id' => 'mail_blacklist_list');
-}
 
 if($app->auth->get_client_limit($userid, 'mailrouting') != 0)
 {
@@ -83,6 +82,8 @@ if($app->auth->get_client_limit($userid, 'mailrouting') != 0)
 		'html_id' => 'mail_transport_list');
 }
 
+}
+
 if(count($items) && $app->system->has_service($userid, 'mail'))
 {
 	$module['nav'][] = array( 'title' => 'Email Accounts',
@@ -242,14 +243,25 @@ if($app->auth->is_admin())
 		'html_id' => 'mail_content_filter_list');
 
 
+	$items[] = array( 'title'  => 'Email Routing',
+		'target'  => 'content',
+		'link' => 'mail/mail_transport_list.php',
+		'html_id' => 'mail_transport_list');
+
+
+	$items[] = array(   'title'  => 'Relay Domains',
+		'target'  => 'content',
+		'link'     => 'mail/mail_relay_domain_list.php',
+		'html_id' => 'mail_relay_domain_list');
+
+
 	$items[] = array(   'title'  => 'Relay Recipients',
 		'target'  => 'content',
 		'link'     => 'mail/mail_relay_recipient_list.php',
 		'html_id' => 'mail_relay_recipient_list');
 
 
-	$module['nav'][] = array( 'title' => 'Global Filters',
+	$module['nav'][] = array( 'title' => 'Server Settings',
 		'open'  => 1,
 		'items' => $items);
 }
-?>
diff --git a/interface/web/mail/list/mail_relay_domain.list.php b/interface/web/mail/list/mail_relay_domain.list.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6ff7834824de4c4e703bc876b48971e3ea2afa1
--- /dev/null
+++ b/interface/web/mail/list/mail_relay_domain.list.php
@@ -0,0 +1,111 @@
+<?php
+
+/*
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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.
+*/
+
+
+// Name of the list
+$liste["name"]     = "mail_relay_domain";
+
+// Database table
+$liste["table"]    = "mail_relay_domain";
+
+// Index index field of the database table
+$liste["table_idx"]   = "relay_domain_id";
+
+// Search Field Prefix
+$liste["search_prefix"]  = "search_";
+
+// Records per page
+$liste["records_per_page"]  = "15";
+
+// Script File of the list
+$liste["file"]    = "mail_relay_domain_list.php";
+
+// Script file of the edit form
+$liste["edit_file"]   = "mail_relay_domain_edit.php";
+
+// Script File of the delete script
+$liste["delete_file"]  = "mail_relay_domain_del.php";
+
+// Paging Template
+$liste["paging_tpl"]  = "templates/paging.tpl.htm";
+
+// Enable auth
+$liste["auth"]    = "yes";
+
+
+/*****************************************************
+ * Search fields
+ *****************************************************/
+
+/*
+	Datatypes:
+	- INTEGER
+	- DOUBLE
+	- CURRENCY
+	- VARCHAR
+	- TEXT
+	- DATE
+*/
+
+
+$liste["item"][] = array( 'field'  => "active",
+	'datatype' => "VARCHAR",
+	'formtype' => "SELECT",
+	'op'  => "=",
+	'prefix' => "",
+	'suffix' => "",
+	'width'  => "",
+	'value'  => array('y' => $app->lng('yes_txt'), 'n' => $app->lng('no_txt')));
+
+
+$liste["item"][] = array( 'field'  => "server_id",
+	'datatype' => "VARCHAR",
+	'formtype' => "SELECT",
+	'op'  => "like",
+	'prefix' => "%",
+	'suffix' => "%",
+	'datasource' => array (  'type' => 'SQL',
+		'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} AND mirror_server_id = 0 ORDER BY server_name',
+		'keyfield'=> 'server_id',
+		'valuefield'=> 'server_name'
+	),
+	'width'  => "",
+	'value'  => "");
+
+
+$liste["item"][] = array( 'field'  => "domain",
+	'datatype' => "VARCHAR",
+	'formtype' => "TEXT",
+	'op'  => "like",
+	'prefix' => "%",
+	'suffix' => "%",
+	'width'  => "",
+	'value'  => "");
+
diff --git a/interface/web/mail/mail_relay_domain_del.php b/interface/web/mail/mail_relay_domain_del.php
new file mode 100644
index 0000000000000000000000000000000000000000..2981d1518d2a62287fed9aa3e68fc169b48e95b0
--- /dev/null
+++ b/interface/web/mail/mail_relay_domain_del.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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.
+*/
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/mail_relay_domain.list.php";
+$tform_def_file = "form/mail_relay_domain.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->auth->check_module_permissions('mail');
+
+$app->uses("tform_actions");
+$app->tform_actions->onDelete();
+
diff --git a/interface/web/mail/mail_relay_domain_edit.php b/interface/web/mail/mail_relay_domain_edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..131b6fe06af73f19a00eed5bc9e2f43b3352683e
--- /dev/null
+++ b/interface/web/mail/mail_relay_domain_edit.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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.
+*/
+
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$tform_def_file = "form/mail_relay_domain.tform.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+//* Check permissions for module
+$app->auth->check_module_permissions('mail');
+
+//* Only administrators allowed
+if(! $app->auth->is_admin()) { die( $app->lng("non_admin_error") ); }
+
+// Loading classes
+$app->uses('tpl,tform,tform_actions');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+
+	function onSubmit() {
+		global $app, $conf;
+
+		//* make sure that the email domain is lowercase
+		if(isset($this->dataRecord["domain"])){
+			$this->dataRecord["domain"] = $app->functions->idn_encode($this->dataRecord["domain"]);
+			$this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]);
+		}
+
+		//* server_id must be > 0
+		if(isset($this->dataRecord["server_id"]) && $this->dataRecord["server_id"] < 1) {
+			$app->tform->errorMessage .= $app->lng("server_id_0_error_txt");
+		}
+
+		parent::onSubmit();
+	}
+
+}
+
+$app->tform_actions = new page_action;
+$app->tform_actions->onLoad();
+
diff --git a/interface/web/mail/mail_relay_domain_list.php b/interface/web/mail/mail_relay_domain_list.php
new file mode 100644
index 0000000000000000000000000000000000000000..56812b75805b5875695b703744d28fc6dbbffc42
--- /dev/null
+++ b/interface/web/mail/mail_relay_domain_list.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+Copyright (c) 2021, Jesse Norell <jesse@kci.net>
+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.
+*/
+
+require_once '../../lib/config.inc.php';
+require_once '../../lib/app.inc.php';
+
+/******************************************
+* Begin Form configuration
+******************************************/
+
+$list_def_file = "list/mail_relay_domain.list.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+//* Check permissions for module
+$app->auth->check_module_permissions('mail');
+
+$app->uses('listform_actions');
+
+$app->listform_actions->onLoad();
+
+
diff --git a/interface/web/mail/templates/mail_relay_domain_edit.htm b/interface/web/mail/templates/mail_relay_domain_edit.htm
new file mode 100644
index 0000000000000000000000000000000000000000..2d4d1f304164726292ad760f8511bdbf38add15a
--- /dev/null
+++ b/interface/web/mail/templates/mail_relay_domain_edit.htm
@@ -0,0 +1,26 @@
+        <div class="form-group">
+            <label for="server_id" class="col-sm-3 control-label">{tmpl_var name='server_id_txt'}</label>
+            <div class="col-sm-9">
+                <select name="server_id" id="server_id" class="form-control">
+                    {tmpl_var name='server_id'}
+                </select>
+            </div>
+        </div>
+        <div class="form-group">
+            <label for="domain" class="col-sm-3 control-label">{tmpl_var name='domain_txt'}</label>
+            <div class="col-sm-9"><input type="text" name="domain" id="domain" value="{tmpl_var name='domain'}" class="form-control" /></div>
+        </div>
+        <div class="form-group">
+            <label class="col-sm-3 control-label">{tmpl_var name='active_txt'}</label>
+            <div class="col-sm-9">
+                {tmpl_var name='active'}
+            </div>
+        </div>
+
+        <input type="hidden" name="id" value="{tmpl_var name='id'}">
+        <input type="hidden" name="access" value="OK">
+
+        <div class="clear"><div class="right">
+            <button class="btn btn-default formbutton-success" type="button" value="{tmpl_var name='btn_save_txt'}" data-submit-form="pageForm" data-form-action="mail/mail_relay_domain_edit.php">{tmpl_var name='btn_save_txt'}</button>
+            <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="mail/mail_relay_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
+        </div></div>
diff --git a/interface/web/mail/templates/mail_relay_domain_list.htm b/interface/web/mail/templates/mail_relay_domain_list.htm
new file mode 100644
index 0000000000000000000000000000000000000000..4bc201a77b706fe6356f264c10be974b79d8a829
--- /dev/null
+++ b/interface/web/mail/templates/mail_relay_domain_list.htm
@@ -0,0 +1,68 @@
+        <div class='page-header'>
+            <h1><tmpl_var name="list_head_txt"></h1>
+        </div>
+
+        <tmpl_if name='datalog_changes_count' op='>' value='0'>
+        <div>
+            <div class="systemmonitor-state state-info">
+                <div class="status"></div>
+                <div class="statusMsg">
+                    {tmpl_var name="datalog_changes_txt"}
+                    <ul>
+                    <tmpl_loop name="datalog_changes">
+                        <li><strong>{tmpl_var name="text"}:</strong> {tmpl_var name="count"}</li>
+                    </tmpl_loop>
+                    </ul>
+                    {tmpl_var name="datalog_changes_end_txt"}
+                </div>
+            </div><br />
+        </div>
+        </tmpl_if>
+        <p class="fieldset-legend">{tmpl_var name="toolsarea_head_txt"}</p>
+
+        <button class="btn btn-default formbutton-success" type="button" data-load-content="mail/mail_relay_domain_edit.php">{tmpl_var name="add_new_record_txt"}</button>
+
+        <p class="fieldset-legend"><tmpl_var name="list_head_txt"></p>
+            <div class="table-wrapper marginTop15">
+<table class="table">
+                <thead class="dark form-group-sm">
+                    <tr>
+                        <th class="tiny-col" data-column="active"><tmpl_var name="active_txt"></th>
+                        <th data-column="server_id"><tmpl_var name="server_id_txt"></th>
+                        <th data-column="domain"><tmpl_var name="domain_txt"></th>
+                        <th class="small-col text-right">{tmpl_var name='search_limit'}</th>
+                    </tr>
+                    <tr>
+                        <td><select class="form-control" name="search_active">{tmpl_var name='search_active'}</select></td>
+                        <td><select class="form-control" name="search_server_id">{tmpl_var name='search_server_id'}</select></td>
+                        <td><input class="form-control" type="text" name="search_domain" value="{tmpl_var name='search_domain'}" /></td>
+                        <td class="text-right">
+                            <button type="button" class="btn btn-default formbutton-default formbutton-narrow" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" data-submit-form="pageForm" data-form-action="mail/mail_relay_domain_list.php"><span class="icon icon-filter"></span></button>
+                        </td>
+                    </tr>
+                </thead>
+                <tbody>
+                    <tmpl_loop name="records">
+                        <tr>
+                            <td><a href="#" data-load-content="mail/mail_relay_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="active"}</a></td>
+                            <td><a href="#" data-load-content="mail/mail_relay_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="server_id"}</a></td>
+                            <td><a href="#" data-load-content="mail/mail_relay_domain_edit.php?id={tmpl_var name='id'}">{tmpl_var name="domain"}</a></td>
+                            <td class="text-right">
+                                <a class="btn btn-default formbutton-danger formbutton-narrow" href="javascript: ISPConfig.confirm_action('mail/mail_relay_domain_del.php?id={tmpl_var name='id'}&_csrf_id={tmpl_var name='csrf_id'}&_csrf_key={tmpl_var name='csrf_key'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span class="icon icon-delete"></span></a>
+                            </td>
+                        </tr>
+                    </tmpl_loop>
+                    <tmpl_unless name="records">
+                        <tr class="tbl_row_noresults tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+                            <td colspan="4">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+                        </tr>
+                    </tmpl_unless>
+                </tbody>
+                <tfoot>
+                    <tr>
+                        <td colspan="4"><tmpl_var name="paging"></td>
+                    </tr>
+                </tfoot>
+            </table>
+</div>
+
diff --git a/server/conf/index/standard_index.html_sk b/server/conf/index/standard_index.html_sk
new file mode 100644
index 0000000000000000000000000000000000000000..d6edcdeb9f3c73ab85f1292b8d4a320ad8b6fafe
--- /dev/null
+++ b/server/conf/index/standard_index.html_sk
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>Vitajte!</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <link rel="shortcut icon" href="/favicon.ico" />
+    <meta name="robots" content="noindex" />
+	<style type="text/css"><!--
+    body {
+        color: #444444;
+        background-color: #EEEEEE;
+        font-family: 'Trebuchet MS', sans-serif;
+        font-size: 80%;
+    }
+    h1 {}
+    h2 { font-size: 1.2em; }
+    #page{
+        background-color: #FFFFFF;
+        width: 60%;
+        margin: 24px auto;
+        padding: 12px;
+    }
+    #header{
+        padding: 6px ;
+        text-align: center;
+    }
+    .header{ background-color: #83A342; color: #FFFFFF; }
+    #content {
+        padding: 4px 0 24px 0;
+    }
+    #footer {
+        color: #666666;
+        background: #f9f9f9;
+        padding: 10px 20px;
+        border-top: 5px #efefef solid;
+        font-size: 0.8em;
+        text-align: center;
+    }
+    #footer a {
+        color: #999999;
+    }
+    --></style>
+</head>
+<body>
+    <div id="page">
+        <div id="header" class="header">
+            <h1>Vitajte na <!--ADRESSE//-->Vašej webstránke!<!--ADRESSE//--></h1>
+        </div>
+        <div id="content">
+            <h2>Toto je štandardná stránka Vašej webstránky.</h2>
+            <p>Môžete ju bez obáv vymazať alebo nahradiť iným súborom. Toto je súbor <b>index.html</b> v adresári <b>web</b>.</p>
+            <p>Ak máte akékoľvek otázky kontaktujte <!--SUPPORT//-->podporu<!--SUPPORT//-->.</p>
+        </div>
+        <div id="footer">
+            <p>Powered by <a href="https://www.ispconfig.org">ISPConfig</a></p>
+        </div>
+    </div>
+</body>
+</html>
diff --git a/server/conf/index/user_standard_index.html_sk b/server/conf/index/user_standard_index.html_sk
new file mode 100644
index 0000000000000000000000000000000000000000..36e8e90db844d24a0c23767ec25b1260f249e9ea
--- /dev/null
+++ b/server/conf/index/user_standard_index.html_sk
@@ -0,0 +1,60 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+    <title>Vitajte!</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <link rel="shortcut icon" href="/favicon.ico" />
+    <meta name="robots" content="noindex" />
+	<style type="text/css"><!--
+    body {
+        color: #444444;
+        background-color: #EEEEEE;
+        font-family: 'Trebuchet MS', sans-serif;
+        font-size: 80%;
+    }
+    h1 {}
+    h2 { font-size: 1.2em; }
+    #page{
+        background-color: #FFFFFF;
+        width: 60%;
+        margin: 24px auto;
+        padding: 12px;
+    }
+    #header{
+        padding: 6px ;
+        text-align: center;
+    }
+    .header{ background-color: #83A342; color: #FFFFFF; }
+    #content {
+        padding: 4px 0 24px 0;
+    }
+    #footer {
+        color: #666666;
+        background: #f9f9f9;
+        padding: 10px 20px;
+        border-top: 5px #efefef solid;
+        font-size: 0.8em;
+        text-align: center;
+    }
+    #footer a {
+        color: #999999;
+    }
+    --></style>
+</head>
+<body>
+    <div id="page">
+        <div id="header" class="header">
+            <h1>Vitajte na <!--ADRESSE//-->Vašej webstránke!<!--ADRESSE//--></h1>
+        </div>
+        <div id="content">
+            <h2>Toto je štandardná stránka Vašej webstránky <b>{USER_USERNAME}</b></h2>
+            <p>Môžete ju bez obáv vymazať alebo nahradiť iným súborom. Toto je súbor <b>index.html</b> v adresári <b>user/{USER_USERNAME}/web</b>.</p>
+            <p>Ak máte akékoľvek otázky kontaktujte <!--SUPPORT//-->podporu<!--SUPPORT//-->.</p>
+        </div>
+        <div id="footer">
+            <p>Powered by <a href="https://www.ispconfig.org">ISPConfig</a></p>
+        </div>
+    </div>
+</body>
+</html>
diff --git a/server/conf/mail/db_quota_notification_sk.txt b/server/conf/mail/db_quota_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c90c9854073801c943ef39ced9d6b37f6bb18273
--- /dev/null
+++ b/server/conf/mail/db_quota_notification_sk.txt
@@ -0,0 +1,13 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Upozornenie na veľkosť databázy
+
+Databáza {database_name} je blízko alebo prekročila limit veľkosti.
+
+Databáza:			{database_name}
+Využité miesto:		{used}
+Limit:				{quota}
+Percento využitia:	{ratio}
diff --git a/server/conf/mail/db_quota_ok_notification_sk.txt b/server/conf/mail/db_quota_ok_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..10dc74ca811fc443c222a336799efb96dc8ba111
--- /dev/null
+++ b/server/conf/mail/db_quota_ok_notification_sk.txt
@@ -0,0 +1,13 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Veľkosť databázy ok
+
+Databáza {database_name} už nie je blízko ani neprekračuje limit veľkosti.
+
+Databáza:			{database_name}
+Využité miesto:		{used}
+Limit:				{quota}
+Percento využitia:	{ratio}
diff --git a/server/conf/mail/mail_quota_notification_sk.txt b/server/conf/mail/mail_quota_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f9abcab03a3785ffa99b2b27eb210984774fac65
--- /dev/null
+++ b/server/conf/mail/mail_quota_notification_sk.txt
@@ -0,0 +1,14 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Upozornenie na veľkosť poštovej schránky
+
+Poštová schránka {email} je blízko alebo prekročila limit veľkosti.
+
+Poštová schránka:		{email}
+Meno:					{name}
+Využité miesto:			{used}
+Limit:					{quota}
+Percento využitia:		{ratio}
diff --git a/server/conf/mail/mail_quota_ok_notification_sk.txt b/server/conf/mail/mail_quota_ok_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1750a5ecd51902bd0da6d5cf04174de4bbd712b7
--- /dev/null
+++ b/server/conf/mail/mail_quota_ok_notification_sk.txt
@@ -0,0 +1,14 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Veľkosť poštovej schránky ok
+
+Poštová schránka {email} už nie je blízko ani neprekračuje limit veľkosti.
+
+Poštová schránka:		{email}
+Meno:					{name}
+Využité miesto:			{used}
+Limit:					{quota}
+Percento využitia:		{ratio}
diff --git a/server/conf/mail/web_quota_notification_sk.txt b/server/conf/mail/web_quota_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..62a73a7404f44e22853fd1422f589fb3858947e0
--- /dev/null
+++ b/server/conf/mail/web_quota_notification_sk.txt
@@ -0,0 +1,14 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Upozornenie na veľkosť webstránky
+
+Webstránka {domain} je blízko alebo prekročila limit veľkosti.
+
+Doména: 				{domain}
+Využité miesto:			{used}
+Mäkký limit:			{soft}
+Tvrdý limit:			{hard}
+Percento využitia:		{ratio}
diff --git a/server/conf/mail/web_quota_ok_notification_sk.txt b/server/conf/mail/web_quota_ok_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..88f36432a0bfbd669cfce24e441ed724a9d7c895
--- /dev/null
+++ b/server/conf/mail/web_quota_ok_notification_sk.txt
@@ -0,0 +1,14 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Veľkosť webstránky ok
+
+Webstránka {domain} už nie je blízko ani neprekračuje limit veľkosti.
+
+Doména: 				{domain}
+Využité miesto:			{used}
+Mäkký limit:			{soft}
+Tvrdý limit:			{hard}
+Percento využitia:		{ratio}
diff --git a/server/conf/mail/web_traffic_notification_sk.txt b/server/conf/mail/web_traffic_notification_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8cac0e96138e92e3ed0520054cbc631c6d7ada77
--- /dev/null
+++ b/server/conf/mail/web_traffic_notification_sk.txt
@@ -0,0 +1,8 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Upozornenie na dátovú premávku webstránky
+
+Webstránka {domain} prekročila limit dátovej premávky a bola zablokovaná.
diff --git a/server/conf/mail/web_traffic_notification_warn_sk.txt b/server/conf/mail/web_traffic_notification_warn_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7f83616a5e14472a03509e8839b915456301c212
--- /dev/null
+++ b/server/conf/mail/web_traffic_notification_warn_sk.txt
@@ -0,0 +1,8 @@
+MIME-Version: 1.0
+Content-type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 8bit
+From: {admin_mail}
+Reply-To: {admin_mail}
+Subject: Upozornenie na dátovú premávku webstránky
+
+Webstránka {domain} prekročila limit dátovej premávky.
diff --git a/server/conf/mail/welcome_email_sk.txt b/server/conf/mail/welcome_email_sk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..98f6d8ecc668519608bdcd7c7b216e334531b6d4
--- /dev/null
+++ b/server/conf/mail/welcome_email_sk.txt
@@ -0,0 +1,4 @@
+From: {admin_name} <{admin_mail}>
+Subject: Vitajte vo Vašej novej emailovej schránke.
+
+Vitajte vo Vašej novej emailovej schránke. Váš správca.
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index 0b432f2bf4de7b9c5418462f8a12ff6f523763bb..a1873eab84033afbc75776924ac7414962aeef6a 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -517,8 +517,12 @@
 		RewriteCond %{REQUEST_URI} !^/php-fcgi/
 		RewriteCond %{REQUEST_URI} !^<tmpl_var name='rewrite_target'>
 </tmpl_if>
+<tmpl_if name='use_proxy_protocol' op='==' value='y'>
+<tmpl_if name='ssl_enabled'>
 <tmpl_if name="rewrite_target_is_ssl" op="==" value="y">
 		SSLProxyEngine On
+</tmpl_if>
+</tmpl_if>
 </tmpl_if>
 
 		RewriteRule   ^/(.*)$ <tmpl_var name='rewrite_target'><tmpl_if name="rewrite_add_path" op="==" value="y">$1</tmpl_if>  <tmpl_var name='rewrite_type'>
diff --git a/server/lib/classes/cron.d/300-quota_notify.inc.php b/server/lib/classes/cron.d/300-quota_notify.inc.php
index 5e1bb922767e395569a045e394c3b65b555c1445..ac7ae0aa5c70fab9c8e539145f558c950d174563 100644
--- a/server/lib/classes/cron.d/300-quota_notify.inc.php
+++ b/server/lib/classes/cron.d/300-quota_notify.inc.php
@@ -210,8 +210,8 @@ class cronjob_quota_notify extends cronjob {
 						$rec['hard'] .= ' KB';
 					}
 
-					// send notifications only if 90% or more of the quota are used
-					if($used_ratio < 0.9) {
+					// send notifications only if the website is over the quota threshold
+					if($used_ratio <= $web_config['overquota_notify_threshold'] / 100) {
 						// reset notification date
 						if($rec['last_quota_notification']) $app->dbmaster->datalogUpdate('web_domain', array("last_quota_notification" => null), 'domain_id', $rec['domain_id']);
 
@@ -339,8 +339,8 @@ class cronjob_quota_notify extends cronjob {
 						$rec['used'] = round($rec['used'] / 1048576, 4).' MB';
 					}
 
-					// send notifications only if 90% or more of the quota are used
-					if($used_ratio < 0.9) {
+					// send notifications only if the mail account is over the quota threshold
+					if($used_ratio <= $mail_config['overquota_notify_threshold'] / 100) {
 						// reset notification date
 						if($rec['last_quota_notification']) $app->dbmaster->datalogUpdate('mail_user', array("last_quota_notification" => null), 'mailuser_id', $rec['mailuser_id']);
 
@@ -455,8 +455,8 @@ class cronjob_quota_notify extends cronjob {
 								if ($quota > 0) $used_ratio = $monitor['size'] / $quota;
 								else $used_ratio = 0;
 
-								//* send notifications only if 90% or more of the quota are used
-								if($used_ratio > 0.9 && $used_ratio != 0) {
+								//* send notifications only if the database is over the quota threshold
+								if($used_ratio >= $web_config['overquota_db_notify_threshold'] / 100 && $used_ratio != 0) {
 
 									//* could a notification be sent?
 									$send_notification = false;
diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php
index 76b358237961017fa919783ef3a779943bd38509..49fd043aff42a89753e81e28196d618468b18fbe 100644
--- a/server/plugins-available/bind_plugin.inc.php
+++ b/server/plugins-available/bind_plugin.inc.php
@@ -328,10 +328,15 @@ class bind_plugin {
 			$filename = $dns_config['bind_zonefiles_dir'].'/' . $this->zone_file_prefix() . str_replace("/", "_", substr($zone['origin'], 0, -1));
 
 			$old_zonefile = @file_get_contents($filename);
-			file_put_contents($filename, $tpl->grab());
+			$rendered_zone = $tpl->grab();
+			file_put_contents($filename, $rendered_zone);
+
 			chown($filename, $dns_config['bind_user']);
 			chgrp($filename, $dns_config['bind_group']);
 
+			// Store also in the db for exports.
+			$app->dbmaster->query("UPDATE `dns_soa` SET `rendered_zone`=? WHERE id=?", $rendered_zone, $zone['id']);
+
 			//* Check the zonefile
 			if(is_file($filename.'.err')) unlink($filename.'.err');
 			$app->system->exec_safe('named-checkzone ? ?', $zone['origin'], $filename);
diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php
index a8ef21447dd8d673bc77a1645716c4dafb00029f..be81fb62a46c64baf21a94a8d9763fa0b2afea95 100644
--- a/server/plugins-available/postfix_server_plugin.inc.php
+++ b/server/plugins-available/postfix_server_plugin.inc.php
@@ -72,6 +72,12 @@ class postfix_server_plugin {
 		global $app, $conf;
 		$postfix_restart = false;
 
+		// Plugin should only run on mail servers
+		if(! $data['new']['mail_server']) {
+			$app->log("postfix_server_plugin: plugin is enabled but this server is not configured as a mail server.", LOGLEVEL_WARN);
+			return false;
+		}
+
 		// get the config
 		$app->uses("getconf,system");
 		$old_ini_data = $app->ini_parser->parse_ini_string($data['old']['config']);
@@ -326,7 +332,9 @@ class postfix_server_plugin {
 			}
 		}
 
-		$quoted_postfix_config_dir = preg_quote($conf['postfix']['config_dir'], '|');
+		$config_dir = exec("postconf -h config_directory");
+		$quoted_postfix_config_dir = preg_quote($config_dir, '|');
+
 		$new_options = array();
 		$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
 		foreach ($options as $key => $value) {
@@ -337,10 +345,14 @@ class postfix_server_plugin {
 			}
 			$new_options[] = $value;
 		}
-		if (defined($configure_lmtp) && $configure_lmtp && $mail_config['content_filter'] == 'amavisd') {
+		if (isset($configure_lmtp) && $configure_lmtp && $mail_config['content_filter'] == 'amavisd') {
 			for ($i = 0; isset($new_options[$i]); $i++) {
 				if ($new_options[$i] == 'reject_unlisted_recipient') {
 					array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${quoted_postfix_config_dir}/mysql-verify_recipients.cf"));
+
+					$app->system->exec_safe("postconf -e ?", 'address_verify_virtual_transport = smtp:[127.0.0.1]:10025');
+					$app->system->exec_safe("postconf -e ?", 'address_verify_transport_maps = static:smtp:[127.0.0.1]:10025');
+
 					break;
 				}
 			}
@@ -351,62 +363,64 @@ class postfix_server_plugin {
 		}
 		exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
 
-		if($mail_config['content_filter'] != $old_ini_data['mail']['content_filter']) {
-			$rslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_sender_login_mismatch," : "";
-			$raslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_authenticated_sender_login_mismatch," : "";
-
-			if($mail_config['content_filter'] == 'rspamd'){
-				exec("postconf -X 'receive_override_options'");
-				exec("postconf -X 'content_filter'");
-
-				exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
-				exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
-				exec("postconf -e 'milter_protocol = 6'");
-				exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
-				exec("postconf -e 'milter_default_action = accept'");
+		$rslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_sender_login_mismatch," : "";
+		$raslm = ($mail_config['reject_sender_login_mismatch'] == 'y') ? "reject_authenticated_sender_login_mismatch," : "";
 
-				exec("postconf -e 'smtpd_sender_restrictions = ${raslm} permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender'");
+		if($mail_config['content_filter'] == 'rspamd'){
+			exec("postconf -X 'receive_override_options'");
+			exec("postconf -X 'content_filter'");
+			exec("postconf -X address_verify_virtual_transport");
+			exec("postconf -X address_verify_transport_maps");
 
+			exec("postconf -e 'smtpd_milters = inet:localhost:11332'");
+			exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'");
+			exec("postconf -e 'milter_protocol = 6'");
+			exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'");
+			exec("postconf -e 'milter_default_action = accept'");
 
-				$new_options = array();
-				$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
-				foreach ($options as $key => $value) {
-					$value = trim($value);
-					if ($value == '') continue;
-					if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
-						continue;
-					}
-					$new_options[] = $value;
-				}
-				exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
+			exec("postconf -e 'smtpd_sender_restrictions = ${raslm} permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender'");
 
-				// get all domains that have dkim enabled
-				if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
-					$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
+			$new_options = array();
+			$options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions"));
+			foreach ($options as $key => $value) {
+				$value = trim($value);
+				if ($value == '') continue;
+				if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
+					continue;
 				}
-				$dkim_domains = $app->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
-				$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
-				$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
-				foreach($dkim_domains as $dkim_domain) {
-					fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
-					fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
+				if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_postfix_config_dir}/mysql-verify_recipients.cf|", $value)) {
+					continue;
 				}
-				fclose($fpp);
-				fclose($fps);
-				unset($dkim_domains);
-			} else {
-				exec("postconf -X 'smtpd_milters'");
-				exec("postconf -X 'non_smtpd_milters'");
-				exec("postconf -X 'milter_protocol'");
-				exec("postconf -X 'milter_mail_macros'");
-				exec("postconf -X 'milter_default_action'");
-
-				exec("postconf -e 'receive_override_options = no_address_mappings'");
-				exec("postconf -e 'content_filter = " . ($configure_lmtp ? "lmtp" : "amavis" ) . ":[127.0.0.1]:10024'");
+				$new_options[] = $value;
+			}
+			exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'");
 
-				// fixme: should read this from conf templates
-				exec("postconf -e 'smtpd_sender_restrictions = ${raslm} check_sender_access regexp:/etc/postfix/tag_as_originating.re, permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:/etc/postfix/tag_as_foreign.re'");
+			// get all domains that have dkim enabled
+			if ( substr($mail_config['dkim_path'], strlen($mail_config['dkim_path'])-1) == '/' ) {
+				$mail_config['dkim_path'] = substr($mail_config['dkim_path'], 0, strlen($mail_config['dkim_path'])-1);
+			}
+			$dkim_domains = $app->db->queryAllRecords('SELECT `dkim_selector`, `domain` FROM `mail_domain` WHERE `dkim` = ? ORDER BY `domain` ASC', 'y');
+			$fpp = fopen('/etc/rspamd/local.d/dkim_domains.map', 'w');
+			$fps = fopen('/etc/rspamd/local.d/dkim_selectors.map', 'w');
+			foreach($dkim_domains as $dkim_domain) {
+				fwrite($fpp, $dkim_domain['domain'] . ' ' . $mail_config['dkim_path'] . '/' . $dkim_domain['domain'] . '.private' . "\n");
+				fwrite($fps, $dkim_domain['domain'] . ' ' . $dkim_domain['dkim_selector'] . "\n");
 			}
+			fclose($fpp);
+			fclose($fps);
+			unset($dkim_domains);
+		} else {
+			exec("postconf -X 'smtpd_milters'");
+			exec("postconf -X 'non_smtpd_milters'");
+			exec("postconf -X 'milter_protocol'");
+			exec("postconf -X 'milter_mail_macros'");
+			exec("postconf -X 'milter_default_action'");
+
+			exec("postconf -e 'receive_override_options = no_address_mappings'");
+			exec("postconf -e 'content_filter = " . ($configure_lmtp ? "lmtp" : "amavis" ) . ":[127.0.0.1]:10024'");
+
+			// fixme: should read this from conf templates
+			exec("postconf -e 'smtpd_sender_restrictions = ${raslm} check_sender_access regexp:/etc/postfix/tag_as_originating.re, permit_mynetworks, check_sender_access proxy:mysql:/etc/postfix/mysql-virtual_sender.cf, ${rslm} permit_sasl_authenticated, reject_non_fqdn_sender, reject_unlisted_sender, check_sender_access regexp:/etc/postfix/tag_as_foreign.re'");
 		}
 
 		if($mail_config['content_filter'] == 'rspamd' && ($mail_config['rspamd_password'] != $old_ini_data['mail']['rspamd_password'] || $mail_config['content_filter'] != $old_ini_data['mail']['content_filter'])) {
diff --git a/server/plugins-available/shelluser_base_plugin.inc.php b/server/plugins-available/shelluser_base_plugin.inc.php
index f9a316d90e195e6e35a68eceba8b67744c08a837..2fc4f0dfc7cdc0b657825dbdfe51fbb299794b53 100755
--- a/server/plugins-available/shelluser_base_plugin.inc.php
+++ b/server/plugins-available/shelluser_base_plugin.inc.php
@@ -168,6 +168,11 @@ class shelluser_base_plugin {
 				$app->system->chown($homedir.'/.profile', $data['new']['username']);
 				$app->system->chgrp($homedir.'/.profile', $data['new']['pgroup']);
 
+				// Create symlinks for conveniance, SFTP user should not land in an empty dir.
+				symlink('../../web', $homedir.'/web');
+				symlink('../../log', $homedir.'/log');
+				symlink('../../private', $homedir.'/private');
+
 				//* Disable shell user temporarily if we use jailkit
 				if($data['new']['chroot'] == 'jailkit') {
 					$command = 'usermod -s /bin/false -L ? 2>/dev/null';
diff --git a/server/scripts/letsencrypt_renew_hook.sh b/server/scripts/letsencrypt_renew_hook.sh
index 63100ed6503808bd5d34c5d42ecf153197251b35..5ec9912f59d87728b83cf0fcd233b78146d2f456 100644
--- a/server/scripts/letsencrypt_renew_hook.sh
+++ b/server/scripts/letsencrypt_renew_hook.sh
@@ -36,15 +36,15 @@ if [ -d "$lelive" ]; then
     pureftpdpem=/etc/ssl/private/pure-ftpd.pem; if [ -e "$pureftpdpem" ]; then chmod 600 $pureftpdpem; fi
     # For Red Hat, Centos or derivatives
     if which yum &> /dev/null 2>&1 ; then
-        if [ rpm -q pure-ftpd ]; then service pure-ftpd restart; fi
-        if [ rpm -q monit ]; then service monit restart; fi
-        if [ rpm -q postfix ]; then service postfix restart; fi
-        if [ rpm -q dovecot ]; then service dovecot restart; fi
-        if [ rpm -q mysql-server ]; then service mysqld restart; fi
-        if [ rpm -q mariadb-server ]; then service mariadb restart; fi
-        if [ rpm -q MariaDB-server ]; then service mysql restart; fi
-        if [ rpm -q nginx ]; then service nginx restart; fi
-        if [ rpm -q httpd ]; then service httpd restart; fi
+        if ( rpm -q pure-ftpd ); then service pure-ftpd restart; fi
+        if ( rpm -q monit ); then service monit restart; fi
+        if ( rpm -q postfix ); then service postfix restart; fi
+        if ( rpm -q dovecot ); then service dovecot restart; fi
+        if ( rpm -q mysql-server ); then service mysqld restart; fi
+        if ( rpm -q mariadb-server ); then service mariadb restart; fi
+        if ( rpm -q MariaDB-server ); then service mysql restart; fi
+        if ( rpm -q nginx ); then service nginx restart; fi
+        if ( rpm -q httpd ); then service httpd restart; fi
     # For Debian, Ubuntu or derivatives
     elif apt-get -v >/dev/null 2>&1 ; then
         if [ $(dpkg-query -W -f='${Status}' pure-ftpd-mysql 2>/dev/null | grep -c "ok installed") -eq 1 ]; then service pure-ftpd-mysql restart; fi