From 2d7d9eaa5acda62f1580bc09304ce85a7f7cea9f Mon Sep 17 00:00:00 2001
From: Dominik <info@profi-webdesign.net>
Date: Thu, 23 Jan 2014 13:40:54 -0500
Subject: [PATCH] Merge remote-tracking branch 'ispc3master/master' into vhostalias

---
 interface/web/admin/templates/server_config_web_edit.htm                          |    4 
 install/dist/lib/fedora.lib.php                                                   |    2 
 interface/web/client/lib/lang/hu.lng                                              |    3 
 interface/web/client/templates/message_template.htm                               |   39 +
 interface/web/mail/mail_user_edit.php                                             |    4 
 interface/web/client/templates/client_edit_address.htm                            |    1 
 server/plugins-available/apps_vhost_plugin.inc.php                                |   39 
 interface/web/client/lib/lang/en_client.lng                                       |    2 
 install/sql/incremental/upd_0055.sql                                              |    2 
 interface/web/client/templates/domain_list.htm                                    |    6 
 server/conf/vhost.conf.master                                                     |   54 +
 interface/web/client/lib/lang/en_client_message_template.lng                      |   11 
 install/lib/installer_base.lib.php                                                |    9 
 interface/web/client/lib/lang/en_client_message_template_list.lng                 |    5 
 install/sql/ispconfig3.sql                                                        |   33 +
 server/lib/classes/tpl.inc.php                                                    |   85 +-
 server/plugins-available/apache2_plugin.inc.php                                   |    7 
 interface/web/client/lib/lang/sk.lng                                              |    3 
 interface/lib/classes/remoting.inc.php                                            |   26 
 interface/web/client/lib/lang/en_client_template.lng                              |    2 
 interface/web/client/lib/lang/en_client_template_list.lng                         |    2 
 install/sql/incremental/upd_0052.sql                                              |    4 
 interface/lib/classes/ispcmail.inc.php                                            |    1 
 interface/web/client/message_template_del.php                                     |   58 +
 server/conf/apache_apps.vhost.master                                              |   44 
 interface/web/client/form/message_template.tform.php                              |  108 +++
 interface/web/client/lib/module.conf.php                                          |   25 
 interface/web/admin/lib/remote.conf.php                                           |    1 
 interface/web/client/lib/lang/hr.lng                                              |    3 
 install/sql/incremental/upd_0064.sql                                              |    2 
 interface/web/client/domain_edit.php                                              |    9 
 interface/web/client/lib/lang/br.lng                                              |    3 
 interface/web/client/lib/lang/ja.lng                                              |    3 
 interface/web/client/lib/lang/ro.lng                                              |    3 
 interface/web/client/lib/lang/nl.lng                                              |    3 
 interface/web/themes/default-304/templates/sites/web_vhost_subdomain_advanced.htm |    4 
 install/sql/incremental/upd_0063.sql                                              |   21 
 interface/lib/classes/custom_datasource.inc.php                                   |    2 
 interface/lib/classes/tform_base.inc.php                                          |    1 
 interface/web/client/form/reseller.tform.php                                      |   14 
 interface/web/client/lib/lang/es.lng                                              |    3 
 interface/web/client/templates/reseller_edit_address.htm                          |    1 
 interface/web/sites/templates/web_domain_advanced.htm                             |   12 
 interface/web/client/lib/lang/pl.lng                                              |    3 
 interface/web/client/lib/lang/fi.lng                                              |    3 
 interface/web/client/lib/lang/id.lng                                              |    3 
 interface/web/client/lib/lang/bg.lng                                              |    3 
 interface/web/client/lib/lang/en_reseller.lng                                     |    4 
 interface/web/sites/database_edit.php                                             |   42 +
 interface/web/admin/form/server_config.tform.php                                  |    6 
 interface/web/client/lib/lang/el.lng                                              |    3 
 interface/web/client/message_template_list.php                                    |   53 +
 interface/web/themes/default-304/templates/sites/web_vhost_subdomain_stats.htm    |    4 
 interface/web/client/client_edit.php                                              |  134 ++++
 install/lib/install.lib.php                                                       |   17 
 interface/lib/classes/tpl.inc.php                                                 |  109 +-
 interface/web/admin/lib/lang/en_users.lng                                         |    1 
 interface/web/client/templates/reseller_edit_limits.htm                           |   94 ++
 interface/web/client/client_message.php                                           |    2 
 server/plugins-available/mail_plugin.inc.php                                      |   26 
 install/sql/incremental/upd_0065.sql                                              |    7 
 interface/web/client/lib/lang/pt.lng                                              |    3 
 interface/web/client/lib/lang/ar.lng                                              |    3 
 interface/web/client/templates/client_template_edit_limits.htm                    |   15 
 server/lib/classes/system.inc.php                                                 |   29 
 interface/lib/classes/remote.d/admin.inc.php                                      |  109 +++
 interface/web/client/reseller_edit.php                                            |  104 +++
 interface/web/themes/default-304/templates/sites/web_vhost_subdomain_backup.htm   |    4 
 interface/web/client/lib/lang/ru.lng                                              |    3 
 interface/web/client/templates/client_edit_limits.htm                             |   17 
 server/conf/apache_ispconfig.conf.master                                          |   65 +
 interface/web/client/lib/lang/de.lng                                              |    3 
 interface/web/client/lib/lang/tr.lng                                              |    3 
 install/dist/lib/gentoo.lib.php                                                   |    2 
 install/dist/lib/opensuse.lib.php                                                 |    2 
 interface/web/client/lib/lang/en.lng                                              |    3 
 interface/web/themes/default-304/templates/sites/web_vhost_subdomain_ssl.htm      |    4 
 interface/web/sites/web_domain_edit.php                                           |   22 
 interface/web/admin/users_edit.php                                                |    7 
 interface/web/client/client_template_edit.php                                     |   13 
 interface/lib/classes/remote.d/mail.inc.php                                       |    4 
 install/sql/incremental/upd_0049.sql                                              |    1 
 interface/lib/classes/client_templates.inc.php                                    |    4 
 interface/web/client/list/message_template.list.php                               |   77 ++
 interface/web/themes/default-304/templates/sites/web_vhost_subdomain_redirect.htm |    4 
 interface/web/client/lib/lang/cz.lng                                              |    3 
 server/plugins-available/maildeliver_plugin.inc.php                               |    3 
 interface/web/client/form/client_template.tform.php                               |   14 
 interface/web/client/message_template_edit.php                                    |   99 +++
 install/dist/lib/debian60.lib.php                                                 |    2 
 interface/web/client/lib/lang/se.lng                                              |    3 
 interface/web/client/templates/message_template_list.htm                          |   52 +
 interface/web/client/lib/lang/fr.lng                                              |    3 
 interface/web/client/templates/client_message_template_list.htm                   |   57 +
 94 files changed, 1,620 insertions(+), 295 deletions(-)

diff --git a/install/dist/lib/debian60.lib.php b/install/dist/lib/debian60.lib.php
index b3887cb..d792c5a 100644
--- a/install/dist/lib/debian60.lib.php
+++ b/install/dist/lib/debian60.lib.php
@@ -57,7 +57,7 @@
 		// Adding the amavisd commands to the postfix configuration
 		$postconf_commands = array (
 			'dovecot_destination_recipient_limit = 1',
-			'virtual_transport = dovecot',
+			'virtual_transport = lmtp:unix:private/dovecot-lmtp',
 			'smtpd_sasl_type = dovecot',
 			'smtpd_sasl_path = private/auth'
 		);
diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php
index ab25741..628f012 100644
--- a/install/dist/lib/fedora.lib.php
+++ b/install/dist/lib/fedora.lib.php
@@ -402,7 +402,7 @@
 		// Adding the amavisd commands to the postfix configuration
 		$postconf_commands = array (
 			'dovecot_destination_recipient_limit = 1',
-			'virtual_transport = dovecot',
+			'virtual_transport = lmtp:unix:private/dovecot-lmtp',
 			'smtpd_sasl_type = dovecot',
 			'smtpd_sasl_path = private/auth',
 			'receive_override_options = no_address_mappings'
diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php
index 99670ee..7078f83 100644
--- a/install/dist/lib/gentoo.lib.php
+++ b/install/dist/lib/gentoo.lib.php
@@ -245,7 +245,7 @@
 		//* Reconfigure postfix to use dovecot authentication
 		$postconf_commands = array (
 			'dovecot_destination_recipient_limit = 1',
-			'virtual_transport = dovecot',
+			'virtual_transport = lmtp:unix:private/dovecot-lmtp',
 			'smtpd_sasl_type = dovecot',
 			'smtpd_sasl_path = private/auth'
 		);
diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php
index 7663f7e..9ec6bcf 100644
--- a/install/dist/lib/opensuse.lib.php
+++ b/install/dist/lib/opensuse.lib.php
@@ -437,7 +437,7 @@
 		// Adding the amavisd commands to the postfix configuration
 		$postconf_commands = array (
 			'dovecot_destination_recipient_limit = 1',
-			'virtual_transport = dovecot',
+			'virtual_transport = lmtp:unix:private/dovecot-lmtp',
 			'smtpd_sasl_type = dovecot',
 			'smtpd_sasl_path = private/auth',
 			'receive_override_options = no_address_mappings'
diff --git a/install/lib/install.lib.php b/install/lib/install.lib.php
index eac79e9..501cf3b 100644
--- a/install/lib/install.lib.php
+++ b/install/lib/install.lib.php
@@ -666,6 +666,23 @@
 	}
 }
 
+function hasLine($filename, $search_pattern, $strict = 0) {
+	if($lines = @file($filename)) {
+		foreach($lines as $line) {
+			if($strict == 0) {
+				if(stristr($line, $search_pattern)) {
+					return true;
+				}
+			} else {
+				if(trim($line) == $search_pattern) {
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
 function is_installed($appname) {
 	exec('which '.escapeshellcmd($appname).' 2> /dev/null', $out, $returncode);
 	if(isset($out[0]) && stristr($out[0], $appname) && $returncode == 0) {
diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index ab0c963..cdb0a53 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -1247,6 +1247,15 @@
 			replaceLine('/etc/apache2/ports.conf', 'Listen 443', 'Listen 443', 1);
 		}
 
+		if(is_file('/etc/apache2/apache.conf')) {
+			if(hasLine('/etc/apache2/apache.conf', 'Include sites-enabled/', 1) == false) {
+				if(hasLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.conf', 1) == false) {
+					replaceLine('/etc/apache2/apache.conf', 'Include sites-enabled/', 'Include sites-enabled/', 1, 1);
+				} elseif(hasLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.vhost', 1) == false) {
+					replaceLine('/etc/apache2/apache.conf', 'IncludeOptional sites-enabled/*.vhost', 'IncludeOptional sites-enabled/*.vhost', 1, 1);
+				}
+			}
+		}
 
 		//* Copy the ISPConfig configuration include
 		$vhost_conf_dir = $conf['apache']['vhost_conf_dir'];
diff --git a/install/sql/incremental/upd_0049.sql b/install/sql/incremental/upd_0049.sql
index d37d1a5..7cfe112 100644
--- a/install/sql/incremental/upd_0049.sql
+++ b/install/sql/incremental/upd_0049.sql
@@ -1,2 +1 @@
 ALTER TABLE `client_template` CHANGE `limit_aps` `limit_aps` INT( 11 ) NOT NULL DEFAULT '-1';
-ALTER TABLE `web_backup` ADD `filesize` VARCHAR(10) NOT NULL AFTER `filename`;
diff --git a/install/sql/incremental/upd_0052.sql b/install/sql/incremental/upd_0052.sql
index 5f4a1b6..a25f7a7 100644
--- a/install/sql/incremental/upd_0052.sql
+++ b/install/sql/incremental/upd_0052.sql
@@ -1,5 +1 @@
-ALTER TABLE `client_template` CHANGE `limit_aps` `limit_aps` INT( 11 ) NOT NULL DEFAULT '-1';
-ALTER TABLE `mail_domain` ADD `dkim_public` MEDIUMTEXT NOT NULL AFTER `domain`;
-ALTER TABLE `mail_domain` ADD `dkim_private` MEDIUMTEXT NOT NULL AFTER `domain`;
-ALTER TABLE `mail_domain` ADD `dkim` ENUM( 'n', 'y' ) NOT NULL AFTER `domain`;
 ALTER TABLE `client` ADD `default_slave_dnsserver` INT( 11 ) UNSIGNED NOT NULL DEFAULT '1' AFTER `limit_dns_zone`;
diff --git a/install/sql/incremental/upd_0055.sql b/install/sql/incremental/upd_0055.sql
index 3a7c5d5..6d1a56f 100644
--- a/install/sql/incremental/upd_0055.sql
+++ b/install/sql/incremental/upd_0055.sql
@@ -1,3 +1 @@
-ALTER TABLE `web_backup` CHANGE `backup_type` `backup_type` enum('web','mongodb','mysql') NOT NULL DEFAULT 'web';
-ALTER TABLE `web_database_user` ADD `database_password_mongo` varchar(32) DEFAULT NULL AFTER `database_password`;
 ALTER TABLE `sys_datalog` ADD `error` MEDIUMTEXT NULL DEFAULT NULL;
diff --git a/install/sql/incremental/upd_0063.sql b/install/sql/incremental/upd_0063.sql
index 827fdee..04e1daa 100644
--- a/install/sql/incremental/upd_0063.sql
+++ b/install/sql/incremental/upd_0063.sql
@@ -1 +1,20 @@
-ALTER TABLE `mail_user` ADD `disablelmtp` ENUM( 'n', 'y' ) NOT NULL DEFAULT 'n' AFTER `disablelda` ;
\ No newline at end of file
+ALTER TABLE `client` ADD `limit_domainmodule` INT NOT NULL DEFAULT '0';
+ALTER TABLE `client_template` ADD `limit_domainmodule` INT NOT NULL DEFAULT '0';
+CREATE TABLE `client_message_template` (
+  `client_message_template_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,
+  `template_type` varchar(255) DEFAULT NULL,
+  `template_name` varchar(255) DEFAULT NULL,
+  `subject` varchar(255) DEFAULT NULL,
+  `message` text,
+  PRIMARY KEY (`client_message_template_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+ALTER TABLE  `spamfilter_policy` ADD  `policyd_quota_in` int(11) NOT NULL DEFAULT  '-1',
+ADD  `policyd_quota_in_period` int(11) NOT NULL DEFAULT  '24',
+ADD  `policyd_quota_out` int(11) NOT NULL DEFAULT  '-1',
+ADD  `policyd_quota_out_period` int(11) NOT NULL DEFAULT  '24',
+ADD  `policyd_greylist` ENUM(  'Y',  'N' ) NOT NULL DEFAULT  'N';
\ No newline at end of file
diff --git a/install/sql/incremental/upd_0064.sql b/install/sql/incremental/upd_0064.sql
new file mode 100644
index 0000000..23bdd26
--- /dev/null
+++ b/install/sql/incremental/upd_0064.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `mail_user` ADD `disablelmtp` ENUM( 'n', 'y' ) NOT NULL DEFAULT 'n' AFTER `disablelda` ;
+ALTER TABLE `mail_user` CHANGE `uid` `uid` INT( 11 ) NOT NULL DEFAULT '5000', CHANGE `gid` `gid` INT( 11 ) NOT NULL DEFAULT '5000' ;
\ No newline at end of file
diff --git a/install/sql/incremental/upd_0065.sql b/install/sql/incremental/upd_0065.sql
new file mode 100644
index 0000000..ccc790c
--- /dev/null
+++ b/install/sql/incremental/upd_0065.sql
@@ -0,0 +1,7 @@
+ALTER TABLE `web_backup` ADD `filesize` VARCHAR(10) NOT NULL AFTER `filename`;
+ALTER TABLE `client_template` CHANGE `limit_aps` `limit_aps` INT( 11 ) NOT NULL DEFAULT '-1';
+ALTER TABLE `mail_domain` ADD `dkim_public` MEDIUMTEXT NOT NULL AFTER `domain`;
+ALTER TABLE `mail_domain` ADD `dkim_private` MEDIUMTEXT NOT NULL AFTER `domain`;
+ALTER TABLE `mail_domain` ADD `dkim` ENUM( 'n', 'y' ) NOT NULL AFTER `domain`;
+ALTER TABLE `web_backup` CHANGE `backup_type` `backup_type` enum('web','mysql','mongodb') NOT NULL DEFAULT 'web';
+ALTER TABLE `web_database_user` ADD `database_password_mongo` varchar(32) DEFAULT NULL AFTER `database_password`;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 4841b1a..81a4cf3 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -219,6 +219,7 @@
   `limit_cron_frequency` int(11) NOT NULL DEFAULT '5',
   `limit_traffic_quota` int(11) NOT NULL DEFAULT '-1',
   `limit_client` int(11) NOT NULL DEFAULT '0',
+  `limit_domainmodule` int(11) NOT NULL DEFAULT '0',
   `limit_mailmailinglist` int(11) NOT NULL DEFAULT '-1',
   `limit_openvz_vm` int(11) NOT NULL DEFAULT '0',
   `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0',
@@ -321,6 +322,7 @@
   `limit_cron_frequency` int(11) NOT NULL default '5',
   `limit_traffic_quota` int(11) NOT NULL default '-1',
   `limit_client` int(11) NOT NULL default '0',
+  `limit_domainmodule` int(11) NOT NULL DEFAULT '0',
   `limit_mailmailinglist` int(11) NOT NULL default '-1',
   `limit_openvz_vm` int(11) NOT NULL DEFAULT '0',
   `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0',
@@ -340,6 +342,30 @@
   PRIMARY KEY (`assigned_template_id`),
   KEY `client_id` (`client_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+-- --------------------------------------------------------
+
+--
+-- Table structure for table `invoice_message_template`
+--
+
+CREATE TABLE `client_message_template` (
+  `client_message_template_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,
+  `template_type` varchar(255) DEFAULT NULL,
+  `template_name` varchar(255) DEFAULT NULL,
+  `subject` varchar(255) DEFAULT NULL,
+  `message` text,
+  PRIMARY KEY (`client_message_template_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+--
+-- Dumping data for table `invoice_message_template`
+--
+
 -- --------------------------------------------------------
 
 --
@@ -1379,6 +1405,11 @@
   `spam_subject_tag2` varchar(64) default NULL,
   `message_size_limit` int(11) unsigned default NULL,
   `banned_rulenames` varchar(64) default NULL,
+  `policyd_quota_in` int(11) NOT NULL DEFAULT  '-1',
+  `policyd_quota_in_period` int(11) NOT NULL DEFAULT  '24',
+  `policyd_quota_out` int(11) NOT NULL DEFAULT  '-1',
+  `policyd_quota_out_period` int(11) NOT NULL DEFAULT  '24',
+  `policyd_greylist` ENUM(  'Y',  'N' ) NOT NULL DEFAULT  'N',
   PRIMARY KEY  (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
 
@@ -1699,7 +1730,7 @@
   `backup_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `server_id` int(10) unsigned NOT NULL,
   `parent_domain_id` int(10) unsigned NOT NULL,
-  `backup_type` enum('web','mongodb','mysql') NOT NULL DEFAULT 'web',
+  `backup_type` enum('web','mysql','mongodb') NOT NULL DEFAULT 'web',
   `backup_mode` varchar(64) NOT NULL DEFAULT  '',
   `tstamp` int(10) unsigned NOT NULL,
   `filename` varchar(255) NOT NULL,
diff --git a/interface/lib/classes/client_templates.inc.php b/interface/lib/classes/client_templates.inc.php
index bdf9b16..64beb9e 100644
--- a/interface/lib/classes/client_templates.inc.php
+++ b/interface/lib/classes/client_templates.inc.php
@@ -106,9 +106,10 @@
 		/*
          * Get the master-template for the client
          */
-		$sql = "SELECT template_master, template_additional FROM client WHERE client_id = " . $app->functions->intval($clientId);
+		$sql = "SELECT template_master, template_additional,limit_client FROM client WHERE client_id = " . $app->functions->intval($clientId);
 		$record = $app->db->queryOneRecord($sql);
 		$masterTemplateId = $record['template_master'];
+		$is_reseller = ($record['limit_client'] > 0)?true:false;
 
 		if($record['template_additional'] != '') {
 			// we have to call the update_client_templates function
@@ -222,6 +223,7 @@
          * Write all back to the database
          */
 		$update = '';
+		if(!$is_reseller) unset($limits['limit_client']); // Only Resellers may have limit_client set in template to ensure that we do not convert a client to reseller accidently.
 		foreach($limits as $k => $v){
 			if ((strpos($k, 'limit') !== false or $k == 'ssh_chroot' or $k == 'web_php_options' or $k == 'force_suexec') && !is_array($v)){
 				if ($update != '') $update .= ', ';
diff --git a/interface/lib/classes/custom_datasource.inc.php b/interface/lib/classes/custom_datasource.inc.php
index ff01084..16036f5 100644
--- a/interface/lib/classes/custom_datasource.inc.php
+++ b/interface/lib/classes/custom_datasource.inc.php
@@ -32,7 +32,7 @@
 
 	function master_templates($field, $record) {
 		global $app, $conf;
-		$records = $app->db->queryAllRecords("SELECT template_id,template_name FROM client_template WHERE template_type ='m'");
+		$records = $app->db->queryAllRecords("SELECT template_id,template_name FROM client_template WHERE template_type ='m' and ".$app->tform->getAuthSQL('r'));
 		$records_new[0] = $app->lng('Custom');
 		foreach($records as $rec) {
 			$key = $rec['template_id'];
diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php
index 16247ab..2e49c8d 100644
--- a/interface/lib/classes/ispcmail.inc.php
+++ b/interface/lib/classes/ispcmail.inc.php
@@ -223,6 +223,7 @@
 		elseif(isset($_SERVER['SERVER_NAME'])) $this->smtp_helo = $_SERVER['SERVER_NAME'];
 		else $this->smtp_helo = php_uname('n');
 		if($this->smtp_helo == '') $this->smtp_helo = 'localhost';
+		return $this->smtp_helo;
 	}
 
 
diff --git a/interface/lib/classes/remote.d/admin.inc.php b/interface/lib/classes/remote.d/admin.inc.php
new file mode 100644
index 0000000..ba966fe
--- /dev/null
+++ b/interface/lib/classes/remote.d/admin.inc.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+Copyright (c) 2007 - 2013, 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.
+
+--UPDATED 08.2009--
+Full SOAP support for ISPConfig 3.1.4 b
+Updated by Arkadiusz Roch & Artur Edelman
+Copyright (c) Tri-Plex technology
+
+--UPDATED 08.2013--
+Migrated into new remote classes system
+by Marius Cramer <m.cramer@pixcept.de>
+
+*/
+
+class remoting_admin extends remoting {
+	
+	/**
+	 * set record permissions in any table
+	 * @param string session_id
+	 * @param string index_field
+	 * @param string index_value
+	 * @param array permissions
+	 * @author "ispcomm", improved by M. Cramer <m.cramer@pixcept.de>
+	 */
+	public function update_record_permissions($tablename, $index_field, $index_value, $permissions) {
+		global $app;
+		
+		if(!$this->checkPerm($session_id, 'admin_record_permissions')) {
+			$this->server->fault('permission_denied', 'You do not have the permissions to access this function.');
+			return false;
+		}
+		
+		foreach($permissions as $key => $value) {  // make sure only sys_ fields are updated
+			switch($key) {
+				case 'sys_userid':
+					// check if userid is valid
+					$check = $app->db->queryOneRecord('SELECT userid FROM sys_user WHERE userid = ' . $app->functions->intval($value));
+					if(!$check || !$check['userid']) {
+						$this->server->fault('invalid parameters', $value . ' is no valid sys_userid.');
+						return false;
+					}
+					$permissions[$key] = $app->functions->intval($value);
+					break;
+				case 'sys_groupid':
+					// check if groupid is valid
+					$check = $app->db->queryOneRecord('SELECT groupid FROM sys_group WHERE groupid = ' . $app->functions->intval($value));
+					if(!$check || !$check['groupid']) {
+						$this->server->fault('invalid parameters', $value . ' is no valid sys_groupid.');
+						return false;
+					}
+					$permissions[$key] = $app->functions->intval($value);
+					break;
+				case 'sys_perm_user':
+				case 'sys_perm_group':
+					// check if permissions are valid
+					$value = strtolower($value);
+					if(!preg_match('/^[riud]+$/', $value)) {
+						$this->server->fault('invalid parameters', $value . ' is no valid permission string.');
+						return false;
+					}
+					
+					$newvalue = '';
+					if(strpos($value, 'r') !== false) $newvalue .= 'r';
+					if(strpos($value, 'i') !== false) $newvalue .= 'i';
+					if(strpos($value, 'u') !== false) $newvalue .= 'u';
+					if(strpos($value, 'd') !== false) $newvalue .= 'd';
+					$permissions[$key] = $newvalue;
+					unset($newvalue);
+					
+					break;
+				default:
+					$this->server->fault('invalid parameters', 'Only sys_userid, sys_groupid, sys_perm_user and sys_perm_group parameters can be changed with this function.');
+					break;
+			}
+		}
+		
+		return $app->db->datalogUpdate( $tablename, $permissions, $index_field, $index_value ) ;
+	}
+	
+
+}
+
+?>
diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php
index d235d01..c54466f 100644
--- a/interface/lib/classes/remote.d/mail.inc.php
+++ b/interface/lib/classes/remote.d/mail.inc.php
@@ -214,6 +214,10 @@
 			return false;
 		}
 
+		//* Set a few params to non empty values that will be overwritten by mail_plugin
+		if (!isset($params['uid'])) $params['uid'] = -1;
+		if (!isset($params['gid'])) $params['gid'] = -1;
+
 		$affected_rows = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params);
 		return $affected_rows;
 	}
diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php
index 268b257..647ba80 100644
--- a/interface/lib/classes/remoting.inc.php
+++ b/interface/lib/classes/remoting.inc.php
@@ -184,33 +184,7 @@
 		return $app->db->affectedRows() == 1;
 	}
 
-	//* Add mail domain
-	public function mail_user_add($session_id, $client_id, $params){
-		global $app;
-	
-		if (!$this->checkPerm($session_id, 'mail_user_add')){
-			$this->server->fault('permission_denied','You do not have the permissions to access this function.');
-			return false;
-		}
-	
-		//* Check if mail domain exists
-		$email_parts = explode('@',$params['email']);
-		$tmp = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain = '".$app->db->quote($email_parts[1])."'");
-		if($tmp['domain'] != $email_parts[1]) {
-			$this->server->fault('mail_domain_does_not_exist','Mail domain - '.$email_parts[1].' - does not exist.');
-			return false;
-		}
-	
-		//* Set a few params to non empty values that will be overwritten by mail_plugin
-		if (!isset($params['uid'])) $params['uid'] = 999989999;
-		if (!isset($params['gid'])) $params['gid'] = 999989999;
-	
-		$affected_rows = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params);
-		return $affected_rows;
-	}
-	
 	//** protected functions -----------------------------------------------------------------------------------
-
 
 	protected function klientadd($formdef_file, $reseller_id, $params)
 	{
diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php
index 6cfdfe0..65f10c5 100644
--- a/interface/lib/classes/tform_base.inc.php
+++ b/interface/lib/classes/tform_base.inc.php
@@ -270,6 +270,7 @@
 			unset($tmp_recordid);
 
 			$querystring = str_replace("{AUTHSQL}", $this->getAuthSQL('r'), $querystring);
+			$querystring = preg_replace_callback('@{AUTHSQL::(.+?)}@', "self::table_auth_sql", $querystring);
 
 			// Getting the records
 			$tmp_records = $app->db->queryAllRecords($querystring);
diff --git a/interface/lib/classes/tpl.inc.php b/interface/lib/classes/tpl.inc.php
index 4b411e2..a8533bb 100644
--- a/interface/lib/classes/tpl.inc.php
+++ b/interface/lib/classes/tpl.inc.php
@@ -864,7 +864,7 @@
 
 				$regex = '/(<|<\/|{|{\/|<!--|<!--\/){1}\s*';
 				$regex.= 'tmpl_([\w]+)\s*';
-				$regex.= '(?:';
+				$regex.= '((?:(?:';
 				$regex.=    '(?:';
 				$regex.=        '(name|format|escape|op|value|file)';
 				$regex.=        '\s*=\s*';
@@ -873,30 +873,10 @@
 				$regex.=    '((?<=[\"\'])';
 				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
 				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
-				$regex.= '(?:';
-				$regex.=    '(?:';
-				$regex.=        '(name|format|escape|op|value)';
-				$regex.=        '\s*=\s*';
-				$regex.=    ')';
-				$regex.=    '(?:[\"\'])?';
-				$regex.=    '((?<=[\"\'])';
-				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
-				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
-				$regex.= '(?:';
-				$regex.=    '(?:';
-				$regex.=        '(name|format|escape|op|value)';
-				$regex.=        '\s*=\s*';
-				$regex.=    ')';
-				$regex.=    '(?:[\"\'])?';
-				$regex.=    '((?<=[\"\'])';
-				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
-				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
+				$regex.= ')?\s*)*?)';
 				$regex.= '(?:>|\/>|}|-->){1}';
-				$regex.= '([\r\n|\n|\r])?/i';
-				$data = preg_replace_callback($regex, array($this, _parseTag), $data);
+				$regex.= '/i';
+				$data = preg_replace_callback($regex, array($this, '_parseTag'), $data);
 
 				if ($this->_cache) { // add cache if need be
 					$this->_createCache($data);
@@ -1026,8 +1006,7 @@
 		 * @access private
 		 * @return string used for eval'ing
 		 */
-		private function _parseIf($varname, $value = null, $op = null, $namespace = null)
-		{
+		function _parseIf ($varname, $value=null, $op=null, $namespace=null, $format=null) {
 			if (isset($namespace)) $namespace = substr($namespace, 0, -1);
 			$comp_str = ''; // used for extended if statements
 
@@ -1065,9 +1044,19 @@
 				}
 			}
 			if ($this->OPTIONS['GLOBAL_VARS'] && empty($namespace)) {
-				return '(('.$retstr.'[\''.$varname.'\'] !== null) ? '.$retstr.'[\''.$varname.'\'] : $this->_vars[\''.$varname.'\'])'.$comp_str;
-			} else {
-				return $retstr."['".$varname."']".$comp_str;
+				$retstr = '(('.$retstr.'[\''.$varname.'\'] !== null) ? '.$retstr.'[\''.$varname.'\'] : $this->_vars[\''.$varname.'\'])';
+				if(isset($format) && isset($value) && $format == 'version') {
+					return 'version_compare(' . $retstr . ', \'' . $value . '\', ' . (!empty($op) ? $op : '==') . ')';
+				} else {
+					return $retstr.$comp_str;
+				}
+			}
+			else {
+				if(isset($format) && isset($value) && $format == 'version') {
+					return 'version_compare(' . $retstr."['".$varname."']" . ', \'' . $value . '\', ' . (!empty($op) ? $op : '==') . ')';
+				} else {
+					return $retstr."['".$varname."']".$comp_str;
+				}
 			}
 		}
 
@@ -1186,28 +1175,38 @@
 			$wholetag = $args[0];
 			$openclose = $args[1];
 			$tag = strtolower($args[2]);
-			$newline = $args[9];
-
-			if ($tag == 'else') return '<?php } else { ?>'.$newline;
+			
+			if ($tag == 'else') return '<?php } else { ?>';
 			if ($tag == 'tmpl_include') return $wholetag; // ignore tmpl_include tags
 
 			if (preg_match("/^<\/|{\/|<!--\/$/s", $openclose) || preg_match("/^end[if|loop|unless|comment]$/", $tag)) {
 				if ($tag == 'loop' || $tag == 'endloop') array_pop($this->_namespace);
 				if ($tag == 'comment' || $tag == 'endcomment') {
-					return '<?php */ ?>'.$newline;
-				} else {
-					return '<?php } ?>'.$newline;
+					return '<?php */ ?>';
+				}
+				else {
+					return '<?php } ?>';
 				}
 			}
 
-			//* arrange attributes
-			for ($i=3; $i < 8; $i=($i+2)) {
-				if (empty($args[$i]) && empty($args[($i+1)])) break;
-				$key = (empty($args[$i])) ? 'name' : strtolower($args[$i]);
-				if ($key == 'name' && preg_match('/^(php)?include$/', $tag)) $key = 'file';
-				$$key = $args[($i+1)];
+			// arrange attributes
+			$tmp_atts = $args[3];
+			$atts = preg_split('/\s+/', $tmp_atts);
+			foreach($atts as $att) {
+				$regex =    '/(?:';
+				$regex.=        '(name|format|escape|op|value|file)';
+				$regex.=        '\s*=\s*';
+				$regex.=    ')?';
+				$regex.=    '(?:[\"\'])?';
+				$regex.=    '((?<=[\"\'])';
+				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
+				$regex.=    '[\"\']?/';
+				if(preg_match($regex, $att, $match)) {
+					$key = (empty($match[1])) ? 'name' : strtolower($match[1]);
+					if ($key == 'name' && preg_match('/^(php)?include$/', $tag)) $key = 'file';
+					$$key = $match[2];
+				}
 			}
-
 			$var = ($this->OPTIONS['CASELESS']) ? strtolower($name) : $name;
 
 			if ($this->_debug && !empty($var)) {
@@ -1229,37 +1228,47 @@
 				if (empty($escape) && (!empty($this->OPTIONS['DEFAULT_ESCAPE']) && strtolower($this->OPTIONS['DEFAULT_ESCAPE']) != 'none')) {
 					$escape = strtolower($this->OPTIONS['DEFAULT_ESCAPE']);
 				}
-				return '<?php '.$this->_parseVar ($wholetag, $tag, $var, @$escape, @$format, @$namespace)." ?>$newline";
+				return '<?php '.$this->_parseVar ($wholetag, $tag, $var, @$escape, @$format, @$namespace).' ?>'."\n";
+				break;
 
 			case 'if':
-				return '<?php if ('. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php if ('. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
+				break;
 
 			case 'unless':
-				return '<?php if (!'. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php if (!'. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
+				break;
 
 			case 'elseif':
-				return '<?php } elseif ('. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php } elseif ('. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
+				break;
 
 			case 'loop':
-				return '<?php '. $this->_parseLoop($var) .'?>'.$newline;
+				return '<?php '. $this->_parseLoop($var) .'?>';
+				break;
 
 			case 'comment':
 				if (empty($var)) { // full open/close style comment
-					return '<?php /* ?>'.$newline;
-				} else { // just ignore tag if it was a one line comment
+					return '<?php /* ?>';
+				}
+				else { // just ignore tag if it was a one line comment
 					return;
 				}
+				break;
 
 			case 'phpinclude':
 				if ($this->OPTIONS['ENABLE_PHPINCLUDE']) {
-					return '<?php include(\''.$file.'\'); ?>'.$newline;
+					return '<?php include(\''.$file.'\'); ?>';
 				}
+				break;
 
 			case 'include':
 				return '<?php $this->_getData($this->_fileSearch(\''.$file.'\'), 1); ?>';
+				break;
 
 			case 'dyninclude':
 				return '<?php $this->_getData($this->_fileSearch($this->_dyninclude[\''.$name.'\']), 1); ?>';
+				break;
 
 			default:
 				if ($this->OPTIONS['STRICT']) vlibTemplateError::raiseError('VT_ERROR_INVALID_TAG', KILL, htmlspecialchars($wholetag, ENT_QUOTES));
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index dde1d74..89165ec 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -368,6 +368,12 @@
 			'width' => '10',
 			'maxlength' => '255'
 		),
+		'mailbox_virtual_uidgid_maps' => array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'CHECKBOX',
+			'default' => 'n',
+			'value' => array(0 => 'n', 1 => 'y')
+		),
 		'relayhost' => array(
 			'datatype' => 'VARCHAR',
 			'formtype' => 'TEXT',
diff --git a/interface/web/admin/lib/lang/en_users.lng b/interface/web/admin/lib/lang/en_users.lng
index 9eec322..09b8ac3 100644
--- a/interface/web/admin/lib/lang/en_users.lng
+++ b/interface/web/admin/lib/lang/en_users.lng
@@ -30,4 +30,5 @@
 $wb['password_mismatch_txt'] = 'The passwords do not match.';
 $wb['password_match_txt'] = 'The passwords do match.';
 $wb['username_error_collision'] = 'The username may not be web or web plus a number."';
+$wb['client_not_admin_err'] = 'A user that belongs to a client can not be set to type: admin';
 ?>
diff --git a/interface/web/admin/lib/remote.conf.php b/interface/web/admin/lib/remote.conf.php
index 4268f47..c40e8bf 100644
--- a/interface/web/admin/lib/remote.conf.php
+++ b/interface/web/admin/lib/remote.conf.php
@@ -1,5 +1,6 @@
 <?php
 
 $function_list['server_get,get_function_list,client_templates_get_all,server_get_serverid_by_ip,server_ip_add,server_ip_update,server_ip_delete'] = 'Server functions';
+$function_list['admin_record_permissions'] = 'Record permission changes';
 
 ?>
diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm
index 89ba859..ece9d7d 100644
--- a/interface/web/admin/templates/server_config_web_edit.htm
+++ b/interface/web/admin/templates/server_config_web_edit.htm
@@ -145,11 +145,11 @@
                 </div>
                 <div class="ctrlHolder">
                     <label for="CA_path">{tmpl_var name='CA_path_txt'}</label>
-                    <input name="CA_path" id="CA_path" value="{tmpl_var name='CA_path'}" size="40" maxlength="255" type="text" class="textInput" />
+                    <input name="CA_path" id="CA_path" value="{tmpl_var name='CA_path'}" size="40" maxlength="255" type="text" autocomplete="off" class="textInput" />
                 </div>
                 <div class="ctrlHolder">
                     <label for="CA_pass">{tmpl_var name='CA_pass_txt'}</label>
-                    <input name="CA_pass" id="CA_pass" value="{tmpl_var name='CA_pass'}" size="40" maxlength="255" type="password" class="textInput" />
+                    <input name="CA_pass" id="CA_pass" value="{tmpl_var name='CA_pass'}" size="40" maxlength="255" type="password" autocomplete="off" class="textInput" />
                 </div>
             </div>
             <div class="subsectiontoggle"><span></span>{tmpl_var name='permissions_txt'}<em></em></div>
diff --git a/interface/web/admin/users_edit.php b/interface/web/admin/users_edit.php
index 5eab80a..2b1be7f 100644
--- a/interface/web/admin/users_edit.php
+++ b/interface/web/admin/users_edit.php
@@ -66,7 +66,14 @@
 		if(@is_array($this->dataRecord['modules']) && !in_array($this->dataRecord['startmodule'], $this->dataRecord['modules'])) {
 			$app->tform->errorMessage .= $app->tform->wordbook['startmodule_err'];
 		}
+		
 		$this->oldDataRecord = $app->tform->getDataRecord($this->id);
+		
+		//* A user that belongs to a client record (client or reseller) may not have typ admin
+		if(isset($this->dataRecord['typ']) && $this->dataRecord['typ'][0] == 'admin'  && $this->oldDataRecord['client_id'] > 0) {
+			$app->tform->errorMessage .= $app->tform->wordbook['client_not_admin_err'];
+		}
+		
 	}
 
 	/*
diff --git a/interface/web/client/client_edit.php b/interface/web/client/client_edit.php
index d12f39e..f731cca 100644
--- a/interface/web/client/client_edit.php
+++ b/interface/web/client/client_edit.php
@@ -92,6 +92,11 @@
 				}
 			}
 		}
+		
+		//* Resellers shall not be able to create another reseller
+		if($_SESSION["s"]["user"]["typ"] == 'user') {
+			$this->dataRecord['limit_client'] = 0;
+		}
 
 		if($this->id != 0) {
 			$this->oldTemplatesAssigned = $app->db->queryAllRecords('SELECT * FROM `client_template_assigned` WHERE `client_id` = ' . $this->id);
@@ -189,9 +194,11 @@
 					$app->tpl->setVar('customer_no',$customer_no_string);
 				
 					//* save new counter value
+					/*
 					$system_config['misc']['customer_no_counter']++;
 					$system_config_str = $app->ini_parser->get_ini_string($system_config);
 					$app->db->datalogUpdate('sys_ini', "config = '".$app->db->quote($system_config_str)."'", 'sysini_id', 1);
+					*/
 				}
 			} else {
 				//* Logged in user must be a reseller
@@ -206,10 +213,30 @@
 					$app->tpl->setVar('customer_no',$customer_no_string);
 					
 					//* save new counter value
+					/*
 					$customer_no_counter = $app->functions->intval($reseller['customer_no_counter']+1);
 					$app->db->query("UPDATE client SET customer_no_counter = $customer_no_counter WHERE client_id = ".$app->functions->intval($reseller['client_id']));
+					*/
 				}
 			}
+		}
+		
+		if($app->auth->is_admin()) {
+			// Fill the client select field
+			$sql = "SELECT client.client_id, sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 AND client.limit_client > 0 ORDER BY sys_group.name";
+			$clients = $app->db->queryAllRecords($sql);
+			$client_select = "<option value='0'>- ".$app->tform->lng('none_txt')." -</option>";
+			//$tmp_data_record = $app->tform->getDataRecord($this->id);
+			if(is_array($clients)) {
+				$selected_client_id = 0; // needed to get list of PHP versions
+				foreach($clients as $client) {
+					if(is_array($this->dataRecord) && ($client["client_id"] == $this->dataRecord['parent_client_id']) && !$selected_client_id) $selected_client_id = $client["client_id"];
+					$selected = @(is_array($this->dataRecord) && ($client["client_id"] == $this->dataRecord['parent_client_id']))?'SELECTED':'';
+					if($selected == 'SELECTED') $selected_client_id = $client["client_id"];
+					$client_select .= "<option value='$client[client_id]' $selected>$client[contactname]</option>\r\n";
+				}
+			}
+			$app->tpl->setVar("parent_client_id", $client_select);
 		}
 		
 		parent::onShowEnd();
@@ -253,6 +280,14 @@
 		if($_SESSION['s']['user']['typ'] == 'user') {
 			$app->auth->add_group_to_user($_SESSION['s']['user']['userid'], $groupid);
 			$app->db->query("UPDATE client SET parent_client_id = ".$app->functions->intval($_SESSION['s']['user']['client_id'])." WHERE client_id = ".$this->id);
+		} else {
+			if($this->dataRecord['parent_client_id'] > 0) {
+				//* get userid of the reseller and add it to the group of the client
+				$tmp = $app->db->queryOneRecord("SELECT sys_user.userid FROM sys_user,sys_group WHERE sys_user.default_group = sys_group.groupid AND sys_group.client_id = ".$app->functions->intval($this->dataRecord['parent_client_id']));
+				$app->auth->add_group_to_user($tmp['userid'], $groupid);
+				$app->db->query("UPDATE client SET parent_client_id = ".$app->functions->intval($this->dataRecord['parent_client_id'])." WHERE client_id = ".$this->id);
+				unset($tmp);
+			}
 		}
 
 		//* Set the default servers
@@ -272,6 +307,75 @@
 			$app->uses('client_templates');
 			$app->client_templates->update_client_templates($this->id, $this->_template_additional);
 		}
+		
+		if($this->dataRecord['customer_no'] == $this->dataRecord['customer_no_org']) {
+			if($app->auth->is_admin()) {
+				//* Logged in User is admin
+				//* get the system config
+				$app->uses('getconf');
+				$system_config = $app->getconf->get_global_config();
+				if($system_config['misc']['customer_no_template'] != '') {
+				
+					//* save new counter value
+					$system_config['misc']['customer_no_counter']++;
+					$system_config_str = $app->ini_parser->get_ini_string($system_config);
+					$app->db->datalogUpdate('sys_ini', "config = '".$app->db->quote($system_config_str)."'", 'sysini_id', 1);
+				}
+			} else {
+				//* Logged in user must be a reseller
+				//* get the record of the reseller
+				$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+				$reseller = $app->db->queryOneRecord("SELECT client.client_id, client.customer_no_template, client.customer_no_counter, client.customer_no_start FROM sys_group,client WHERE client.client_id = sys_group.client_id and sys_group.groupid = ".$client_group_id);
+				
+				if($reseller['customer_no_template'] != '') {
+					//* save new counter value
+					$customer_no_counter = $app->functions->intval($reseller['customer_no_counter']+1);
+					$app->db->query("UPDATE client SET customer_no_counter = $customer_no_counter WHERE client_id = ".$app->functions->intval($reseller['client_id']));
+				}
+			}
+		}
+		
+		//* Send welcome email
+		$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+		$sql = "SELECT * FROM client_message_template WHERE template_type = 'welcome' AND sys_groupid = ".$client_group_id;
+		$email_template = $app->db->queryOneRecord($sql);
+		$client = $app->tform->getDataRecord($this->id);
+
+		if(is_array($email_template) && $client['email'] != '') {
+			//* Parse client details into message
+			$message = $email_template['message'];
+			$subject = $email_template['subject'];
+			foreach($client as $key => $val) {
+				switch ($key) {
+				case 'password':
+					$message = str_replace('{password}', $this->dataRecord['password'], $message);
+					$subject = str_replace('{password}', $this->dataRecord['password'], $subject);
+					break;
+				case 'gender':
+					$message = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $message);
+					$subject = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $subject);
+					break;
+				default:
+					$message = str_replace('{'.$key.'}', $val, $message);
+					$subject = str_replace('{'.$key.'}', $val, $subject);
+				}
+			}
+			
+			//* Get sender address
+			if($app->auth->is_admin()) {
+				$app->uses('getconf');
+				$system_config = $app->getconf->get_global_config();
+				$from = $system_config['admin_mail'];
+			} else {
+				$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+				$reseller = $app->db->queryOneRecord("SELECT client.email FROM sys_group,client WHERE client.client_id = sys_group.client_id and sys_group.groupid = ".$client_group_id);
+				$from = $reseller["email"];
+			}
+
+			//* Send the email
+			$app->functions->mail($client['email'], $subject, $message, $from);
+		}
+		
 
 		parent::onAfterInsert();
 	}
@@ -412,7 +516,7 @@
 			$app->db->query($sql);
 		}
 
-		// reseller status changed
+		//* reseller status changed
 		if(isset($this->dataRecord["limit_client"]) && $this->dataRecord["limit_client"] != $this->oldDataRecord["limit_client"]) {
 			$modules = $conf['interface_modules_enabled'];
 			if($this->dataRecord["limit_client"] > 0) $modules .= ',client';
@@ -421,6 +525,34 @@
 			$sql = "UPDATE sys_user SET modules = '$modules' WHERE client_id = $client_id";
 			$app->db->query($sql);
 		}
+		
+		//* Client has been moved to another reseller
+		if($_SESSION['s']['user']['typ'] == 'admin' && isset($this->dataRecord['parent_client_id']) && $this->dataRecord['parent_client_id'] != $this->oldDataRecord['parent_client_id']) {
+			//* Get groupid of the client
+			$tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ".intval($this->id));
+			$groupid = $tmp['groupid'];
+			unset($tmp);
+			
+			//* Remove sys_user of old reseller from client group
+			if($this->oldDataRecord['parent_client_id'] > 0) {
+				//* get userid of the old reseller remove it from the group of the client
+				$tmp = $app->db->queryOneRecord("SELECT sys_user.userid FROM sys_user,sys_group WHERE sys_user.default_group = sys_group.groupid AND sys_group.client_id = ".$app->functions->intval($this->oldDataRecord['parent_client_id']));
+				$app->auth->remove_group_from_user($tmp['userid'], $groupid);
+				unset($tmp);
+			}
+			
+			//* Add sys_user of new reseller to client group
+			if($this->dataRecord['parent_client_id'] > 0) {
+				//* get userid of the reseller and add it to the group of the client
+				$tmp = $app->db->queryOneRecord("SELECT sys_user.userid, sys_user.default_group FROM sys_user,sys_group WHERE sys_user.default_group = sys_group.groupid AND sys_group.client_id = ".$app->functions->intval($this->dataRecord['parent_client_id']));
+				$app->auth->add_group_to_user($tmp['userid'], $groupid);
+				$app->db->query("UPDATE client SET sys_userid = ".$app->functions->intval($tmp['userid']).", sys_groupid = ".$app->functions->intval($tmp['default_group']).", parent_client_id = ".$app->functions->intval($this->dataRecord['parent_client_id'])." WHERE client_id = ".$this->id);
+				unset($tmp);
+			} else {
+				//* Client is not assigned to a reseller anymore, so we assign it to the admin
+				$app->db->query("UPDATE client SET sys_userid = 1, sys_groupid = 1, parent_client_id = 0 WHERE client_id = ".$this->id);
+			}
+		}
 
 		if(isset($this->dataRecord['template_master'])) {
 			$app->uses('client_templates');
diff --git a/interface/web/client/client_message.php b/interface/web/client/client_message.php
index 199fc69..5707e88 100644
--- a/interface/web/client/client_message.php
+++ b/interface/web/client/client_message.php
@@ -146,7 +146,7 @@
 
 //message variables
 $message_variables = '';
-$sql = "SHOW COLUMNS FROM client WHERE Field NOT IN ('client_id', 'sys_userid', 'sys_groupid', 'sys_perm_user', 'sys_perm_group', 'sys_perm_other', 'password', 'parent_client_id', 'id_rsa', 'ssh_rsa', 'created_at', 'default_mailserver', 'default_webserver', 'web_php_options', 'ssh_chroot', 'default_dnsserver', 'default_dbserver', 'template_master', 'template_additional') AND Field NOT LIKE 'limit_%'";
+$sql = "SHOW COLUMNS FROM client WHERE Field NOT IN ('client_id', 'sys_userid', 'sys_groupid', 'sys_perm_user', 'sys_perm_group', 'sys_perm_other', 'password', 'parent_client_id', 'id_rsa', 'ssh_rsa', 'created_at', 'default_mailserver', 'default_webserver', 'web_php_options', 'ssh_chroot', 'default_dnsserver', 'default_dbserver', 'template_master', 'template_additional', 'force_suexec', 'default_slave_dnsserver', 'usertheme', 'locked', 'canceled', 'can_use_api', 'tmp_data', 'customer_no_template', 'customer_no_start', 'customer_no_counter', 'added_date', 'added_by') AND Field NOT LIKE 'limit_%'";
 $field_names = $app->db->queryAllRecords($sql);
 if(!empty($field_names) && is_array($field_names)){
 	foreach($field_names as $field_name){
diff --git a/interface/web/client/client_template_edit.php b/interface/web/client/client_template_edit.php
index d956faf..bc5c6d2 100644
--- a/interface/web/client/client_template_edit.php
+++ b/interface/web/client/client_template_edit.php
@@ -51,6 +51,19 @@
 
 class page_action extends tform_actions {
 
+	
+	function onSubmit() {
+		global $app;
+		
+		//* Resellers shall not be able to create another reseller or set reseller specific settings
+		if($_SESSION["s"]["user"]["typ"] == 'user') {
+			$this->dataRecord['limit_client'] = 0;
+			$this->dataRecord['limit_domainmodule'] = 0;
+		}
+		
+		parent::onSubmit();
+	}
+	
 	function onBeforeUpdate() {
 		global $app;
 
diff --git a/interface/web/client/domain_edit.php b/interface/web/client/domain_edit.php
index 24a4c81..07929f9 100644
--- a/interface/web/client/domain_edit.php
+++ b/interface/web/client/domain_edit.php
@@ -52,6 +52,15 @@
 $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'.lng';
 include $lng_file;
 
+if(!$app->tform->checkClientLimit('limit_domainmodule')) {
+	$app->uses('ini_parser,getconf');
+	$settings = $app->getconf->get_global_config('domains');
+	if ($settings['use_domain_module'] == 'y') {
+		$app->error($settings['new_domain_html']);
+	}
+}
+
+
 class page_action extends tform_actions {
 
 	function onShowNew() {
diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php
index ecf61f7..f9d9f6b 100644
--- a/interface/web/client/form/client_template.tform.php
+++ b/interface/web/client/form/client_template.tform.php
@@ -101,6 +101,20 @@
 		//#################################
 		// Begin Datatable fields
 		//#################################
+		'limit_client' => array (
+			'datatype' => 'INTEGER',
+			'formtype' => 'TEXT',
+			'validators' => array (  0 => array ( 'type' => 'ISINT',
+					'errmsg'=> 'limit_client_error_notint'),
+			),
+			'default' => '1',
+			'value'  => '',
+			'separator' => '',
+			'width'  => '10',
+			'maxlength' => '10',
+			'rows'  => '',
+			'cols'  => ''
+		),
 		'limit_maildomain' => array (
 			'datatype' => 'INTEGER',
 			'formtype' => 'TEXT',
diff --git a/interface/web/client/form/message_template.tform.php b/interface/web/client/form/message_template.tform.php
new file mode 100644
index 0000000..421b1af
--- /dev/null
+++ b/interface/web/client/form/message_template.tform.php
@@ -0,0 +1,108 @@
+<?php
+
+/*
+	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"]    = "Email template";
+$form["description"]  = "";
+$form["name"]    = "client_message_template";
+$form["action"]   = "message_template_edit.php";
+$form["db_table"]  = "client_message_template";
+$form["db_table_idx"] = "client_message_template_id";
+$form["db_history"]  = "no";
+$form["tab_default"] = "template";
+$form["list_default"] = "message_template_list.php";
+$form["auth"]   = 'yes';
+
+$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"]['template'] = array (
+	'title'  => "Settings",
+	'width'  => 100,
+	'template'  => "templates/message_template.htm",
+	'fields'  => array (
+		//#################################
+		// Begin Datatable fields
+		//#################################
+		'template_type' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'SELECT',
+			'default' => '',
+			'value'  => array('welcome' => 'Default welcome email', 'other' => 'Other')
+		),
+		'template_name' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => '',
+			'value'  => '',
+			'separator' => '',
+			'width'  => '30',
+			'maxlength' => '255',
+			'rows'  => '',
+			'cols'  => ''
+		),
+		'subject' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => '',
+			'value'  => '',
+			'separator' => '',
+			'width'  => '30',
+			'maxlength' => '255',
+			'rows'  => '',
+			'cols'  => ''
+		),
+		'message' => array (
+			'datatype' => 'TEXT',
+			'formtype' => 'TEXTAREA',
+			'default' => '',
+			'value'  => '',
+			'separator' => '',
+			'width'  => '30',
+			'maxlength' => '255',
+			'rows'  => '',
+			'cols'  => ''
+		),
+		//#################################
+		// END Datatable fields
+		//#################################
+	)
+);
+
+
+
+?>
diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php
index eb74ce7..8db74b6 100644
--- a/interface/web/client/form/reseller.tform.php
+++ b/interface/web/client/form/reseller.tform.php
@@ -1203,6 +1203,20 @@
 			'width'  => '30',
 			'maxlength' => '255'
 		),
+		'limit_domainmodule' => array (
+			'datatype' => 'INTEGER',
+			'formtype' => 'TEXT',
+			'validators' => array (  0 => array ( 'type' => 'ISINT',
+					'errmsg'=> 'limit_domainmodule_error_notint'),
+			),
+			'default' => '0',
+			'value'  => '',
+			'separator' => '',
+			'width'  => '10',
+			'maxlength' => '10',
+			'rows'  => '',
+			'cols'  => ''
+		),
 		//#################################
 		// END Datatable fields
 		//#################################
diff --git a/interface/web/client/lib/lang/ar.lng b/interface/web/client/lib/lang/ar.lng
index 88e0f8f..bb03af8 100644
--- a/interface/web/client/lib/lang/ar.lng
+++ b/interface/web/client/lib/lang/ar.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Add Client';
 $wb['Edit Client'] = 'Edit Client';
 $wb['Clients'] = 'Clients';
-$wb['Edit Client-Templates'] = 'Edit Client-Templates';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Add Reseller';
 $wb['Edit Reseller'] = 'Edit Reseller';
 $wb['Resellers'] = 'Resellers';
diff --git a/interface/web/client/lib/lang/bg.lng b/interface/web/client/lib/lang/bg.lng
index e441730..836fc56 100644
--- a/interface/web/client/lib/lang/bg.lng
+++ b/interface/web/client/lib/lang/bg.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Добавяне на клиент';
 $wb['Edit Client'] = 'Редактиране на клиент';
 $wb['Clients'] = 'Клиенти';
-$wb['Edit Client-Templates'] = 'Редактирай Клиентски-Шаблон';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Добави дистрибутор';
 $wb['Edit Reseller'] = 'Редактирай дистрибутор';
 $wb['Resellers'] = 'Дистрибутори';
diff --git a/interface/web/client/lib/lang/br.lng b/interface/web/client/lib/lang/br.lng
index bb73de1..2604940 100644
--- a/interface/web/client/lib/lang/br.lng
+++ b/interface/web/client/lib/lang/br.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Adcionar Cliente';
 $wb['Edit Client'] = 'Editar Cliente';
 $wb['Clients'] = 'Clientes';
-$wb['Edit Client-Templates'] = 'Editar Gabaritos de Clientes';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Adcionar Revendedor';
 $wb['Edit Reseller'] = 'Editar Revendedor';
 $wb['Resellers'] = 'Revendedores';
diff --git a/interface/web/client/lib/lang/cz.lng b/interface/web/client/lib/lang/cz.lng
index fa1c78d..38d1ac8 100644
--- a/interface/web/client/lib/lang/cz.lng
+++ b/interface/web/client/lib/lang/cz.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Přidat klienta';
 $wb['Edit Client'] = 'Upravit klienta';
 $wb['Clients'] = 'Klienti';
-$wb['Edit Client-Templates'] = 'Upravit klientské šablony';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Přidat distributora';
 $wb['Edit Reseller'] = 'Upravit distributora';
 $wb['Resellers'] = 'Distributoři (prodejci)';
diff --git a/interface/web/client/lib/lang/de.lng b/interface/web/client/lib/lang/de.lng
index ba66401..bdff0bb 100644
--- a/interface/web/client/lib/lang/de.lng
+++ b/interface/web/client/lib/lang/de.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Kunde hinzufügen';
 $wb['Edit Client'] = 'Kunde bearbeiten';
 $wb['Clients'] = 'Kunden';
-$wb['Edit Client-Templates'] = 'Kundenvorlagen';
+$wb['Templates'] = 'Vorlagen';
+$wb['Limit-Templates'] = 'Kundenvorlagen';
 $wb['Add Reseller'] = 'Reseller hinzufügen';
 $wb['Edit Reseller'] = 'Reseller bearbeiten';
 $wb['Resellers'] = 'Reseller';
diff --git a/interface/web/client/lib/lang/el.lng b/interface/web/client/lib/lang/el.lng
index 7d4f4fa..fe70d3f 100644
--- a/interface/web/client/lib/lang/el.lng
+++ b/interface/web/client/lib/lang/el.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Νέος Πελάτης';
 $wb['Edit Client'] = 'Επεξεργασία Πελάτη';
 $wb['Clients'] = 'Πελάτες';
-$wb['Edit Client-Templates'] = 'Επεξεργασία προτύπων πελατών';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Νέος Μεταπωλητής';
 $wb['Edit Reseller'] = 'Επεξεργασία Μεταπωλητή';
 $wb['Resellers'] = 'Μεταπωλητές';
diff --git a/interface/web/client/lib/lang/en.lng b/interface/web/client/lib/lang/en.lng
index 46cdb4a..d901b7a 100644
--- a/interface/web/client/lib/lang/en.lng
+++ b/interface/web/client/lib/lang/en.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Add Client';
 $wb['Edit Client'] = 'Edit Client';
 $wb['Clients'] = 'Clients';
-$wb['Edit Client-Templates'] = 'Edit Client-Templates';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Add Reseller';
 $wb['Edit Reseller'] = 'Edit Reseller';
 $wb['Resellers'] = 'Resellers';
diff --git a/interface/web/client/lib/lang/en_client.lng b/interface/web/client/lib/lang/en_client.lng
index d4ab57a..a9565a3 100644
--- a/interface/web/client/lib/lang/en_client.lng
+++ b/interface/web/client/lib/lang/en_client.lng
@@ -170,4 +170,6 @@
 $wb['mail_servers_used'] = 'The server you are trying to remove from this client is used as a Mailserver. Be sure that this server is not used by this client before to remove it.';
 $wb['added_by_txt'] = 'Added by';
 $wb['added_date_txt'] = 'Added date';
+$wb['parent_client_id_txt'] = 'Client of reseller';
+$wb['none_txt'] = 'none';
 ?>
diff --git a/interface/web/client/lib/lang/en_client_message_template.lng b/interface/web/client/lib/lang/en_client_message_template.lng
new file mode 100644
index 0000000..e2ab2c7
--- /dev/null
+++ b/interface/web/client/lib/lang/en_client_message_template.lng
@@ -0,0 +1,11 @@
+<?php
+$wb["template_type_txt"] = 'Email type';
+$wb["template_name_txt"] = 'Template name';
+$wb["subject_txt"] = 'Subject';
+$wb["message_txt"] = 'Message';
+$wb['Email template'] = 'Email template';
+$wb['Settings'] = 'Setting';
+$wb['variables_txt'] = 'Variables';
+$wb['variables_description_txt'] = '(The username and password variables are only available in welcome emails.)';
+$wb['duplicate_welcome_error'] = 'There can be only one default welcome email template. Please edit the existing template instead of adding a new one.';
+?>
\ No newline at end of file
diff --git a/interface/web/client/lib/lang/en_client_message_template_list.lng b/interface/web/client/lib/lang/en_client_message_template_list.lng
new file mode 100644
index 0000000..7a78bf0
--- /dev/null
+++ b/interface/web/client/lib/lang/en_client_message_template_list.lng
@@ -0,0 +1,5 @@
+<?php
+$wb["list_head_txt"] = 'Email templates';
+$wb["template_type_txt"] = 'Message for';
+$wb["template_name_txt"] = 'Template name';
+?>
\ No newline at end of file
diff --git a/interface/web/client/lib/lang/en_client_template.lng b/interface/web/client/lib/lang/en_client_template.lng
index e7c06a8..0eef470 100644
--- a/interface/web/client/lib/lang/en_client_template.lng
+++ b/interface/web/client/lib/lang/en_client_template.lng
@@ -88,4 +88,6 @@
 $wb['aps_limits_txt'] = 'APS Installer Limits';
 $wb['limit_aps_txt'] = 'Max. number of APS instances';
 $wb['limit_aps_error_notint'] = 'The APS instances limit must be a number.';
+$wb['limit_domainmodule_txt'] = 'Domainmodule Limit';
+$wb['client_limits_txt'] = 'Client Limits'
 ?>
\ No newline at end of file
diff --git a/interface/web/client/lib/lang/en_client_template_list.lng b/interface/web/client/lib/lang/en_client_template_list.lng
index ce1f9bd..1906cef 100644
--- a/interface/web/client/lib/lang/en_client_template_list.lng
+++ b/interface/web/client/lib/lang/en_client_template_list.lng
@@ -1,5 +1,5 @@
 <?php
-$wb["list_head_txt"] = 'Client-Templates';
+$wb["list_head_txt"] = 'Client and Reseller Templates';
 $wb["template_type_txt"] = 'Type';
 $wb["template_name_txt"] = 'Template name';
 $wb['template_id_txt'] = 'Template ID';
diff --git a/interface/web/client/lib/lang/en_reseller.lng b/interface/web/client/lib/lang/en_reseller.lng
index c70e324..3b478e4 100644
--- a/interface/web/client/lib/lang/en_reseller.lng
+++ b/interface/web/client/lib/lang/en_reseller.lng
@@ -172,4 +172,8 @@
 $wb['customer_no_counter_txt'] = 'Customer No. counter';
 $wb['added_by_txt'] = 'Added by';
 $wb['added_date_txt'] = 'Added date';
+$wb['limit_domainmodule_error_notint'] = 'Domainmodule limit must be a number.';
+$wb['limit_domainmodule_txt'] = 'Domainmodule Limit';
+$wb['client_limits_txt'] = 'Client Limits';
+$wb['err_msg_master_tpl_set'] = 'All custom limit settings are ignored if any master template other than "custom" is selected.';
 ?>
diff --git a/interface/web/client/lib/lang/es.lng b/interface/web/client/lib/lang/es.lng
index fb636c3..da72048 100644
--- a/interface/web/client/lib/lang/es.lng
+++ b/interface/web/client/lib/lang/es.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Añadir cliente';
 $wb['Edit Client'] = 'Editar cliente';
 $wb['Clients'] = 'Clientes';
-$wb['Edit Client-Templates'] = 'Editar plantillas de clientes';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Añadir revendedor';
 $wb['Edit Reseller'] = 'Editar revendedor';
 $wb['Resellers'] = 'Revendedores';
diff --git a/interface/web/client/lib/lang/fi.lng b/interface/web/client/lib/lang/fi.lng
index 6f3dd5a..d440dfe 100755
--- a/interface/web/client/lib/lang/fi.lng
+++ b/interface/web/client/lib/lang/fi.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Lisää asiakas';
 $wb['Edit Client'] = 'Muokkaa asiakkaan tietoja';
 $wb['Clients'] = 'Asiakkaat';
-$wb['Edit Client-Templates'] = 'Muokkaa asiakasmalleja';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Lisää uusi jälleenmyyjä';
 $wb['Edit Reseller'] = 'Muokkaa jälleenmyyjää';
 $wb['Resellers'] = 'Jälleenmyyjät';
diff --git a/interface/web/client/lib/lang/fr.lng b/interface/web/client/lib/lang/fr.lng
index 8676a29..02d06df 100644
--- a/interface/web/client/lib/lang/fr.lng
+++ b/interface/web/client/lib/lang/fr.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Ajouter un Client';
 $wb['Edit Client'] = 'Editer un Client';
 $wb['Clients'] = 'Clients';
-$wb['Edit Client-Templates'] = 'Editer les modèles de Clients';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Ajouter un Revendeur';
 $wb['Edit Reseller'] = 'Editer un Revendeur';
 $wb['Resellers'] = 'Revendeurs';
diff --git a/interface/web/client/lib/lang/hr.lng b/interface/web/client/lib/lang/hr.lng
index 74e37dd..137f9bb 100644
--- a/interface/web/client/lib/lang/hr.lng
+++ b/interface/web/client/lib/lang/hr.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Dodaj klijenta';
 $wb['Edit Client'] = 'Editiraj klijenta';
 $wb['Clients'] = 'Klijenti';
-$wb['Edit Client-Templates'] = 'Editiraj predložak za klijente';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Dodaj preprodavača';
 $wb['Edit Reseller'] = 'Editiraj preprodavača';
 $wb['Resellers'] = 'Preprodavači';
diff --git a/interface/web/client/lib/lang/hu.lng b/interface/web/client/lib/lang/hu.lng
index 84311fe..84beaf5 100644
--- a/interface/web/client/lib/lang/hu.lng
+++ b/interface/web/client/lib/lang/hu.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Ügyfél hozzáadása';
 $wb['Edit Client'] = 'Ügyfél adatok szerkesztése';
 $wb['Clients'] = 'Ügyfelek';
-$wb['Edit Client-Templates'] = 'Ügyfél-Sablonok szerkesztése';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Új Viszonteladó';
 $wb['Edit Reseller'] = 'Viszonteladók szerkesztése';
 $wb['Resellers'] = 'Viszonteladók';
diff --git a/interface/web/client/lib/lang/id.lng b/interface/web/client/lib/lang/id.lng
index 280dd42..8459d16 100644
--- a/interface/web/client/lib/lang/id.lng
+++ b/interface/web/client/lib/lang/id.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Tambah Klien';
 $wb['Edit Client'] = 'Sunting Klien';
 $wb['Clients'] = 'Klien';
-$wb['Edit Client-Templates'] = 'Sunting Template Klien';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Tambah Reseller';
 $wb['Edit Reseller'] = 'Sunting Reseller';
 $wb['Resellers'] = 'Reseller';
diff --git a/interface/web/client/lib/lang/ja.lng b/interface/web/client/lib/lang/ja.lng
index 716fc07..c0c0971 100644
--- a/interface/web/client/lib/lang/ja.lng
+++ b/interface/web/client/lib/lang/ja.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'クライアントを追加する';
 $wb['Edit Client'] = 'クライアントを編集する';
 $wb['Clients'] = 'クライアント';
-$wb['Edit Client-Templates'] = 'クライアントテンプレートを編集する';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'リセラーを追加する';
 $wb['Edit Reseller'] = 'リセラーを編集する';
 $wb['Resellers'] = 'リセラー';
diff --git a/interface/web/client/lib/lang/nl.lng b/interface/web/client/lib/lang/nl.lng
index 75add75..2ebe389 100644
--- a/interface/web/client/lib/lang/nl.lng
+++ b/interface/web/client/lib/lang/nl.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Toevoegen klant';
 $wb['Edit Client'] = 'Wijzigen klant';
 $wb['Clients'] = 'klanten';
-$wb['Edit Client-Templates'] = 'Wijzig klant-template';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Toevoegen Reseller';
 $wb['Edit Reseller'] = 'Wijzigen Reseller';
 $wb['Resellers'] = 'Resellers';
diff --git a/interface/web/client/lib/lang/pl.lng b/interface/web/client/lib/lang/pl.lng
index 2727435..12dc65c 100644
--- a/interface/web/client/lib/lang/pl.lng
+++ b/interface/web/client/lib/lang/pl.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Dodaj klienta';
 $wb['Edit Client'] = 'Edytuj klienta';
 $wb['Clients'] = 'Klienci';
-$wb['Edit Client-Templates'] = 'Edytuj szablony klientów';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Dodaj Resellera';
 $wb['Edit Reseller'] = 'Edytuj Resellera';
 $wb['Resellers'] = 'Resellerzy';
diff --git a/interface/web/client/lib/lang/pt.lng b/interface/web/client/lib/lang/pt.lng
index 181ab88..cd56569 100644
--- a/interface/web/client/lib/lang/pt.lng
+++ b/interface/web/client/lib/lang/pt.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Adicionar Cliente';
 $wb['Edit Client'] = 'Editar Cliente';
 $wb['Clients'] = 'Clientes';
-$wb['Edit Client-Templates'] = 'Editar Templates de Clientes';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Adicionar Revendedor';
 $wb['Edit Reseller'] = 'Editar Revendedor';
 $wb['Resellers'] = 'Revendedores';
diff --git a/interface/web/client/lib/lang/ro.lng b/interface/web/client/lib/lang/ro.lng
index 88e0f8f..bb03af8 100644
--- a/interface/web/client/lib/lang/ro.lng
+++ b/interface/web/client/lib/lang/ro.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Add Client';
 $wb['Edit Client'] = 'Edit Client';
 $wb['Clients'] = 'Clients';
-$wb['Edit Client-Templates'] = 'Edit Client-Templates';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Add Reseller';
 $wb['Edit Reseller'] = 'Edit Reseller';
 $wb['Resellers'] = 'Resellers';
diff --git a/interface/web/client/lib/lang/ru.lng b/interface/web/client/lib/lang/ru.lng
index 5d37029..087e68b 100644
--- a/interface/web/client/lib/lang/ru.lng
+++ b/interface/web/client/lib/lang/ru.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Добавить клиента';
 $wb['Edit Client'] = 'Изменить клиента';
 $wb['Clients'] = 'Клиенты';
-$wb['Edit Client-Templates'] = 'Изменить шаблон клиента';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Добавить реселлера';
 $wb['Edit Reseller'] = 'Изменить реселлера';
 $wb['Resellers'] = 'Реселлеры';
diff --git a/interface/web/client/lib/lang/se.lng b/interface/web/client/lib/lang/se.lng
index 88e0f8f..bb03af8 100644
--- a/interface/web/client/lib/lang/se.lng
+++ b/interface/web/client/lib/lang/se.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Add Client';
 $wb['Edit Client'] = 'Edit Client';
 $wb['Clients'] = 'Clients';
-$wb['Edit Client-Templates'] = 'Edit Client-Templates';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Add Reseller';
 $wb['Edit Reseller'] = 'Edit Reseller';
 $wb['Resellers'] = 'Resellers';
diff --git a/interface/web/client/lib/lang/sk.lng b/interface/web/client/lib/lang/sk.lng
index e9d300c..6351f3d 100644
--- a/interface/web/client/lib/lang/sk.lng
+++ b/interface/web/client/lib/lang/sk.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Pridať klienta';
 $wb['Edit Client'] = 'Upraviť klienta';
 $wb['Clients'] = 'Klienti';
-$wb['Edit Client-Templates'] = 'Upraviť klient-Šablónu';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Pridať nového predajcu';
 $wb['Edit Reseller'] = 'Upraviť predajcu';
 $wb['Resellers'] = 'Predajcovia';
diff --git a/interface/web/client/lib/lang/tr.lng b/interface/web/client/lib/lang/tr.lng
index 96dd7a0..8a98a13 100644
--- a/interface/web/client/lib/lang/tr.lng
+++ b/interface/web/client/lib/lang/tr.lng
@@ -5,7 +5,8 @@
 $wb['Add Client'] = 'Müşteri Ekle';
 $wb['Edit Client'] = 'Müşteri Düzenle';
 $wb['Clients'] = 'Müşteriler';
-$wb['Edit Client-Templates'] = 'Müşteri-Şablon Düzenle';
+$wb['Templates'] = 'Templates';
+$wb['Limit-Templates'] = 'Limit-Templates';
 $wb['Add Reseller'] = 'Reseller Ekle';
 $wb['Edit Reseller'] = 'Reseller Düzenle';
 $wb['Resellers'] = 'Resellerlar';
diff --git a/interface/web/client/lib/module.conf.php b/interface/web/client/lib/module.conf.php
index bfb6ac8..e4bddd7 100644
--- a/interface/web/client/lib/module.conf.php
+++ b/interface/web/client/lib/module.conf.php
@@ -17,13 +17,6 @@
 	'link' => 'client/client_edit.php',
 	'html_id'   => 'client_add');
 
-if($_SESSION["s"]["user"]["typ"] == 'admin'){
-	$items[] = array(   'title'  => "Edit Client-Templates",
-		'target'  => 'content',
-		'link' => 'client/client_template_list.php',
-		'html_id'   => 'client_template_list');
-}
-
 $module["nav"][] = array(   'title' => 'Clients',
 	'open'  => 1,
 	'items' => $items);
@@ -66,6 +59,24 @@
 
 unset($items);
 
+
+$items[] = array(   'title'  => "Limit-Templates",
+	'target'  => 'content',
+	'link' => 'client/client_template_list.php',
+	'html_id'   => 'client_template_list');
+
+$items[] = array(   'title'  => "Email-Templates",
+	'target'  => 'content',
+	'link' => 'client/message_template_list.php',
+	'html_id'   => 'message_template_list');
+
+$module["nav"][] = array(   'title' => 'Templates',
+	'open'  => 1,
+	'items' => $items);
+
+unset($items);
+
+
 $app->uses('ini_parser,getconf');
 $settings = $app->getconf->get_global_config('domains');
 
diff --git a/interface/web/client/list/message_template.list.php b/interface/web/client/list/message_template.list.php
new file mode 100644
index 0000000..6441182
--- /dev/null
+++ b/interface/web/client/list/message_template.list.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+Copyright (c) 2010, Till Brehm, projektfarm Gmbh
+All rights reserved.
+*/
+
+/*
+	Datatypes:
+	- INTEGER
+	- DOUBLE
+	- CURRENCY
+	- VARCHAR
+	- TEXT
+	- DATE
+*/
+
+
+
+// Name of the list
+$liste["name"]     = "client_message_template";
+
+// Database table
+$liste["table"]    = "client_message_template";
+
+// Index index field of the database table
+$liste["table_idx"]   = "client_message_template_id";
+
+// Search Field Prefix
+$liste["search_prefix"]  = "search_";
+
+// Records per page
+$liste["records_per_page"]  = 15;
+
+// Script File of the list
+$liste["file"]    = "message_template_list.php";
+
+// Script file of the edit form
+$liste["edit_file"]   = "message_template_edit.php";
+
+// Script File of the delete script
+$liste["delete_file"]  = "message_template_del.php";
+
+// Paging Template
+$liste["paging_tpl"]  = "templates/paging.tpl.htm";
+
+// Enable authe
+$liste["auth"]    = "yes";
+
+
+/*****************************************************
+* Suchfelder
+*****************************************************/
+
+$liste["item"][] = array( 'field'  => "template_type",
+	'datatype' => "VARCHAR",
+	'formtype' => "SELECT",
+	'op'  => "=",
+	'prefix' => "",
+	'suffix' => "",
+	'width'  => "",
+	'value'  => array('welcome' => 'Default welcome email', 'other' => 'Other'));
+
+$liste["item"][] = array( 'field'  => "template_name",
+	'datatype' => "VARCHAR",
+	'formtype' => "TEXT",
+	'op'  => "like",
+	'prefix' => "%",
+	'suffix' => "%",
+	'width'  => "",
+	'value'  => "");
+
+
+
+
+
+?>
diff --git a/interface/web/client/message_template_del.php b/interface/web/client/message_template_del.php
new file mode 100644
index 0000000..46aba4f
--- /dev/null
+++ b/interface/web/client/message_template_del.php
@@ -0,0 +1,58 @@
+<?php
+
+/*
+Copyright (c) 2014 Till Brehm, ISPConfig UG
+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/message_template.list.php";
+$tform_def_file = "form/message_template.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('client');
+
+$app->uses('tpl,tform');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+
+}
+
+$page = new page_action;
+$page->onDelete()
+
+?>
diff --git a/interface/web/client/message_template_edit.php b/interface/web/client/message_template_edit.php
new file mode 100644
index 0000000..819e267
--- /dev/null
+++ b/interface/web/client/message_template_edit.php
@@ -0,0 +1,99 @@
+<?php
+/*
+Copyright (c) 2014 Till Brehm, ISPConfig UG
+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/message_template.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('client');
+
+// Loading classes
+$app->uses('tpl,tform,tform_actions');
+$app->load('tform_actions');
+
+class page_action extends tform_actions {
+	
+	function onSubmit() {
+		global $app, $conf;
+		
+		// Check for duplicates
+		if($this->dataRecord['template_type'] == 'welcome') {
+			$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+			$sql = "SELECT count(client_message_template_id) as number FROM client_message_template WHERE template_type = 'welcome' AND sys_groupid = ".$client_group_id;
+			if($this->id > 0) {
+				$sql .= " AND client_message_template_id != ".$this->id;
+			}
+			
+			$tmp = $app->db->queryOneRecord($sql);
+			if($tmp['number'] > 0) $app->tform->errorMessage .= $app->tform->lng('duplicate_welcome_error');
+		}
+		
+		parent::onSubmit();
+	}
+	
+	function onShowEnd() {
+		global $app, $conf;
+	
+		//message variables
+		$message_variables = '';
+		$sql = "SHOW COLUMNS FROM client WHERE Field NOT IN ('client_id', 'sys_userid', 'sys_groupid', 'sys_perm_user', 'sys_perm_group', 'sys_perm_other', 'parent_client_id', 'id_rsa', 'ssh_rsa', 'created_at', 'default_mailserver', 'default_webserver', 'web_php_options', 'ssh_chroot', 'default_dnsserver', 'default_dbserver', 'template_master', 'template_additional', 'force_suexec', 'default_slave_dnsserver', 'usertheme', 'locked', 'canceled', 'can_use_api', 'tmp_data', 'customer_no_template', 'customer_no_start', 'customer_no_counter', 'added_date', 'added_by') AND Field NOT LIKE 'limit_%'";
+		$field_names = $app->db->queryAllRecords($sql);
+		if(!empty($field_names) && is_array($field_names)){
+			foreach($field_names as $field_name){
+				if($field_name['Field'] != ''){
+					if($field_name['Field'] == 'gender'){
+						$message_variables .= '<a href="javascript:void(0);" class="addPlaceholder">{salutation}</a> ';
+					} else {
+						$message_variables .= '<a href="javascript:void(0);" class="addPlaceholder">{'.$field_name['Field'].'}</a> ';
+					}
+				}
+			}
+		}
+		$app->tpl->setVar('message_variables', trim($message_variables));
+
+		parent::onShowEnd();
+	}
+	
+}
+
+$page = new page_action;
+$page->onLoad();
+
+?>
diff --git a/interface/web/client/message_template_list.php b/interface/web/client/message_template_list.php
new file mode 100644
index 0000000..a324732
--- /dev/null
+++ b/interface/web/client/message_template_list.php
@@ -0,0 +1,53 @@
+<?php
+/*
+Copyright (c) 2014 Till Brehm, ISPConfig UG
+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/message_template.list.php";
+
+/******************************************
+* End Form configuration
+******************************************/
+
+//* Check permissions for module
+$app->auth->check_module_permissions('client');
+
+$app->uses('listform_actions');
+
+//$app->listform_actions->SQLOrderBy = 'ORDER BY company_name, contact_name, client_id';
+//$app->listform_actions->SQLExtWhere = "limit_client = 0";
+$app->listform_actions->onLoad();
+
+
+?>
diff --git a/interface/web/client/reseller_edit.php b/interface/web/client/reseller_edit.php
index f982856..4a7cc87 100644
--- a/interface/web/client/reseller_edit.php
+++ b/interface/web/client/reseller_edit.php
@@ -94,6 +94,26 @@
 				}
 			}
 		}
+		
+		if($this->id != 0) {
+			$this->oldTemplatesAssigned = $app->db->queryAllRecords('SELECT * FROM `client_template_assigned` WHERE `client_id` = ' . $this->id);
+			if(!is_array($this->oldTemplatesAssigned) || count($this->oldTemplatesAssigned) < 1) {
+				// check previous type of storing templates
+				$tpls = explode('/', $this->oldDataRecord['template_additional']);
+				$this->oldTemplatesAssigned = array();
+				foreach($tpls as $item) {
+					$item = trim($item);
+					if(!$item) continue;
+					$this->oldTemplatesAssigned[] = array('assigned_template_id' => 0, 'client_template_id' => $item, 'client_id' => $this->id);
+				}
+				unset($tpls);
+			}
+		} else {
+			$this->oldTemplatesAssigned = array();
+		}
+
+		$this->_template_additional = explode('/', $this->dataRecord['template_additional']);
+		$this->dataRecord['template_additional'] = '';
 
 		parent::onSubmit();
 	}
@@ -117,13 +137,27 @@
 		$result = $app->db->queryAllRecords('SELECT assigned_template_id, client_template_id FROM client_template_assigned WHERE client_id = ' . $this->id);
 		if($result && count($result) > 0) {
 			// new style
+			$items = array();
 			$text = '';
 			foreach($result as $item){
 				if (trim($item['client_template_id']) != ''){
 					if ($text != '') $text .= '';
-					$text .= '<li rel="' . $item['assigned_template_id'] . '">' . $tpl[$item['client_template_id']]. '<a href="#" class="button icons16 icoDelete"></a></li>';
+					$text .= '<li rel="' . $item['assigned_template_id'] . '">' . $tpl[$item['client_template_id']];
+					$text .= '<a href="#" class="button icons16 icoDelete"></a>';
+					$tmp = new stdClass();
+					$tmp->id = $item['assigned_template_id'];
+					$tmp->data = '';
+					$app->plugin->raiseEvent('get_client_template_details', $tmp);
+					if($tmp->data != '') $text .= '<br /><em>' . $tmp->data . '</em>';
+
+					$text .= '</li>';
+					$items[] = $item['assigned_template_id'] . ':' . $item['client_template_id'];
 				}
 			}
+
+			$tmprec = $app->tform->getHTML(array('template_additional' => implode('/', $items)), $this->active_tab, 'EDIT');
+			$app->tpl->setVar('template_additional', $tmprec['template_additional']);
+			unset($tmprec);
 		} else {
 			// old style
 			$sql = "SELECT template_additional FROM client WHERE client_id = " . $this->id;
@@ -139,6 +173,7 @@
 		}
 
 		$app->tpl->setVar('template_additional_list', $text);
+		$app->tpl->setVar('app_module', 'client');
 		
 		//* Set the 'customer no' default value
 		if($this->id == 0) {
@@ -153,9 +188,11 @@
 				$app->tpl->setVar('customer_no',$customer_no_string);
 				
 				//* save new counter value
+				/*
 				$system_config['misc']['customer_no_counter']++;
 				$system_config_str = $app->ini_parser->get_ini_string($system_config);
 				$app->db->datalogUpdate('sys_ini', "config = '".$app->db->quote($system_config_str)."'", 'sysini_id', 1);
+				*/
 			}
 		}
 		
@@ -210,6 +247,66 @@
 
 		$sql = "UPDATE client SET default_mailserver = $default_mailserver, default_webserver = $default_webserver, default_dnsserver = $default_dnsserver, default_slave_dnsserver = $default_dnsserver, default_dbserver = $default_dbserver WHERE client_id = ".$this->id;
 		$app->db->query($sql);
+		
+		if(isset($this->dataRecord['template_master'])) {
+			$app->uses('client_templates');
+			$app->client_templates->update_client_templates($this->id, $this->_template_additional);
+		}
+		
+		if($this->dataRecord['customer_no'] == $this->dataRecord['customer_no_org']) {
+			//* get the system config
+			$app->uses('getconf');
+			$system_config = $app->getconf->get_global_config();
+			if($system_config['misc']['customer_no_template'] != '') {
+				
+				//* save new counter value
+				$system_config['misc']['customer_no_counter']++;
+				$system_config_str = $app->ini_parser->get_ini_string($system_config);
+				$app->db->datalogUpdate('sys_ini', "config = '".$app->db->quote($system_config_str)."'", 'sysini_id', 1);
+				
+			}
+		}
+		
+		//* Send welcome email
+		$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+		$sql = "SELECT * FROM client_message_template WHERE template_type = 'welcome' AND sys_groupid = ".$client_group_id;
+		$email_template = $app->db->queryOneRecord($sql);
+		$client = $app->tform->getDataRecord($this->id);
+
+		if(is_array($email_template) && $client['email'] != '') {
+			//* Parse client details into message
+			$message = $email_template['message'];
+			$subject = $email_template['subject'];
+			foreach($client as $key => $val) {
+				switch ($key) {
+				case 'password':
+					$message = str_replace('{password}', $this->dataRecord['password'], $message);
+					$subject = str_replace('{password}', $this->dataRecord['password'], $subject);
+					break;
+				case 'gender':
+					$message = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $message);
+					$subject = str_replace('{salutation}', $wb['gender_'.$val.'_txt'], $subject);
+					break;
+				default:
+					$message = str_replace('{'.$key.'}', $val, $message);
+					$subject = str_replace('{'.$key.'}', $val, $subject);
+				}
+			}
+			
+			//* Get sender address
+			if($app->auth->is_admin()) {
+				$app->uses('getconf');
+				$system_config = $app->getconf->get_global_config();
+				$from = $system_config['admin_mail'];
+			} else {
+				$client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
+				$reseller = $app->db->queryOneRecord("SELECT client.email FROM sys_group,client WHERE client.client_id = sys_group.client_id and sys_group.groupid = ".$client_group_id);
+				$from = $reseller["email"];
+			}
+
+			//* Send the email
+			$app->functions->mail($client['email'], $subject, $message, $from);
+		}
 
 		parent::onAfterInsert();
 	}
@@ -272,6 +369,11 @@
 			$sql = "UPDATE sys_user SET modules = '$modules' WHERE client_id = $client_id";
 			$app->db->query($sql);
 		}
+		
+		if(isset($this->dataRecord['template_master'])) {
+			$app->uses('client_templates');
+			$app->client_templates->update_client_templates($this->id, $this->_template_additional);
+		}
 
 		parent::onAfterUpdate();
 	}
diff --git a/interface/web/client/templates/client_edit_address.htm b/interface/web/client/templates/client_edit_address.htm
index 8392820..6149a42 100644
--- a/interface/web/client/templates/client_edit_address.htm
+++ b/interface/web/client/templates/client_edit_address.htm
@@ -22,6 +22,7 @@
             <div class="ctrlHolder">
                 <label for="customer_no">{tmpl_var name='customer_no_txt'}</label>
                 <input name="customer_no" id="customer_no" value="{tmpl_var name='customer_no'}" size="30" maxlength="255" type="text" class="textInput" />
+				<input name="customer_no_org" id="customer_no_org" value="{tmpl_var name='customer_no'}" type="hidden" />
             </div>
             <div class="ctrlHolder">
                 <label for="username">{tmpl_var name='username_txt'}*</label>
diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm
index 05ceb63..c97e03f 100644
--- a/interface/web/client/templates/client_edit_limits.htm
+++ b/interface/web/client/templates/client_edit_limits.htm
@@ -3,7 +3,6 @@
 
 <div class="panel panel_client">
 
-    <tmpl_if name="is_admin">
         <div class="pnl_toolsarea">
             <fieldset><legend>{tmpl_var name="toolsarea_head_txt"}</legend>
                 <div class="buttons topbuttons">
@@ -11,11 +10,9 @@
                 </div>
             </fieldset>
         </div>
-    </tmpl_if>
 
     <div class="pnl_formsarea">
         <fieldset class="inlineLabels"><legend>Limits</legend>
-            <tmpl_if name="is_admin">
                 <div class="ctrlHolder">
                     <label for="template_master">{tmpl_var name='template_master_txt'}</label>
                     <select name="template_master" id="template_master" class="selectInput">
@@ -40,7 +37,14 @@
                 <div class="ctrlHolder">
                     &nbsp;
                 </div>
-            </tmpl_if>
+				<tmpl_if name="is_admin">
+                <div class="ctrlHolder">
+                    <label for="parent_client_id_id">{tmpl_var name='parent_client_id_txt'}</label>
+                    <select name="parent_client_id" id="parent_client_id" class="selectInput">
+                        {tmpl_var name='parent_client_id'}
+                    </select>
+                </div>
+                </tmpl_if>
             <div class="subsectiontoggle"><span class="showing"></span>{tmpl_var name='web_limits_txt'}<em class="showing"></em></div>
             <div>
                 <div class="ctrlHolder">
@@ -301,7 +305,7 @@
     </div>
 
 </div>
-<tmpl_if name="is_admin">
+
 <script type="text/javascript">
 <!--
 function custom_template_selected() {
@@ -317,7 +321,7 @@
         .find('div.pnl_formsarea')
         .find('fieldset')
         .find('input,select,button')
-        .not('#template_master,#template_additional,#default_mailserver,#default_webserver,#default_dbserver,#default_dnsserver,#default_slave_dnsserver')
+        .not('#template_master,#template_additional,#default_mailserver,#default_webserver,#default_dbserver,#default_dnsserver,#default_slave_dnsserver,#customer_no_template,#customer_no_start,#customer_no_counter,#parent_client_id')
         .click(function(e) {
             if(custom_template_selected()) return true;
             e.preventDefault();
@@ -330,4 +334,3 @@
 
 //-->
 </script>
-</tmpl_if>
\ No newline at end of file
diff --git a/interface/web/client/templates/client_message_template_list.htm b/interface/web/client/templates/client_message_template_list.htm
new file mode 100644
index 0000000..95f6f00
--- /dev/null
+++ b/interface/web/client/templates/client_message_template_list.htm
@@ -0,0 +1,57 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+
+<div class="panel panel_list_client_message_template">
+
+  <div class="pnl_toolsarea">
+    <fieldset><legend>{tmpl_var name="toolsarea_head_txt"}</legend>
+      <div class="buttons">
+        <button class="iconstxt icoAdd" type="button" onclick="loadContent('client/message_template_edit.php');">
+          <span>{tmpl_var name="add_new_record_txt"}</span>
+        </button>
+      </div>
+    </fieldset>
+  </div>
+
+  <div class="pnl_listarea">
+    <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+      <table class="list">
+        <thead>
+          <tr>
+            <th class="tbl_col_template_type" scope="col"><tmpl_var name="template_type_txt"></th>
+            <th class="tbl_col_template_name" scope="col"><tmpl_var name="template_name_txt"></th>
+            <th class="tbl_col_buttons" scope="col">&nbsp;</th>
+          </tr>
+          <tr>
+            <td class="tbl_col_template_type"><select name="search_template_type" onChange="submitForm('pageForm','client/message_template_list.php');">{tmpl_var name='search_template_type'}</select></td>
+            <td class="tbl_col_template_name"><input type="text" name="search_template_name" value="{tmpl_var name='search_template_name'}" /></td>
+            <td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onclick="submitForm('pageForm','client/message_template_list.php');"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
+          </tr>
+        </thead>
+        <tbody>
+          <tmpl_loop name="records">
+          <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+            <td class="tbl_col_template_type"><a href="#" onclick="loadContent('client/message_template_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="template_type"}</a></td>
+            <td class="tbl_col_template_name"><a href="#" onclick="loadContent('client/message_template_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="template_name"}</a></td>
+            <td class="tbl_col_buttons">
+              <div class="buttons icons16">
+                <a class="button icons16 icoDelete" href="javascript: del_record('client/message_template_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
+              </div>
+            </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="2">{tmpl_var name='globalsearch_noresults_text_txt'}</td>
+              </tr>
+          </tmpl_unless>
+        </tbody>
+        <tfoot>
+          <tr>
+            <td class="tbl_footer tbl_paging" colspan="3"><tmpl_var name="paging"></td>
+          </tr>
+        </tfoot>
+      </table>
+    </fieldset>
+  </div>
+
+</div>
diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm
index 18abc9b..1eea399 100644
--- a/interface/web/client/templates/client_template_edit_limits.htm
+++ b/interface/web/client/templates/client_template_edit_limits.htm
@@ -5,7 +5,7 @@
 
     <div class="pnl_formsarea">
         <fieldset class="inlineLabels"><legend>Limits</legend>
-            <div class="subsectiontoggle"><span class="showing"></span>{tmpl_var name='web_limits_txt'}<em class="showing"></em></div>
+			<div class="subsectiontoggle"><span class="showing"></span>{tmpl_var name='web_limits_txt'}<em class="showing"></em></div>
             <div>
                 <div class="ctrlHolder">
                     <label for="limit_web_domain">{tmpl_var name='limit_web_domain_txt'}</label>
@@ -224,6 +224,19 @@
                     <input name="limit_aps" id="limit_aps" value="{tmpl_var name='limit_aps'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
                 </div>
             </div>
+			<tmpl_if name="is_admin">
+			<div class="subsectiontoggle"><span></span>{tmpl_var name='client_limits_txt'}<em></em></div>
+			<div style="display:none;">
+				<div class="ctrlHolder">
+					<label for="limit_client">{tmpl_var name='limit_client_txt'}</label>
+					<input name="limit_client" id="limit_client" value="{tmpl_var name='limit_client'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+				</div>
+				<div class="ctrlHolder">
+					<label for="limit_domainmodule">{tmpl_var name='limit_domainmodule_txt'}</label>
+					<input name="limit_domainmodule" id="limit_domainmodule" value="{tmpl_var name='limit_domainmodule'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+				</div>
+			</div>
+			</tmpl_if>
         </fieldset>
 
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
diff --git a/interface/web/client/templates/domain_list.htm b/interface/web/client/templates/domain_list.htm
index bd8f8be..3100660 100644
--- a/interface/web/client/templates/domain_list.htm
+++ b/interface/web/client/templates/domain_list.htm
@@ -6,15 +6,9 @@
     <div class="pnl_toolsarea">
         <fieldset><legend>{tmpl_var name="toolsarea_head_txt"}</legend>
             <div class="buttons">
-                <tmpl_if name="is_admin">
                 <button class="button iconstxt icoAdd" type="button" onclick="loadContent('client/domain_edit.php');">
                     <span>{tmpl_var name="add_new_record_txt"}</span>
                 </button>
-                <tmpl_else>
-                <button class="button iconstxt icoAdd" type="button" onclick="loadContent('client/domain_new_client.php');">
-                    <span>{tmpl_var name="add_new_record_txt"}</span>
-                </button>
-                </tmpl_if>
             </div>
         </fieldset>
     </div>
diff --git a/interface/web/client/templates/message_template.htm b/interface/web/client/templates/message_template.htm
new file mode 100644
index 0000000..4c0c623
--- /dev/null
+++ b/interface/web/client/templates/message_template.htm
@@ -0,0 +1,39 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+<p><tmpl_var name="list_desc_txt"></p>
+
+<div class="panel panel_invoice_message_template">
+
+  <div class="pnl_formsarea">
+    <fieldset class="inlineLabels"><legend>Settings</legend>
+      <div class="ctrlHolder">
+      	<label for="template_type">{tmpl_var name='template_type_txt'}</label>
+        <select name="template_type" id="template_type" class="selectInput">
+					{tmpl_var name='template_type'}
+				</select>
+      </div>
+      <div class="ctrlHolder">
+      	<label for="template_name">{tmpl_var name='template_name_txt'}</label>
+        <input name="template_name" id="template_name" value="{tmpl_var name='template_name'}" size="30" maxlength="255" type="text" class="textInput" />
+			</div>
+      <div class="ctrlHolder">
+      	<label for="subject">{tmpl_var name='subject_txt'}</label>
+        <input name="subject" id="subject" value="{tmpl_var name='subject'}" style="width:500px" size="30" maxlength="255" type="text" class="textInput" />
+		<br clear="all">{tmpl_var name='variables_txt'}: {tmpl_var name="message_variables"} <br />{tmpl_var name='variables_description_txt'}
+			</div>
+      <div class="ctrlHolder">
+      	<label for="message">{tmpl_var name='message_txt'}</label>
+        <textarea name="message" id="message" rows='' cols='' style="width:500px">{tmpl_var name='message'}</textarea>
+		<br clear="all">{tmpl_var name='variables_txt'}: {tmpl_var name="message_variables"} <br />{tmpl_var name='variables_description_txt'}
+      </div>
+	  <div class="buttonHolder buttons">
+      <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','client/message_template_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+      <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('client/message_template_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+    </div>
+    </fieldset>
+
+    <input type="hidden" name="id" value="{tmpl_var name='id'}">
+
+    
+  </div>
+  
+</div>
diff --git a/interface/web/client/templates/message_template_list.htm b/interface/web/client/templates/message_template_list.htm
new file mode 100644
index 0000000..27b0113
--- /dev/null
+++ b/interface/web/client/templates/message_template_list.htm
@@ -0,0 +1,52 @@
+<h2><tmpl_var name="list_head_txt"></h2>
+
+<div class="panel panel_list_invoice_message_template">
+
+  <div class="pnl_toolsarea">
+    <fieldset><legend>{tmpl_var name="toolsarea_head_txt"}</legend>
+      <div class="buttons">
+        <button class="iconstxt icoAdd" type="button" onClick="loadContent('billing/invoice_message_template_edit.php');">
+          <span>{tmpl_var name="add_new_record_txt"}</span>
+        </button>
+      </div>
+    </fieldset>
+  </div>
+
+  <div class="pnl_listarea">
+    <fieldset><legend><tmpl_var name="list_head_txt"></legend>
+      <table class="list">
+        <thead>
+          <tr>
+            <th class="tbl_col_template_type" scope="col"><tmpl_var name="template_type_txt"></th>
+            <th class="tbl_col_template_name" scope="col"><tmpl_var name="template_name_txt"></th>
+            <th class="tbl_col_buttons" scope="col">&nbsp;</th>
+          </tr>
+          <tr>
+            <td class="tbl_col_template_type"><select name="search_template_type" onChange="submitForm('pageForm','billing/invoice_message_template_list.php');">{tmpl_var name='search_template_type'}</select></td>
+            <td class="tbl_col_template_name"><input type="text" name="search_template_name" value="{tmpl_var name='search_template_name'}" /></td>
+            <td class="tbl_col_buttons"><div class="buttons"><button type="button" class="icons16 icoFilter" name="Filter" id="Filter" value="{tmpl_var name="filter_txt"}" onClick="submitForm('pageForm','billing/invoice_message_template_list.php');"><span>{tmpl_var name="filter_txt"}</span></button></div></td>
+          </tr>
+        </thead>
+        <tbody>
+          <tmpl_loop name="records">
+          <tr class="tbl_row_<tmpl_if name='__EVEN__'}even<tmpl_else>uneven</tmpl_if>">
+            <td class="tbl_col_template_type"><a href="#" onClick="loadContent('billing/invoice_message_template_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="template_type"}</a></td>
+            <td class="tbl_col_template_name"><a href="#" onClick="loadContent('billing/invoice_message_template_edit.php?id={tmpl_var name='id'}');">{tmpl_var name="template_name"}</a></td>
+            <td class="tbl_col_buttons">
+              <div class="buttons icons16">    
+                <a class="button icons16 icoDelete" href="javascript: del_record('billing/invoice_message_template_del.php?id={tmpl_var name='id'}&phpsessid={tmpl_var name='phpsessid'}','{tmpl_var name='delete_confirmation'}');"><span>{tmpl_var name='delete_txt'}</span></a>
+              </div>
+            </td>
+          </tr>
+          </tmpl_loop>
+        </tbody>
+        <tfoot>
+          <tr>
+            <td class="tbl_footer tbl_paging" colspan="3"><tmpl_var name="paging"></td>
+          </tr>
+        </tfoot>
+      </table>
+    </fieldset>
+  </div>
+
+</div>
diff --git a/interface/web/client/templates/reseller_edit_address.htm b/interface/web/client/templates/reseller_edit_address.htm
index 86acccd..5495d0a 100644
--- a/interface/web/client/templates/reseller_edit_address.htm
+++ b/interface/web/client/templates/reseller_edit_address.htm
@@ -22,6 +22,7 @@
             <div class="ctrlHolder">
                 <label for="customer_no">{tmpl_var name='customer_no_txt'}</label>
                 <input name="customer_no" id="customer_no" value="{tmpl_var name='customer_no'}" size="30" maxlength="255" type="text" class="textInput" />
+				<input name="customer_no_org" id="customer_no_org" value="{tmpl_var name='customer_no'}" type="hidden" />
             </div>
             <div class="ctrlHolder">
                 <label for="username">{tmpl_var name='username_txt'}*</label>
diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm
index e12726e..d5ff205 100644
--- a/interface/web/client/templates/reseller_edit_limits.htm
+++ b/interface/web/client/templates/reseller_edit_limits.htm
@@ -3,33 +3,44 @@
 
 <div class="panel panel_client">
 
+	<tmpl_if name="is_admin">
+		<div class="pnl_toolsarea">
+			<fieldset><legend>{tmpl_var name="toolsarea_head_txt"}</legend>
+			<div class="buttons topbuttons">
+				<button class="positive iconstxt icoAdd" type="button" value="{tmpl_var name='add_additional_template_txt'}" onclick="addAdditionalTemplate();"><span>{tmpl_var name='add_additional_template_txt'}</span></button>
+			</div>
+			</fieldset>
+		</div>
+	</tmpl_if>
+
     <div class="pnl_formsarea">
         <fieldset class="inlineLabels"><legend>Limits</legend>
-            <!--
-            <tmpl_if name="is_admin">
-                  <div class="ctrlHolder">
+			<tmpl_if name="is_admin">
+                <div class="ctrlHolder">
                     <label for="template_master">{tmpl_var name='template_master_txt'}</label>
                     <select name="template_master" id="template_master" class="selectInput">
-                                                    {tmpl_var name='template_master'}
-                                            </select>
-                  </div>
-                  <div class="ctrlHolder">
+                        {tmpl_var name='template_master'}
+                    </select>
+                </div>
+                <div class="ctrlHolder">
                     <label for="template_additional">{tmpl_var name='template_additional_txt'}</label>
                     <select name="tpl_add_select" id="tpl_add_select" class="selectInput">
-                                                    {tmpl_var name='tpl_add_select'}
-                                            </select>
-                          <span id="template_additional_list">{tmpl_var name='template_additional_list'}</span>
-                              <input type="hidden" id="template_additional" name="template_additional" value="{tmpl_var name='template_additional'}">
-                  </div>
-                      <div class="ctrlHolder">
-                        &nbsp;
-                      </div>
+                        {tmpl_var name='tpl_add_select'}
+                    </select>
+                </div>
+                <div class="ctrlHolder">
+                    <p class="label">{tmpl_var name='active_template_additional_txt'}</p>
+                    <div id="template_additional_list" class="multiField">
+                        <ul>
+                        {tmpl_var name='template_additional_list'}
+                        </ul>
+                    </div>
+                    <input type="hidden" id="template_additional" name="template_additional" value="{tmpl_var name='template_additional'}">
+                </div>
+                <div class="ctrlHolder">
+                    &nbsp;
+                </div>
             </tmpl_if>
-            -->
-            <div class="ctrlHolder">
-                <label for="limit_client">{tmpl_var name='limit_client_txt'}</label>
-                <input name="limit_client" id="limit_client" value="{tmpl_var name='limit_client'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
-            </div>
 			<div class="ctrlHolder">
                 <label for="customer_no_template">{tmpl_var name='customer_no_template_txt'}</label>
                 <input name="customer_no_template" id="customer_no_template" value="{tmpl_var name='customer_no_template'}" size="30" maxlength="255" type="text" class="textInput formLengthHalf" />
@@ -291,6 +302,17 @@
                     <input name="limit_aps" id="limit_aps" value="{tmpl_var name='limit_aps'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
                 </div>
             </div>
+			<div class="subsectiontoggle"><span></span>{tmpl_var name='client_limits_txt'}<em></em></div>
+			<div style="display:none;">
+				<div class="ctrlHolder">
+					<label for="limit_client">{tmpl_var name='limit_client_txt'}</label>
+					<input name="limit_client" id="limit_client" value="{tmpl_var name='limit_client'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+				</div>
+				<div class="ctrlHolder">
+					<label for="limit_domainmodule">{tmpl_var name='limit_domainmodule_txt'}</label>
+					<input name="limit_domainmodule" id="limit_domainmodule" value="{tmpl_var name='limit_domainmodule'}" size="10" maxlength="10" type="text" class="textInput formLengthLimit" />
+				</div>
+			</div>
         </fieldset>
 
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
@@ -301,4 +323,34 @@
         </div>
     </div>
 
-</div>
\ No newline at end of file
+</div>
+<tmpl_if name="is_admin">
+<script type="text/javascript">
+<!--
+function custom_template_selected() {
+    return ($('#template_master').val() == '0' ? true : false);
+}
+
+jQuery('#template_additional_list').find('li > a').click(function(e) {
+    e.preventDefault();
+    delAdditionalTemplate($(this).parent().attr('rel'));
+});
+
+jQuery('div.panel_client')
+        .find('div.pnl_formsarea')
+        .find('fieldset')
+        .find('input,select,button')
+        .not('#template_master,#template_additional,#default_mailserver,#default_webserver,#default_dbserver,#default_dnsserver,#default_slave_dnsserver,#customer_no_template,#customer_no_start,#customer_no_counter')
+        .click(function(e) {
+            if(custom_template_selected()) return true;
+            e.preventDefault();
+            alert('{tmpl_var name="err_msg_master_tpl_set"}');
+        })
+        .focus(function() {
+            if(custom_template_selected()) return true;
+            $(this).blur();
+        });
+
+//-->
+</script>
+</tmpl_if>
diff --git a/interface/web/mail/mail_user_edit.php b/interface/web/mail/mail_user_edit.php
index 435489f..75fb42f 100644
--- a/interface/web/mail/mail_user_edit.php
+++ b/interface/web/mail/mail_user_edit.php
@@ -205,8 +205,8 @@
 			$this->dataRecord["homedir"] = $mail_config["homedir_path"];
 			
 			// Will be overwritten by mail_plugin
-			$this->dataRecord['uid'] = 999989999;
-			$this->dataRecord['gid'] = 999989999;
+			$this->dataRecord['uid'] = -1;
+			$this->dataRecord['gid'] = -1;
 				
 			//* Check if there is no alias or forward with this address
 			$tmp = $app->db->queryOneRecord("SELECT count(forwarding_id) as number FROM mail_forwarding WHERE active = 'y' AND source = '".$app->db->quote($this->dataRecord["email"])."'");
diff --git a/interface/web/sites/database_edit.php b/interface/web/sites/database_edit.php
index 139c971..2249351 100644
--- a/interface/web/sites/database_edit.php
+++ b/interface/web/sites/database_edit.php
@@ -302,7 +302,26 @@
 				}
 			}
 		}
-
+		
+		if ($app->tform->errorMessage == '') {
+			// force update of the used database user
+			if($this->dataRecord['database_user_id']) {
+				$user_old_rec = $app->db->queryOneRecord('SELECT * FROM `web_database_user` WHERE `database_user_id` = ' . $app->functions->intval($this->dataRecord['database_user_id']));
+				if($user_old_rec) {
+					$user_new_rec = $user_old_rec;
+					$user_new_rec['server_id'] = $this->dataRecord['server_id'];
+					$app->db->datalogSave('web_database_user', 'UPDATE', 'database_user_id', $this->dataRecord['database_user_id'], $user_old_rec, $user_new_rec);
+				}
+			}
+			if($this->dataRecord['database_ro_user_id']) {
+				$user_old_rec = $app->db->queryOneRecord('SELECT * FROM `web_database_user` WHERE `database_user_id` = ' . $app->functions->intval($this->dataRecord['database_ro_user_id']));
+				if($user_old_rec) {
+					$user_new_rec = $user_old_rec;
+					$user_new_rec['server_id'] = $this->dataRecord['server_id'];
+					$app->db->datalogSave('web_database_user', 'UPDATE', 'database_user_id', $this->dataRecord['database_ro_user_id'], $user_old_rec, $user_new_rec);
+				}
+			}
+		}
 
 		parent::onBeforeUpdate();
 	}
@@ -371,6 +390,27 @@
 			}
 		}
 
+		if ($app->tform->errorMessage == '') {
+			// force update of the used database user
+			if($this->dataRecord['database_user_id']) {
+				$user_old_rec = $app->db->queryOneRecord('SELECT * FROM `web_database_user` WHERE `database_user_id` = ' . $app->functions->intval($this->dataRecord['database_user_id']));
+				if($user_old_rec) {
+					$user_new_rec = $user_old_rec;
+					$user_new_rec['server_id'] = $this->dataRecord['server_id'];
+					$app->db->datalogSave('web_database_user', 'UPDATE', 'database_user_id', $this->dataRecord['database_user_id'], $user_old_rec, $user_new_rec);
+				}
+			}
+			if($this->dataRecord['database_ro_user_id']) {
+				$user_old_rec = $app->db->queryOneRecord('SELECT * FROM `web_database_user` WHERE `database_user_id` = ' . $app->functions->intval($this->dataRecord['database_ro_user_id']));
+				if($user_old_rec) {
+					$user_new_rec = $user_old_rec;
+					$user_new_rec['server_id'] = $this->dataRecord['server_id'];
+					$app->db->datalogSave('web_database_user', 'UPDATE', 'database_user_id', $this->dataRecord['database_ro_user_id'], $user_old_rec, $user_new_rec);
+				}
+			}
+		}
+
+
 		parent::onBeforeInsert();
 	}
 
diff --git a/interface/web/sites/templates/web_domain_advanced.htm b/interface/web/sites/templates/web_domain_advanced.htm
index 0afe57a..3a634e1 100644
--- a/interface/web/sites/templates/web_domain_advanced.htm
+++ b/interface/web/sites/templates/web_domain_advanced.htm
@@ -55,27 +55,27 @@
                 </div>
                 <div class="ctrlHolder">
                     <label for="pm_max_children">{tmpl_var name='pm_max_children_txt'}</label>
-                    <input name="pm_max_children" id="pm_max_children" value="{tmpl_var name='pm_max_children'}" size="3" maxlength="3" type="text" class="textInput formLengthLimit" />
+                    <input name="pm_max_children" id="pm_max_children" value="{tmpl_var name='pm_max_children'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />
                 </div>
                 <div class="ctrlHolder pm_dynamic">
                     <label for="pm_start_servers">{tmpl_var name='pm_start_servers_txt'}</label>
-                    <input name="pm_start_servers" id="pm_start_servers" value="{tmpl_var name='pm_start_servers'}" size="3" maxlength="3" type="text" class="textInput formLengthLimit" />
+                    <input name="pm_start_servers" id="pm_start_servers" value="{tmpl_var name='pm_start_servers'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />
                 </div>
                 <div class="ctrlHolder pm_dynamic">
                     <label for="pm_min_spare_servers">{tmpl_var name='pm_min_spare_servers_txt'}</label>
-                    <input name="pm_min_spare_servers" id="pm_min_spare_servers" value="{tmpl_var name='pm_min_spare_servers'}" size="3" maxlength="3" type="text" class="textInput formLengthLimit" />
+                    <input name="pm_min_spare_servers" id="pm_min_spare_servers" value="{tmpl_var name='pm_min_spare_servers'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />
                 </div>
                 <div class="ctrlHolder pm_dynamic">
                     <label for="pm_max_spare_servers">{tmpl_var name='pm_max_spare_servers_txt'}</label>
-                    <input name="pm_max_spare_servers" id="pm_max_spare_servers" value="{tmpl_var name='pm_max_spare_servers'}" size="3" maxlength="3" type="text" class="textInput formLengthLimit" />
+                    <input name="pm_max_spare_servers" id="pm_max_spare_servers" value="{tmpl_var name='pm_max_spare_servers'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />
                 </div>
                 <div class="ctrlHolder pm_ondemand">
                     <label for="pm_process_idle_timeout">{tmpl_var name='pm_process_idle_timeout_txt'}</label>
-                    <input name="pm_process_idle_timeout" id="pm_process_idle_timeout" value="{tmpl_var name='pm_process_idle_timeout'}" size="3" maxlength="6" type="text" class="textInput formLengthLimit" />&nbsp;s
+                    <input name="pm_process_idle_timeout" id="pm_process_idle_timeout" value="{tmpl_var name='pm_process_idle_timeout'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />&nbsp;s
                 </div>
                 <div class="ctrlHolder">
                     <label for="pm_max_requests">{tmpl_var name='pm_max_requests_txt'}</label>
-                    <input name="pm_max_requests" id="pm_max_requests" value="{tmpl_var name='pm_max_requests'}" size="3" maxlength="6" type="text" class="textInput formLengthLimit" />
+                    <input name="pm_max_requests" id="pm_max_requests" value="{tmpl_var name='pm_max_requests'}" size="6" maxlength="6" type="text" class="textInput formLengthLimit" />
                 </div>
             </div>
             <div class="ctrlHolder php">
diff --git a/interface/web/sites/web_domain_edit.php b/interface/web/sites/web_domain_edit.php
index c793cd0..7673895 100644
--- a/interface/web/sites/web_domain_edit.php
+++ b/interface/web/sites/web_domain_edit.php
@@ -133,11 +133,21 @@
 			} else {
 				$server_id = (isset($web_servers[0])) ? intval($web_servers[0]) : 0;
 			}
-
+			
+			if($app->functions->intval($this->dataRecord["server_id"]) > 0) {
+				// check if server is in client's servers or add it.
+				$chk_sid = explode(',', $client['web_servers']);
+				if(in_array($this->dataRecord["server_id"], $client['web_servers']) == false) {
+					if($client['web_servers'] != '') $client['web_servers'] .= ',';
+					$client['web_servers'] .= $app->functions->intval($this->dataRecord["server_id"]);
+				}
+			}
+			
 			//* Fill the IPv4 select field with the IP addresses that are allowed for this client
 			$sql = "SELECT ip_address FROM server_ip WHERE server_id IN (" . $client['web_servers'] . ") AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")";
 			$ips = $app->db->queryAllRecords($sql);
 			$ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":"";
+			//if(!in_array($this->dataRecord["ip_address"], $ips)) $ip_select .= "<option value='".$this->dataRecord["ip_address"]."' SELECTED>".$this->dataRecord["ip_address"]."</option>\r\n";
 			//$ip_select = "";
 			if(is_array($ips)) {
 				foreach( $ips as $ip) {
@@ -234,10 +244,20 @@
 			}
 			$app->tpl->setVar("client_group_id", $client_select);
 
+			if($app->functions->intval($this->dataRecord["server_id"]) > 0) {
+				// check if server is in client's servers or add it.
+				$chk_sid = explode(',', $client['web_servers']);
+				if(in_array($this->dataRecord["server_id"], $client['web_servers']) == false) {
+					if($client['web_servers'] != '') $client['web_servers'] .= ',';
+					$client['web_servers'] .= $app->functions->intval($this->dataRecord["server_id"]);
+				}
+			}
+			
 			//* Fill the IPv4 select field with the IP addresses that are allowed for this client
 			$sql = "SELECT ip_address FROM server_ip WHERE server_id IN (" . $client['web_servers'] . ") AND ip_type = 'IPv4' AND (client_id = 0 OR client_id=".$_SESSION['s']['user']['client_id'].")";
 			$ips = $app->db->queryAllRecords($sql);
 			$ip_select = ($web_config['enable_ip_wildcard'] == 'y')?"<option value='*'>*</option>":"";
+			//if(!in_array($this->dataRecord["ip_address"], $ips)) $ip_select .= "<option value='".$this->dataRecord["ip_address"]."' SELECTED>".$this->dataRecord["ip_address"]."</option>\r\n";
 			//$ip_select = "";
 			if(is_array($ips)) {
 				foreach( $ips as $ip) {
diff --git a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_advanced.htm b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_advanced.htm
index 8710740..289339b 100644
--- a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_advanced.htm
+++ b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_advanced.htm
@@ -82,8 +82,8 @@
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
         <div class="buttonHolder buttons">
-            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
-            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_vhost_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_vhost_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
         </div>
     </div>
 
diff --git a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_backup.htm b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_backup.htm
index c46d4e2..1784e24 100644
--- a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_backup.htm
+++ b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_backup.htm
@@ -24,8 +24,8 @@
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
         <div class="buttonHolder buttons">
-            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
-            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_vhost_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_vhost_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
         </div>
     </div>
 
diff --git a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_redirect.htm b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_redirect.htm
index 66a1703..eb059e2 100644
--- a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_redirect.htm
+++ b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_redirect.htm
@@ -26,8 +26,8 @@
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
         <div class="buttonHolder buttons">
-            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
-            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_vhost_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_vhost_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
         </div>
     </div>
 
diff --git a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_ssl.htm b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_ssl.htm
index 4c27bb7..b4c0357 100644
--- a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_ssl.htm
+++ b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_ssl.htm
@@ -60,8 +60,8 @@
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
         <div class="buttonHolder buttons">
-            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
-            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_vhost_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_vhost_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
         </div>
     </div>
 
diff --git a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_stats.htm b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_stats.htm
index 26eee94..8234422 100644
--- a/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_stats.htm
+++ b/interface/web/themes/default-304/templates/sites/web_vhost_subdomain_stats.htm
@@ -29,8 +29,8 @@
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
         <div class="buttonHolder buttons">
-            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_domain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
-            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_domain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
+            <button class="positive iconstxt icoPositive" type="button" value="{tmpl_var name='btn_save_txt'}" onClick="submitForm('pageForm','sites/web_vhost_subdomain_edit.php');"><span>{tmpl_var name='btn_save_txt'}</span></button>
+            <button class="negative iconstxt icoNegative" type="button" value="{tmpl_var name='btn_cancel_txt'}" onClick="loadContent('sites/web_vhost_subdomain_list.php');"><span>{tmpl_var name='btn_cancel_txt'}</span></button>
         </div>
     </div>
 
diff --git a/server/conf/apache_apps.vhost.master b/server/conf/apache_apps.vhost.master
index ff6d4da..49f829a 100644
--- a/server/conf/apache_apps.vhost.master
+++ b/server/conf/apache_apps.vhost.master
@@ -4,38 +4,46 @@
 # for the ISPConfig apps vhost
 ######################################################
 
-{vhost_port_listen} Listen {apps_vhost_port}
-# NameVirtualHost *:{apps_vhost_port}
+{tmpl_var name='vhost_port_listen'} Listen {tmpl_var name='apps_vhost_port'}
+# NameVirtualHost *:{tmpl_var name='apps_vhost_port'}
 
-<VirtualHost {apps_vhost_ip}:{apps_vhost_port}>
+<VirtualHost {tmpl_var name='apps_vhost_ip'}:{tmpl_var name='apps_vhost_port'}>
   ServerAdmin webmaster@localhost
-  {apps_vhost_servername}
+  {tmpl_var name='apps_vhost_servername'}
   
   <FilesMatch "\.ph(p3?|tml)$">
     SetHandler None
   </FilesMatch>
   
   <IfModule mod_php5.c>
-    DocumentRoot {apps_vhost_dir}
+    DocumentRoot {tmpl_var name='apps_vhost_dir'}
     AddType application/x-httpd-php .php
-    <Directory {apps_vhost_dir}>
-      Options FollowSymLinks
-      AllowOverride None
-      Order allow,deny
-      Allow from all
+    <Directory {tmpl_var name='apps_vhost_dir'}>
+		Options FollowSymLinks
+		AllowOverride None
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
+		Order allow,deny
+		Allow from all
+		{/tmpl_if}
     </Directory>
   </IfModule>
   
   <IfModule mod_fcgid.c>
-    DocumentRoot {apps_vhost_dir}
+    DocumentRoot {tmpl_var name='apps_vhost_dir'}
     SuexecUserGroup ispapps ispapps
-    <Directory {apps_vhost_dir}>
-      Options Indexes FollowSymLinks MultiViews +ExecCGI
-      AllowOverride AuthConfig Indexes Limit Options FileInfo
-      AddHandler fcgid-script .php
-      FCGIWrapper {apps_vhost_basedir}/php-fcgi-scripts/apps/.php-fcgi-starter .php
-      Order allow,deny
-      Allow from all
+    <Directory {tmpl_var name='apps_vhost_dir'}>
+		Options Indexes FollowSymLinks MultiViews +ExecCGI
+		AllowOverride AuthConfig Indexes Limit Options FileInfo
+		AddHandler fcgid-script .php
+		FCGIWrapper {tmpl_var name='apps_vhost_basedir'}/php-fcgi-scripts/apps/.php-fcgi-starter .php
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
+		Order allow,deny
+		Allow from all
+		{/tmpl_if}
     </Directory>
   </IfModule>
 
diff --git a/server/conf/apache_ispconfig.conf.master b/server/conf/apache_ispconfig.conf.master
index 5fb0f2c..a615198 100644
--- a/server/conf/apache_ispconfig.conf.master
+++ b/server/conf/apache_ispconfig.conf.master
@@ -8,61 +8,100 @@
 
 <Directory /var/www/clients>
     AllowOverride None
-    Order Deny,Allow
-    Deny from all
+	{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+	Require all deny
+	{tmpl_else}
+	Order Deny,Allow
+	Deny from all
+	{/tmpl_if}
 </Directory>
 
 # Do not allow access to the root file system of the server for security reasons
 <Directory />
     AllowOverride None
-    Order Deny,Allow
-    Deny from all
+	{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+	Require all deny
+	{tmpl_else}
+	Order Deny,Allow
+	Deny from all
+	{/tmpl_if}
 </Directory>
 
 <Directory /var/www/conf>
     AllowOverride None
-    Order Deny,Allow
-    Deny from all
+	{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+	Require all deny
+	{tmpl_else}
+	Order Deny,Allow
+	Deny from all
+	{/tmpl_if}
 </Directory>
 
 # Except of the following directories that contain website scripts
 <Directory /usr/share/phpmyadmin>
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
         Order allow,deny
         Allow from all
+		{/tmpl_if}
 </Directory>
 
 <Directory /usr/share/phpMyAdmin>
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
         Order allow,deny
         Allow from all
+		{/tmpl_if}
 </Directory>
 
 <Directory /usr/share/squirrelmail>
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
         Order allow,deny
         Allow from all
+		{/tmpl_if}
 </Directory>
 
 # Allow access to mailman on OpenSuSE
 <Directory /usr/lib/mailman/cgi-bin>
-        AllowOverride All
-		order allow,deny
-        allow from all
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
+        Order allow,deny
+        Allow from all
+		{/tmpl_if}
 </Directory>
 
 <Directory /usr/lib/mailman/icons>
-        order allow,deny
-        allow from all
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
+        Order allow,deny
+        Allow from all
+		{/tmpl_if}
 </Directory>
 
 <Directory /var/lib/mailman/archives/>
         Options +FollowSymLinks
-        order allow,deny
-        allow from all
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
+        Order allow,deny
+        Allow from all
+		{/tmpl_if}
 </Directory>
 
 # allow path to awstats and alias for awstats icons
 <Directory /usr/share/awstats>
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all granted
+		{tmpl_else}
         Order allow,deny
         Allow from all
+		{/tmpl_if}
 </Directory>
 
 Alias /awstats-icon "/usr/share/awstats/icon"
diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master
index 5d74512..0f8a79a 100644
--- a/server/conf/vhost.conf.master
+++ b/server/conf/vhost.conf.master
@@ -1,8 +1,12 @@
 
 <Directory {tmpl_var name='web_basedir'}/{tmpl_var name='domain'}>
 		AllowOverride None
+		{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+		Require all deny
+		{tmpl_else}
 		Order Deny,Allow
 		Deny from all
+		{/tmpl_if}
 </Directory>
 
 <tmpl_loop name="vhosts">
@@ -55,8 +59,12 @@
 		<Directory {tmpl_var name='web_document_root_www'}>
 				Options FollowSymLinks
 				AllowOverride <tmpl_var name='allow_override'>
+				{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+				Require all granted
+				{tmpl_else}
 				Order allow,deny
 				Allow from all
+				{/tmpl_if}
 <tmpl_if name='ssi' op='==' value='y'>
 
 				# ssi enabled
@@ -66,17 +74,25 @@
 </tmpl_if>
 <tmpl_if name='php' op='==' value='no'>
 				<Files ~ '.php[s3-6]{0,1}$'>
+						{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+						Require all denied
+						{tmpl_else}
 						Order allow,deny
 						Deny from all
 						Allow from none
+						{/tmpl_if}
 				</Files>
 </tmpl_if>
 		</Directory>
 		<Directory {tmpl_var name='web_document_root'}>
 				Options FollowSymLinks
 				AllowOverride <tmpl_var name='allow_override'>
+				{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+				Require all granted
+				{tmpl_else}
 				Order allow,deny
 				Allow from all
+				{/tmpl_if}
 <tmpl_if name='ssi' op='==' value='y'>
 
 				# ssi enabled
@@ -86,9 +102,13 @@
 </tmpl_if>
 <tmpl_if name='php' op='==' value='no'>
 				<Files ~ '.php[s3-6]{0,1}$'>
-						Order allow,deny
-						Deny from all
-						Allow from none
+					{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+					Require all denied
+					{tmpl_else}
+					Order allow,deny
+					Deny from all
+					Allow from none
+					{/tmpl_if}
 				</Files>
 </tmpl_if>
 		</Directory>
@@ -141,8 +161,12 @@
 <tmpl_if name='cgi' op='==' value='y'>
 		# cgi enabled
 	<Directory {tmpl_var name='document_root'}/cgi-bin>
+			{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+			Require all granted
+			{tmpl_else}
 			Order allow,deny
 			Allow from all
+			{/tmpl_if}
 		</Directory>
 		ScriptAlias  /cgi-bin/ <tmpl_var name='document_root'>/cgi-bin/
 		AddHandler cgi-script .cgi
@@ -189,8 +213,12 @@
 		Action php5-cgi /php5-cgi
 		AddHandler php5-cgi .php .php3 .php4 .php5
 		<Directory {tmpl_var name='cgi_starter_path'}>
-				Order allow,deny
-				Allow from all
+			{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+			Require all granted
+			{tmpl_else}
+			Order allow,deny
+			Allow from all
+			{/tmpl_if}
 		</Directory>
 </tmpl_if>
 <tmpl_if name='php' op='==' value='fast-cgi'>
@@ -224,23 +252,35 @@
 				FCGIWrapper <tmpl_var name='fastcgi_starter_path'><tmpl_var name='fastcgi_starter_script'> .php
 				Options +ExecCGI
 				AllowOverride <tmpl_var name='allow_override'>
+				{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+				Require all granted
+				{tmpl_else}
 				Order allow,deny
 				Allow from all
+				{/tmpl_if}
 		</Directory>
 		<Directory {tmpl_var name='web_document_root'}>
 				AddHandler fcgid-script .php .php3 .php4 .php5
 				FCGIWrapper <tmpl_var name='fastcgi_starter_path'><tmpl_var name='fastcgi_starter_script'> .php
 				Options +ExecCGI
 				AllowOverride <tmpl_var name='allow_override'>
+				{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+				Require all granted
+				{tmpl_else}
 				Order allow,deny
 				Allow from all
+				{/tmpl_if}
 		</Directory>
 </tmpl_if>
 <tmpl_if name='php' op='==' value='php-fpm'>
 		<IfModule mod_fastcgi.c>
 				<Directory {tmpl_var name='document_root'}/cgi-bin>
-						Order allow,deny
-						Allow from all
+					{tmpl_if name='apache_version' op='>' value='2.2' format='version'}
+					Require all granted
+					{tmpl_else}
+					Order allow,deny
+					Allow from all
+					{/tmpl_if}
 			    </Directory>
                 AddHandler php5-fcgi .php
                 Action php5-fcgi /php5-fcgi
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 9b7d994..6ee9555 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -899,7 +899,7 @@
 
 		//* We allow only some characters in the path
 		// * is allowed, for example it is part of wildcard certificates/keys: *.example.com.crt
-		if(!preg_match('@^/[-a-zA-Z0-9_/.*~]{1,}$@', $path)) return false;
+		if(!preg_match('@^/[-a-zA-Z0-9_/.*]{1,}[~]?$@', $path)) return false;
 
 		//* Check path for symlinks
 		$path_parts = explode('/', $path);
@@ -1524,7 +1524,7 @@
 		}
 	}
 
-	function maildirmake($maildir_path, $user = '', $group = '', $subfolder = '') {
+	function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
 
 		global $app;
 
@@ -1774,6 +1774,31 @@
 		if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1);
 		return $init_script_directory.'/'.$servicename.' '.$action;
 	}
+	
+	function getapacheversion($get_minor = false) {
+		global $app;
+		
+		$cmd = '';
+		if($this->is_installed('apache2ctl')) $cmd = 'apache2ctl -v';
+		elseif($this->is_installed('apachectl')) $cmd = 'apachectl -v';
+		else {
+			$app->log("Could not check apache version, apachectl not found.", LOGLEVEL_WARN);
+			return '2.2';
+		}
+		
+		exec($cmd, $output, $return_var);
+		if($return_var != 0 || !$output[0]) {
+			$app->log("Could not check apache version, apachectl did not return any data.", LOGLEVEL_WARN);
+			return '2.2';
+		}
+		
+		if(preg_match('/version:\s*Apache\/(\d+)(\.(\d+)(\.(\d+))*)?(\D|$)/i', $output[0], $matches)) {
+			return $matches[1] . (isset($matches[3]) ? '.' . $matches[3] : '') . (isset($matches[5]) && $get_minor == true ? '.' . $matches[5] : '');
+		} else {
+			$app->log("Could not check apache version, did not find version string in apachectl output.", LOGLEVEL_WARN);
+			return '2.2';
+		}
+	}
 
 }
 
diff --git a/server/lib/classes/tpl.inc.php b/server/lib/classes/tpl.inc.php
index deb9ca1..2a91b06 100644
--- a/server/lib/classes/tpl.inc.php
+++ b/server/lib/classes/tpl.inc.php
@@ -932,7 +932,7 @@
 
 				$regex = '/(<|<\/|{|{\/|<!--|<!--\/){1}\s*';
 				$regex.= 'tmpl_([\w]+)\s*';
-				$regex.= '(?:';
+				$regex.= '((?:(?:';
 				$regex.=    '(?:';
 				$regex.=        '(name|format|escape|op|value|file)';
 				$regex.=        '\s*=\s*';
@@ -941,30 +941,9 @@
 				$regex.=    '((?<=[\"\'])';
 				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
 				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
-				$regex.= '(?:';
-				$regex.=    '(?:';
-				$regex.=        '(name|format|escape|op|value)';
-				$regex.=        '\s*=\s*';
-				$regex.=    ')';
-				$regex.=    '(?:[\"\'])?';
-				$regex.=    '((?<=[\"\'])';
-				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
-				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
-				$regex.= '(?:';
-				$regex.=    '(?:';
-				$regex.=        '(name|format|escape|op|value)';
-				$regex.=        '\s*=\s*';
-				$regex.=    ')';
-				$regex.=    '(?:[\"\'])?';
-				$regex.=    '((?<=[\"\'])';
-				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
-				$regex.=    '[\"\']?';
-				$regex.= ')?\s*';
+				$regex.= ')?\s*)*?)';
 				$regex.= '(?:>|\/>|}|-->){1}';
 				$regex.= '/i';
-				//$regex.= '([\r\n|\n|\r])?/ie';
 				$data = preg_replace_callback($regex, array($this, '_parseTag'), $data);
 
 				if ($this->_cache) { // add cache if need be
@@ -1109,7 +1088,7 @@
 		 * @access private
 		 * @return string used for eval'ing
 		 */
-		function _parseIf ($varname, $value=null, $op=null, $namespace=null) {
+		function _parseIf ($varname, $value=null, $op=null, $namespace=null, $format=null) {
 			if (isset($namespace)) $namespace = substr($namespace, 0, -1);
 			$comp_str = ''; // used for extended if statements
 
@@ -1151,10 +1130,19 @@
 				}
 			}
 			if ($this->OPTIONS['GLOBAL_VARS'] && empty($namespace)) {
-				return '(('.$retstr.'[\''.$varname.'\'] !== null) ? '.$retstr.'[\''.$varname.'\'] : $this->_vars[\''.$varname.'\'])'.$comp_str;
+				$retstr = '(('.$retstr.'[\''.$varname.'\'] !== null) ? '.$retstr.'[\''.$varname.'\'] : $this->_vars[\''.$varname.'\'])';
+				if(isset($format) && isset($value) && $format == 'version') {
+					return 'version_compare(' . $retstr . ', \'' . $value . '\', ' . (!empty($op) ? $op : '==') . ')';
+				} else {
+					return $retstr.$comp_str;
+				}
 			}
 			else {
-				return $retstr."['".$varname."']".$comp_str;
+				if(isset($format) && isset($value) && $format == 'version') {
+					return 'version_compare(' . $retstr."['".$varname."']" . ', \'' . $value . '\', ' . (!empty($op) ? $op : '==') . ')';
+				} else {
+					return $retstr."['".$varname."']".$comp_str;
+				}
 			}
 		}
 
@@ -1281,28 +1269,37 @@
 			$wholetag = $args[0];
 			$openclose = $args[1];
 			$tag = strtolower($args[2]);
-			$newline = $args[9];
-			//echo "1#$newline#2";
-
-			if ($tag == 'else') return '<?php } else { ?>'.$newline;
+			
+			if ($tag == 'else') return '<?php } else { ?>';
 			if ($tag == 'tmpl_include') return $wholetag; // ignore tmpl_include tags
 
 			if (preg_match("/^<\/|{\/|<!--\/$/s", $openclose) || preg_match("/^end[if|loop|unless|comment]$/", $tag)) {
 				if ($tag == 'loop' || $tag == 'endloop') array_pop($this->_namespace);
 				if ($tag == 'comment' || $tag == 'endcomment') {
-					return '<?php */ ?>'.$newline;
+					return '<?php */ ?>';
 				}
 				else {
-					return '<?php } ?>'.$newline;
+					return '<?php } ?>';
 				}
 			}
 
 			// arrange attributes
-			for ($i=3; $i < 8; $i=($i+2)) {
-				if (empty($args[$i]) && empty($args[($i+1)])) break;
-				$key = (empty($args[$i])) ? 'name' : strtolower($args[$i]);
-				if ($key == 'name' && preg_match('/^(php)?include$/', $tag)) $key = 'file';
-				$$key = $args[($i+1)];
+			$tmp_atts = $args[3];
+			$atts = preg_split('/\s+/', $tmp_atts);
+			foreach($atts as $att) {
+				$regex =    '/(?:';
+				$regex.=        '(name|format|escape|op|value|file)';
+				$regex.=        '\s*=\s*';
+				$regex.=    ')?';
+				$regex.=    '(?:[\"\'])?';
+				$regex.=    '((?<=[\"\'])';
+				$regex.=    '[^\"\']*|[a-z0-9_\.]*)';
+				$regex.=    '[\"\']?/';
+				if(preg_match($regex, $att, $match)) {
+					$key = (empty($match[1])) ? 'name' : strtolower($match[1]);
+					if ($key == 'name' && preg_match('/^(php)?include$/', $tag)) $key = 'file';
+					$$key = $match[2];
+				}
 			}
 
 			$var = ($this->OPTIONS['CASELESS']) ? strtolower($name) : $name;
@@ -1326,28 +1323,28 @@
 				if (empty($escape) && (!empty($this->OPTIONS['DEFAULT_ESCAPE']) && strtolower($this->OPTIONS['DEFAULT_ESCAPE']) != 'none')) {
 					$escape = strtolower($this->OPTIONS['DEFAULT_ESCAPE']);
 				}
-				return '<?php '.$this->_parseVar ($wholetag, $tag, $var, @$escape, @$format, @$namespace).' ?>'.$newline."\n";
+				return '<?php '.$this->_parseVar ($wholetag, $tag, $var, @$escape, @$format, @$namespace).' ?>'."\n";
 				break;
 
 			case 'if':
-				return '<?php if ('. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php if ('. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
 				break;
 
 			case 'unless':
-				return '<?php if (!'. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php if (!'. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
 				break;
 
 			case 'elseif':
-				return '<?php } elseif ('. $this->_parseIf($var, @$value, @$op, @$namespace) .') { ?>'.$newline;
+				return '<?php } elseif ('. $this->_parseIf($var, @$value, @$op, @$namespace, @$format) .') { ?>';
 				break;
 
 			case 'loop':
-				return '<?php '. $this->_parseLoop($var) .'?>'.$newline;
+				return '<?php '. $this->_parseLoop($var) .'?>';
 				break;
 
 			case 'comment':
 				if (empty($var)) { // full open/close style comment
-					return '<?php /* ?>'.$newline;
+					return '<?php /* ?>';
 				}
 				else { // just ignore tag if it was a one line comment
 					return;
@@ -1356,7 +1353,7 @@
 
 			case 'phpinclude':
 				if ($this->OPTIONS['ENABLE_PHPINCLUDE']) {
-					return '<?php include(\''.$file.'\'); ?>'.$newline;
+					return '<?php include(\''.$file.'\'); ?>';
 				}
 				break;
 
diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index 6267217..8940cfd 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -1021,6 +1021,7 @@
 		}
 
 		$tpl->setVar($vhost_data);
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
 
 		// Rewrite rules
 		$rewrite_rules = array();
@@ -1227,6 +1228,7 @@
 
 			$fcgi_tpl = new tpl();
 			$fcgi_tpl->newTemplate('php-fcgi-starter.master');
+			$fcgi_tpl->setVar('apache_version', $app->system->getapacheversion());
 
 			// Support for multiple PHP versions (FastCGI)
 			if(trim($data['new']['fastcgi_php_version']) != ''){
@@ -1366,6 +1368,7 @@
 
 			$cgi_tpl = new tpl();
 			$cgi_tpl->newTemplate('php-cgi-starter.master');
+			$cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
 
 			// This works because PHP "rewrites" a symlink to the physical path
 			$php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
@@ -2030,6 +2033,7 @@
 
 		$tpl = new tpl();
 		$tpl->newTemplate('apache_ispconfig.conf.master');
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
 		$records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
 
 		$records_out= array();
@@ -2739,7 +2743,8 @@
 		$app->load('tpl');
 		$tpl = new tpl();
 		$tpl->newTemplate('php_fpm_pool.conf.master');
-
+		$tpl->setVar('apache_version', $app->system->getapacheversion());
+		
 		if($data['new']['php_fpm_use_socket'] == 'y'){
 			$use_tcp = 0;
 			$use_socket = 1;
diff --git a/server/plugins-available/apps_vhost_plugin.inc.php b/server/plugins-available/apps_vhost_plugin.inc.php
index 8251863..320f3d0 100644
--- a/server/plugins-available/apps_vhost_plugin.inc.php
+++ b/server/plugins-available/apps_vhost_plugin.inc.php
@@ -80,13 +80,12 @@
 		$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
 
 		if($web_config['server_type'] == 'apache'){
-			// Dont just copy over the virtualhost template but add some custom settings
-			if(file_exists($conf["rootpath"]."/conf-custom/apache_apps.vhost.master")) {
-				$content = file_get_contents($conf["rootpath"]."/conf-custom/apache_apps.vhost.master");
-			} else {
-				$content = file_get_contents($conf["rootpath"]."/conf/apache_apps.vhost.master");
-			}
+			$app->load('tpl');
 
+			$tpl = new tpl();
+			$tpl->newTemplate('apache_apps.vhost.master');
+
+			$tpl->setVar('apache_version', $app->system->getapacheversion());
 
 			$vhost_conf_dir = $web_config['vhost_conf_dir'];
 			$vhost_conf_enabled_dir = $web_config['vhost_conf_enabled_dir'];
@@ -95,21 +94,31 @@
 			$web_config['apps_vhost_port'] = (empty($web_config['apps_vhost_port']))?8081:$web_config['apps_vhost_port'];
 			$web_config['apps_vhost_ip'] = (empty($web_config['apps_vhost_ip']))?'_default_':$web_config['apps_vhost_ip'];
 
+			$tpl->setVar('apps_vhost_ip', $web_config['apps_vhost_ip']);
+			$tpl->setVar('apps_vhost_port', $web_config['apps_vhost_port']);
+			$tpl->setVar('apps_vhost_dir', $web_config['website_basedir'].'/apps');
+			$tpl->setVar('apps_vhost_servername', $apps_vhost_servername);
+			$tpl->setVar('apps_vhost_basedir', $web_config['website_basedir']);
+
+			$vhost_port_listen = '';
+			// comment out the listen directive if port is 80 or 443
+			if($web_config['apps_vhost_port'] == 80 or $web_config['apps_vhost_port'] == 443) {
+				$vhost_port_listen = '#';
+			}
+			$tpl->setVar('vhost_port_listen', $vhost_port_listen);
+
+			$content = $tpl->grab();
+
+			/* for backwards compatibility we replace the old syntax by hand now */
 			$content = str_replace('{apps_vhost_ip}', $web_config['apps_vhost_ip'], $content);
 			$content = str_replace('{apps_vhost_port}', $web_config['apps_vhost_port'], $content);
 			$content = str_replace('{apps_vhost_dir}', $web_config['website_basedir'].'/apps', $content);
 			$content = str_replace('{apps_vhost_servername}', $apps_vhost_servername, $content);
 			$content = str_replace('{apps_vhost_basedir}', $web_config['website_basedir'], $content);
+			$content = str_replace('{vhost_port_listen}', $vhost_port_listen, $content);
+			/* end of backwards compatibility section */
 
-
-			// comment out the listen directive if port is 80 or 443
-			if($web_config['apps_vhost_port'] == 80 or $web_config['apps_vhost_port'] == 443) {
-				$content = str_replace('{vhost_port_listen}', '#', $content);
-			} else {
-				$content = str_replace('{vhost_port_listen}', '', $content);
-			}
-
-			file_put_contents("$vhost_conf_dir/apps.vhost", $content);
+			$app->system->file_put_contents("$vhost_conf_dir/apps.vhost", $content);
 			$app->services->restartServiceDelayed('httpd', 'restart');
 		}
 
diff --git a/server/plugins-available/mail_plugin.inc.php b/server/plugins-available/mail_plugin.inc.php
index 72b69a3..c5f1392 100644
--- a/server/plugins-available/mail_plugin.inc.php
+++ b/server/plugins-available/mail_plugin.inc.php
@@ -93,7 +93,7 @@
 		$base_path = implode('/', $tmp_basepath_parts);
 
 		//* Set the email-uid and gid if not given
-		if (($data['new']['uid'] == 999989999) || ($data['new']['gid'] == 999989999)) {
+		if (($data['new']['uid'] == -1) || ($data['new']['gid'] == -1)) {
 			$app->log('Setting uid and gid automatically',LOGLEVEL_DEBUG);
 			if ($mail_config["mailbox_virtual_uidgid_maps"] == 'y') {
 				$app->log('Map uid to linux-user',LOGLEVEL_DEBUG);
@@ -113,8 +113,8 @@
 			}
 		}
 		// if nothing set before -> use standard mailuser uid and gid vmail
-		if ($data['new']['uid'] == 999989999) $data['new']['uid'] = $mail_config["mailuser_uid"];
-		if ($data['new']['gid'] == 999989999) $data['new']['gid'] = $mail_config["mailuser_gid"];
+		if ($data['new']['uid'] == -1) $data['new']['uid'] = $mail_config["mailuser_uid"];
+		if ($data['new']['gid'] == -1) $data['new']['gid'] = $mail_config["mailuser_gid"];
 		$app->log('Mailuser uid: '.$data['new']['uid'].', gid: '.$data['new']['gid'],LOGLEVEL_DEBUG);
 
 		// update DB if values changed
@@ -148,7 +148,7 @@
 		if(!empty($maildomain_path) && !is_dir($maildomain_path)) {
 
 			//exec("su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
-			$app->system->maildirmake($maildomain_path, $user, $group);
+			$app->system->maildirmake($maildomain_path, $user, '', $group);
 
 			//* This is to fix the maildrop quota not being rebuilt after the quota is changed.
 			if($mail_config['pop3_imap_daemon'] != 'dovecot') {
@@ -160,22 +160,22 @@
 		if(!is_dir($data['new']['maildir'].'/.Sent')) {
 			//exec("su -c 'maildirmake -f Sent ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Sent: '."su -c 'maildirmake -f Sent ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Sent');
+			$app->system->maildirmake($maildomain_path, $user, 'Sent', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Drafts')) {
 			//exec("su -c 'maildirmake -f Drafts ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Drafts: '."su -c 'maildirmake -f Drafts ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Drafts');
+			$app->system->maildirmake($maildomain_path, $user, 'Drafts', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Trash')) {
 			//exec("su -c 'maildirmake -f Trash ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Trash: '."su -c 'maildirmake -f Trash ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Trash');
+			$app->system->maildirmake($maildomain_path, $user, 'Trash', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Junk')) {
 			//exec("su -c 'maildirmake -f Junk ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Junk: '."su -c 'maildirmake -f Junk ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Junk');
+			$app->system->maildirmake($maildomain_path, $user, 'Junk', $group);
 		}
 
 		// Set permissions now recursive
@@ -284,7 +284,7 @@
 		if(!empty($maildomain_path) && !is_dir($maildomain_path.'/new')) {
 			//exec("su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log("Created Maildir "."su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group);
+			$app->system->maildirmake($maildomain_path, $user, '', $group);
 
 			//* This is to fix the maildrop quota not being rebuilt after the quota is changed.
 			if($mail_config['pop3_imap_daemon'] != 'dovecot') {
@@ -301,22 +301,22 @@
 		if(!is_dir($data['new']['maildir'].'/.Sent')) {
 			//exec("su -c 'maildirmake -f Sent ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Sent: '."su -c 'maildirmake -f Sent ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Sent');
+			$app->system->maildirmake($maildomain_path, $user, 'Sent', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Drafts')) {
 			//exec("su -c 'maildirmake -f Drafts ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Drafts: '."su -c 'maildirmake -f Drafts ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Drafts');
+			$app->system->maildirmake($maildomain_path, $user, 'Drafts', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Trash')) {
 			//exec("su -c 'maildirmake -f Trash ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Trash: '."su -c 'maildirmake -f Trash ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Trash');
+			$app->system->maildirmake($maildomain_path, $user, 'Trash', $group);
 		}
 		if(!is_dir($data['new']['maildir'].'/.Junk')) {
 			//exec("su -c 'maildirmake -f Junk ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']);
 			//$app->log('Created submaildir Junk: '."su -c 'maildirmake -f Junk ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG);
-			$app->system->maildirmake($maildomain_path, $user, $group, 'Junk');
+			$app->system->maildirmake($maildomain_path, $user, 'Junk', $group);
 		}
 
 		// Set permissions now recursive
diff --git a/server/plugins-available/maildeliver_plugin.inc.php b/server/plugins-available/maildeliver_plugin.inc.php
index 7ff4a72..c5b531d 100644
--- a/server/plugins-available/maildeliver_plugin.inc.php
+++ b/server/plugins-available/maildeliver_plugin.inc.php
@@ -208,8 +208,9 @@
 			if ( ! is_dir($data["new"]["maildir"].'/sieve/') ) {
 				$app->system->mkdirpath($data["new"]["maildir"].'/sieve/', 0700, $mail_config['mailuser_name'], $mail_config['mailuser_group']);
 			}
+			file_put_contents($sieve_file, $tpl->grab());
+			exec('chown '.$mail_config['mailuser_name'].':'.$mail_config['mailuser_group'].' '.escapeshellcmd($sieve_file));
 
-			file_put_contents($sieve_file_isp, $tpl->grab());
 			chown($sieve_file_isp,$mail_config['mailuser_name']);
 			chgrp($sieve_file_isp,$mail_config['mailuser_group']);
 			chdir($data["new"]["maildir"]);

--
Gitblit v1.9.1