diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php
index 8d1a02e3203617e0830391e92c06ea1bb7aea1e3..115b199c7c9214dae2b02513ea64cc334a21c7eb 100644
--- a/install/lib/installer_base.lib.php
+++ b/install/lib/installer_base.lib.php
@@ -33,7 +33,6 @@ class installer_base {
 	var $wb = array();
 	var $language = 'en';
 	var $db;
-	public $conf;
 	public $install_ispconfig_interface = true;
 	public $is_update = false; // true if it is an update, falsi if it is a new install
 	public $min_php = '5.3.3'; // minimal php-version for update / install
@@ -42,7 +41,6 @@ class installer_base {
 
 	public function __construct() {
 		global $conf; //TODO: maybe $conf  should be passed to constructor
-		//$this->conf = $conf;
 	}
 
 	//: TODO  Implement the translation function and language files for the installer.
diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..819c9f0f7e5ca9c1ea84308de403743505cdd2ba 100644
--- a/install/sql/incremental/upd_dev_collection.sql
+++ b/install/sql/incremental/upd_dev_collection.sql
@@ -0,0 +1,5 @@
+ALTER TABLE `web_domain` ADD  `jailkit_chroot_app_sections` mediumtext NULL DEFAULT NULL;
+ALTER TABLE `web_domain` ADD  `jailkit_chroot_app_programs` mediumtext NULL DEFAULT NULL;
+ALTER TABLE `web_domain` ADD  `delete_unused_jailkit` enum('n','y') NOT NULL DEFAULT 'n';
+ALTER TABLE `web_domain` ADD  `last_jailkit_update` date NULL DEFAULT NULL;
+ALTER TABLE `web_domain` ADD  `last_jailkit_hash` varchar(255) DEFAULT NULL;
diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 2901bb5af876f4643fae90caba7d242b354f706d..67f0f3bdcbcb82ca3fea33a4540f77ba82fb23c7 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -2084,6 +2084,11 @@ CREATE TABLE `web_domain` (
   `log_retention` int(11) NOT NULL DEFAULT '10',
   `proxy_protocol` enum('n','y') NOT NULL default 'n',
   `server_php_id` INT(11) UNSIGNED NOT NULL DEFAULT 0,
+  `jailkit_chroot_app_sections` mediumtext NULL DEFAULT NULL,
+  `jailkit_chroot_app_programs` mediumtext NULL DEFAULT NULL,
+  `delete_unused_jailkit` enum('n','y') NOT NULL default 'n',
+  `last_jailkit_update` date NULL DEFAULT NULL,
+  `last_jailkit_hash` varchar(255) DEFAULT NULL,
   PRIMARY KEY  (`domain_id`),
   UNIQUE KEY `serverdomain` (  `server_id` , `ip_address`,  `domain` )
 ) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master
index c500fb0cc28f1320b33b868febea26fc7e730755..4d65fe934f4d7d59cdf054957a563fcfc3d6b151 100644
--- a/install/tpl/server.ini.master
+++ b/install/tpl/server.ini.master
@@ -146,6 +146,7 @@ jailkit_chroot_app_sections=basicshell editors extendedshell netutils ssh sftp s
 jailkit_chroot_app_programs=/usr/bin/groups /usr/bin/id /usr/bin/dircolors /usr/bin/lesspipe /usr/bin/basename /usr/bin/dirname /usr/bin/nano /usr/bin/pico /usr/bin/mysql /usr/bin/mysqldump /usr/bin/git /usr/bin/git-receive-pack /usr/bin/git-upload-pack /usr/bin/unzip /usr/bin/zip /bin/tar /bin/rm /usr/bin/patch /usr/bin/which /usr/lib/x86_64-linux-gnu/libmemcached.so.11 /usr/lib/x86_64-linux-gnu/libmemcachedutil.so.2 /usr/lib/x86_64-linux-gnu/libMagickWand-6.Q16.so.2 /opt/php-5.6.8/bin/php /opt/php-5.6.8/include /opt/php-5.6.8/lib
 jailkit_chroot_cron_programs=/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php
 jailkit_chroot_authorized_keys_template=/root/.ssh/authorized_keys
+jailkit_hardlinks=allow
 
 [vlogger]
 config_dir=/etc
diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php
index 47aa517de8d76e347ead06db8a6ea7c12c6996d2..751edcf024ce8d70b157bf74af4e2b45e2ac859c 100644
--- a/interface/lib/classes/remoting.inc.php
+++ b/interface/lib/classes/remoting.inc.php
@@ -59,11 +59,6 @@ class remoting {
 		$app->uses('remoting_lib');
 
 		$this->_methods = $methods;
-
-		/*
-        $this->app = $app;
-        $this->conf = $conf;
-		*/
 	}
 
 	//* remote login function
diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php
index bc2f05840bf441d5cd6fab35a2c221e94a665920..6ecda7872fbdd267a526329270d2b8b0b581868b 100644
--- a/interface/web/admin/form/server_config.tform.php
+++ b/interface/web/admin/form/server_config.tform.php
@@ -1845,6 +1845,16 @@ $form["tabs"]['jailkit'] = array(
 			'width' => '40',
 			'maxlength' => '1000'
 		),
+		'jailkit_hardlinks' => array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'SELECT',
+			'default' => 'allow',
+			'value' => array(
+				'allow' => 'jailkit_hardlinks_allow_txt',
+				'no' => 'jailkit_hardlinks_no_txt',
+				'yes' => 'jailkit_hardlinks_yes_txt',
+			)
+		),
 		//#################################
 		// END Datatable fields
 		//#################################
diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng
index 993ac4a2e1821044914bc2b0b03feba01d8d924d..ad648de1c610e3d7b9d4434198acc06657066511 100644
--- a/interface/web/admin/lib/lang/ar_server_config.lng
+++ b/interface/web/admin/lib/lang/ar_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng
index 7160a1fc273d59a85878fcd86df4ebd83f5623f7..b2b655eca261cc858460dcde83a188dcc4d2d085 100644
--- a/interface/web/admin/lib/lang/bg_server_config.lng
+++ b/interface/web/admin/lib/lang/bg_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng
index f04377c232bb67cf4ede585248f52d2041ef64ef..a598861731fa59ec4962ad2463909bbf591827d8 100644
--- a/interface/web/admin/lib/lang/br_server_config.lng
+++ b/interface/web/admin/lib/lang/br_server_config.lng
@@ -321,3 +321,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng
index 797b5cb78fbbfb98c4d8e8041645e4af5c102144..e4e663e01adf3d8a8d80890e085ca0c84f84fae9 100644
--- a/interface/web/admin/lib/lang/ca_server_config.lng
+++ b/interface/web/admin/lib/lang/ca_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng
index cde526689949624aa505f359fe68e7addeb304ff..76a37e86f07b4ad4b150f914f19b1dfd63ffd089 100644
--- a/interface/web/admin/lib/lang/cz_server_config.lng
+++ b/interface/web/admin/lib/lang/cz_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng
index 7bfb3cb72e4d3e4c0a21e6f5f90da1b8db37a036..bc6225745f19093041b5c68fe62435ac0e45ac9e 100644
--- a/interface/web/admin/lib/lang/de_server_config.lng
+++ b/interface/web/admin/lib/lang/de_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng
index 4798ae18b9a63ba7bb5ee4e6b99bfe06046f6893..dda39b38a69bd8f6dc15310c4306b672fcd49f5b 100644
--- a/interface/web/admin/lib/lang/dk_server_config.lng
+++ b/interface/web/admin/lib/lang/dk_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng
index c5d3fd81f8d5c91fa2ba1ba12d08fdb2203e418a..9dfadedc5d3a06d8d815337b0f83a188782132e2 100644
--- a/interface/web/admin/lib/lang/el_server_config.lng
+++ b/interface/web/admin/lib/lang/el_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng
index f66819353688bf9aec730ef73f8456c60f4f95a7..e609a339d5ee69808c478ee272999debf54a7482 100644
--- a/interface/web/admin/lib/lang/en_server_config.lng
+++ b/interface/web/admin/lib/lang/en_server_config.lng
@@ -326,3 +326,8 @@ $wb['rspamd_password_txt'] = 'Rspamd Password';
 $wb['vhost_proxy_protocol_enabled_txt'] = 'Enable PROXY Protocol';
 $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng
index 4be92cfd4d1343f281be24f2ef85e81c57aaac4a..7f3289a5837d2132bb14028a1c6b26d29e25613f 100644
--- a/interface/web/admin/lib/lang/es_server_config.lng
+++ b/interface/web/admin/lib/lang/es_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng
index 297ef1fd7c0e1adb78474f5c424b652b7576e416..7ab81469b78d3cc49bf699ffb9af4d5f25783294 100644
--- a/interface/web/admin/lib/lang/fi_server_config.lng
+++ b/interface/web/admin/lib/lang/fi_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng
index cfd22a69b79c0010428588eec9aaed80dd9b9d2c..0924bd4a4181df04e71c4b114e8551ad5cd7e987 100644
--- a/interface/web/admin/lib/lang/fr_server_config.lng
+++ b/interface/web/admin/lib/lang/fr_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng
index 811a90d9566c3865fc37241399f83801aed73bf9..97b74e15f95002ec7ce252e172133359ae1e24be 100644
--- a/interface/web/admin/lib/lang/hr_server_config.lng
+++ b/interface/web/admin/lib/lang/hr_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng
index 8b2fd1f0a1d47c6476805203282fbd13c20e3f54..22a0725992d1b73e5e03b858b8e563814af7c435 100644
--- a/interface/web/admin/lib/lang/hu_server_config.lng
+++ b/interface/web/admin/lib/lang/hu_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng
index 08ca6ea6a25a872114a2707c74c69564e54ced3d..48627dd61403f3bd4364deeb910c49a3510a8a5a 100644
--- a/interface/web/admin/lib/lang/id_server_config.lng
+++ b/interface/web/admin/lib/lang/id_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng
index 747cdbc2cf8c8f91c68099e160b7d0ef26265ef8..a2e824450b7873106a187a1e86126b1b216d7672 100644
--- a/interface/web/admin/lib/lang/it_server_config.lng
+++ b/interface/web/admin/lib/lang/it_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng
index b116973b4c1b068934f75a55880c26c6f411de71..135c7ef51e254a59b47ca3186d3e499296a481c6 100644
--- a/interface/web/admin/lib/lang/ja_server_config.lng
+++ b/interface/web/admin/lib/lang/ja_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng
index 74d860902c4f72748205882960f7e32422aa81a5..29bed0ec44c1d2e0829aae772d61ae0382991b82 100644
--- a/interface/web/admin/lib/lang/nl_server_config.lng
+++ b/interface/web/admin/lib/lang/nl_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng
index c45aa6d5f40c3b84f9af1740a9320fc4aaafeb50..524018773f2b42cd4980aabc99f897c0a4402dcd 100644
--- a/interface/web/admin/lib/lang/pl_server_config.lng
+++ b/interface/web/admin/lib/lang/pl_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng
index 16bcb95a291282e95f6c94c942d88ba03eb92717..bf3ae9f8c2cec64ab62e2254e331330b79f0d7d1 100644
--- a/interface/web/admin/lib/lang/pt_server_config.lng
+++ b/interface/web/admin/lib/lang/pt_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng
index f1d230f2634183061e6ced078df55c8f3678d843..5b5294dabab93ffdcd017eb86ed8c853a26b9ae9 100644
--- a/interface/web/admin/lib/lang/ro_server_config.lng
+++ b/interface/web/admin/lib/lang/ro_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng
index 5975503625e86a6d31774eaa9090e638d2c99922..6499caa292d1d53b437a0af6f320959711ed0735 100644
--- a/interface/web/admin/lib/lang/ru_server_config.lng
+++ b/interface/web/admin/lib/lang/ru_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng
index d7327ae46593a31a6c013de3fb0fd4a90e8d7bf7..cedb605b78935bf8cd37ce9e2187ce2b8254a7a7 100644
--- a/interface/web/admin/lib/lang/se_server_config.lng
+++ b/interface/web/admin/lib/lang/se_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng
index 9bc30e114b22d1aceb41cff0810ede0ec3cf3e3d..bacb2e02ad0ecc0a1ed6a650049bb996c8772b02 100644
--- a/interface/web/admin/lib/lang/sk_server_config.lng
+++ b/interface/web/admin/lib/lang/sk_server_config.lng
@@ -320,4 +320,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng
index c55b1ac60b7d1b1afbafe15cc13f7895f8667fdf..f92561872172b98ab0d8ba6e02c213e2bc3a3c98 100644
--- a/interface/web/admin/lib/lang/tr_server_config.lng
+++ b/interface/web/admin/lib/lang/tr_server_config.lng
@@ -314,4 +314,8 @@ $wb['vhost_proxy_protocol_http_port_txt'] = 'PROXY Protocol HTTP Port';
 $wb['vhost_proxy_protocol_https_port_txt'] = 'PROXY Protocol HTTPS Port';
 $wb['jailkit_chroot_authorized_keys_template_txt'] = 'Jailkit authorized_keys template';
 $wb['jailkit_chroot_authorized_keys_template_error_regex'] = 'Invalid jaikit chroot authorized_keys template file.';
-?>
+$wb['jailkit_hardlinks_txt'] = 'Hardlinks within Jailkit chroot';
+$wb['tooltip_jailkit_hardlinks_txt'] = 'Using hardlinks is insecure, but saves disk space.';
+$wb['jailkit_hardlinks_allow_txt'] = 'Allow hardlinks within the jail';
+$wb['jailkit_hardlinks_no_txt'] = 'No, remove hardlinked files';
+$wb['jailkit_hardlinks_yes_txt'] = 'Yes, use hardlinks if possible';
diff --git a/interface/web/admin/templates/server_config_jailkit_edit.htm b/interface/web/admin/templates/server_config_jailkit_edit.htm
index e7f481b0463d34c089f5e55b159c27dd8b170154..91b2e82e4be0930f09fc07ec79b9792a9adb4467 100644
--- a/interface/web/admin/templates/server_config_jailkit_edit.htm
+++ b/interface/web/admin/templates/server_config_jailkit_edit.htm
@@ -17,7 +17,12 @@
             <div class="form-group">
                 <label for="jailkit_chroot_authorized_keys_template" class="col-sm-3 control-label">{tmpl_var name='jailkit_chroot_authorized_keys_template_txt'}</label>
                 <div class="col-sm-9"><input type="text" name="jailkit_chroot_authorized_keys_template" id="jailkit_chroot_authorized_keys_template" value="{tmpl_var name='jailkit_chroot_authorized_keys_template'}" class="form-control" /></div></div>
-
+	<div class="form-group">
+		<label class="col-sm-3 control-label">{tmpl_var name='jailkit_hardlinks_txt'}</label>
+		<div class="col-sm-9"><select name="jailkit_hardlinks" id="jailkit_hardlinks" class="form-control">
+			<a href="#" data-toggle="tooltip" title="{tmpl_var name='tooltip_jailkit_hardlinks_txt'}">{tmpl_var name="jailkit_hardlinks"}</a>
+		</select></div>
+	</div>
 
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php
index 8ca9cae31d620bd22bf205d1c045d99a58647aea..2988e03219c57dcc0a62ac2e5ac6306c5d750a3e 100644
--- a/interface/web/sites/ajax_get_json.php
+++ b/interface/web/sites/ajax_get_json.php
@@ -92,6 +92,7 @@ if($type == 'getserverphp'){
 		$sql_where .= ")";
 	}
 
+	$php_records = array();
 	if($php_type == 'php-fpm' || ($php_type == 'hhvm' && $server_type == 'nginx')){
 		$php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ? AND active = 'y'".$sql_where, $server_id);
 	} elseif($php_type == 'fast-cgi'){
diff --git a/interface/web/sites/form/web_vhost_domain.tform.php b/interface/web/sites/form/web_vhost_domain.tform.php
index eecb634c989be6e610e56784a9cb0b1afa4b7178..f5bca55eea9d615d53a80215e713e3db0f483002 100644
--- a/interface/web/sites/form/web_vhost_domain.tform.php
+++ b/interface/web/sites/form/web_vhost_domain.tform.php
@@ -1041,7 +1041,37 @@ if($_SESSION["s"]["user"]["typ"] == 'admin'
 				'value' => '',
 				'width' => '4',
 				'maxlength' => '4'
-			)
+			),
+			'jailkit_chroot_app_sections' => array(
+				'datatype' => 'TEXT',
+				'formtype' => 'TEXT',
+				'default' => '',
+				'validators' => array(  0 => array ('type' => 'REGEX',
+								'regex' => '/^[a-zA-Z0-9\-\_\ ]*$/',
+								'errmsg'=> 'jailkit_chroot_app_sections_error_regex'),
+				),
+				'value' => '',
+				'width' => '40',
+				'maxlength' => '1000'
+			),
+			'jailkit_chroot_app_programs' => array(
+				'datatype' => 'TEXT',
+				'formtype' => 'TEXT',
+				'default' => '',
+				'validators' => array(  0 => array('type' => 'REGEX',
+								'regex' => '/^[a-zA-Z0-9\.\-\_\/\ ]*$/',
+								'errmsg'=> 'jailkit_chroot_app_programs_error_regex'),
+				),
+				'value' => '',
+				'width' => '40',
+				'maxlength' => '1000'
+			),
+			'delete_unused_jailkit' => array (
+				'datatype' => 'VARCHAR',
+				'formtype' => 'CHECKBOX',
+				'default' => 'n',
+				'value' => array(0 => 'n', 1 => 'y')
+			),
 			//#################################
 			// END Datatable fields
 			//#################################
diff --git a/interface/web/sites/lib/lang/ar_web_vhost_domain.lng b/interface/web/sites/lib/lang/ar_web_vhost_domain.lng
index 668d176ea930fbd61de168a8a4e89d2cf8eb2018..2fd132c9e7118a74731724e963563d8d219acdb4 100644
--- a/interface/web/sites/lib/lang/ar_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/ar_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/bg_web_vhost_domain.lng b/interface/web/sites/lib/lang/bg_web_vhost_domain.lng
index dc20c33926234b700c88f5bdc6c98c02d22efe18..573fe63a4529667376f484744a2ed3241fc3cbd4 100644
--- a/interface/web/sites/lib/lang/bg_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/bg_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/br_web_vhost_domain.lng b/interface/web/sites/lib/lang/br_web_vhost_domain.lng
index 1a70b24b5cde9f7844b4e57d3bb857f93ecf9e0f..835ceeae4d88799b62bd87aea523725941fefe40 100644
--- a/interface/web/sites/lib/lang/br_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/br_web_vhost_domain.lng
@@ -191,4 +191,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Seções de aplicações em chroot no jailkit';
+$wb['jailkit_chroot_app_programs_txt'] = 'Aplicações em chroot no jailkit';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Seções de aplicações no jailkit está em branco.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Aplicações no jailkit está em branco.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'As seções de aplicações no jaikit são inválidas.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'As aplicações em chroot no jailkit são inválidas.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/ca_web_vhost_domain.lng b/interface/web/sites/lib/lang/ca_web_vhost_domain.lng
index bd72fe6f5e1a32432046bbf256e78d1e9a32326e..65c21fd2dd8a6bad2917279f6cafac916df6dbd0 100644
--- a/interface/web/sites/lib/lang/ca_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/ca_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/cz_web_vhost_domain.lng b/interface/web/sites/lib/lang/cz_web_vhost_domain.lng
index bf31bc5e26b011645dc4af8998e40328d3af4ccf..5d3caf5c90aa0ff66ddc2b694044eef5618c537d 100644
--- a/interface/web/sites/lib/lang/cz_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/cz_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sekce';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrootované aplikace';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/de_web_vhost_domain.lng b/interface/web/sites/lib/lang/de_web_vhost_domain.lng
index c2488bd80f16b167a1e672897cb553e5fd3abbb2..3b13009ab7d015f8ecce7372c67aa5514fb2e52f 100644
--- a/interface/web/sites/lib/lang/de_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/de_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit Chroot Anwendungsbereiche';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit Chrooted Anwendungen';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit Chroot Anwendungsbereiche ist leer.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit Chrooted Anwendungen ist leer.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/dk_web_vhost_domain.lng b/interface/web/sites/lib/lang/dk_web_vhost_domain.lng
index bd72fe6f5e1a32432046bbf256e78d1e9a32326e..7721691a6061ea37f3fbe324c65480097cfb0a58 100644
--- a/interface/web/sites/lib/lang/dk_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/dk_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sektioner';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applikationer';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sektioner er tomme.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applikationer er tomme.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Ugyldigt jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Ugyldigt jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/el_web_vhost_domain.lng b/interface/web/sites/lib/lang/el_web_vhost_domain.lng
index e421b21ba4ee97a1b722e952b6fe9c4714c6eacf..8628dff8419e1478262db9ab9e5539fac84cac3a 100644
--- a/interface/web/sites/lib/lang/el_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/el_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/en_web_vhost_domain.lng b/interface/web/sites/lib/lang/en_web_vhost_domain.lng
index c20c3f2c98a4247037fce4918c372b534cac3a2c..f633076dbb66382b830be0aefddddb5bb869cb9e 100644
--- a/interface/web/sites/lib/lang/en_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/en_web_vhost_domain.lng
@@ -191,4 +191,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb["jailkit_chroot_app_sections_txt"] = 'Jailkit chroot app sections';
+$wb["jailkit_chroot_app_programs_txt"] = 'Jailkit chrooted applications';
+$wb["jailkit_chroot_app_sections_error_empty"] = 'Jailkit chroot app sections is empty.';
+$wb["jailkit_chroot_app_programs_error_empty"] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/es_web_vhost_domain.lng b/interface/web/sites/lib/lang/es_web_vhost_domain.lng
index b344f6cc30751d32f87819e9d56685222ee9d997..e9d49604f2839b520a643a290eb3c12dd78f5cbe 100644
--- a/interface/web/sites/lib/lang/es_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/es_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Las aplicaciones chrooted por Jailkit están vacías.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Las aplicaciones de programas chroot de Jailkit son inválidas.';
+$wb['jailkit_chroot_app_programs_txt'] = 'Aplicaciones chrooted por Jailkit';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'La sección de aplicaciones chroot de Jailkit está vacía.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Las secciones chroot de Jailkit son inválidas.';
+$wb['jailkit_chroot_app_sections_txt'] = 'Sección de aplicaciones chroot de Jailkit';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/fi_web_vhost_domain.lng b/interface/web/sites/lib/lang/fi_web_vhost_domain.lng
index 79397d009da08f4bc2b3c0ffa0c3581da537fc4e..b0ede66c4d83ccad3b376795c98ccf9090bdd1b7 100644
--- a/interface/web/sites/lib/lang/fi_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/fi_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot-ohjelmaosiot';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted-ohjelmat';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/fr_web_vhost_domain.lng b/interface/web/sites/lib/lang/fr_web_vhost_domain.lng
index d639c25a561bc6f08d01319cf4c2ce7a365a1efb..c43f5c97d5aaded0895d0c47f5f3c51c5d1401d8 100644
--- a/interface/web/sites/lib/lang/fr_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/fr_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Sections des applications chrootées Jailkit';
+$wb['jailkit_chroot_app_programs_txt'] = 'Applications chrootées Jailkit';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/hr_web_vhost_domain.lng b/interface/web/sites/lib/lang/hr_web_vhost_domain.lng
index 7688c4f88b7b852f89741fe503bdd20ad663cf98..1645ef8eb584e6a3c9f477831571b50fdd5d9bf4 100644
--- a/interface/web/sites/lib/lang/hr_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/hr_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sekcije';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrootane aplikacije';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot aplikacijska sekcija nije upisana.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted aplikacije nisu upisane.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Neispravan jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Neispravan jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/hu_web_vhost_domain.lng b/interface/web/sites/lib/lang/hu_web_vhost_domain.lng
index 351447ad324d40774fb26ed69cb900b17e3aa56b..32a65e6502e611aaceac112efaa25338259495ba 100644
--- a/interface/web/sites/lib/lang/hu_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/hu_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/id_web_vhost_domain.lng b/interface/web/sites/lib/lang/id_web_vhost_domain.lng
index a2b5249c991367f97eca512f2bfad240a4f6cf61..4bc0395328ed15bb6b5a5231ae664a496f9d5880 100644
--- a/interface/web/sites/lib/lang/id_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/id_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Bagian app chroot';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit aplikasi yang ter-chroot';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/it_web_vhost_domain.lng b/interface/web/sites/lib/lang/it_web_vhost_domain.lng
index 29e0be2310ea9acf84e0338fa875710067b00fde..3d1e16fe2ea43e59ff78b495c4b3dd07038fa1dd 100644
--- a/interface/web/sites/lib/lang/it_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/it_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections  vuoto.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications  vuoto.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/ja_web_vhost_domain.lng b/interface/web/sites/lib/lang/ja_web_vhost_domain.lng
index 20bd73f13d373ede03f78c1c99e7b410408fcba2..3ca7f658f58e796198a41056f9415e517dd2f2a7 100644
--- a/interface/web/sites/lib/lang/ja_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/ja_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = '利用可能アプリケーションセクション';
+$wb['jailkit_chroot_app_programs_txt'] = '利用可能アプリケーション';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/nl_web_vhost_domain.lng b/interface/web/sites/lib/lang/nl_web_vhost_domain.lng
index 054aeab43b4883d1022ad400c51c74257865ae8a..afe2da94b8b8d94d6a23ed16347b8c2f8eaf7683 100644
--- a/interface/web/sites/lib/lang/nl_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/nl_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'Het IP adres kan niet worden aangepast. Ne
 $wb['error_ipv6_change_forbidden'] = 'Het IP adres kan niet worden aangepast. Neem contact op met de administrator indien je het IPv6 adres wilt wijzigen.';
 $wb['error_domain_change_forbidden'] = 'De domeinnaam kan niet worden aangepast. Neem contact op met de administrator indien je het domein wilt wijzigen.';
 $wb['error_server_change_not_possible'] = 'De server kan niet worden aangepast.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app secties';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applicaties';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/pl_web_vhost_domain.lng b/interface/web/sites/lib/lang/pl_web_vhost_domain.lng
index 958e6c0f7bb4a7ebde354d2d3dfeb54350c5b7e9..e0b6a596e593c56913c47db421e21b56bca3e789 100644
--- a/interface/web/sites/lib/lang/pl_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/pl_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Sekcje aplikacji roota Jailkit';
+$wb['jailkit_chroot_app_programs_txt'] = 'Ścieżki aplikacji roota Jailkit';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/pt_web_vhost_domain.lng b/interface/web/sites/lib/lang/pt_web_vhost_domain.lng
index 9420ee899b5118b705eb9c2b95db7f0c4fbda5cf..58a256f652682c8a4780418a0607ab1c2d995ca8 100644
--- a/interface/web/sites/lib/lang/pt_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/pt_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Aplicações Jailkit chroot (Sessões)';
+$wb['jailkit_chroot_app_programs_txt'] = 'Aplicações Jailkit em ambiente chroot';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/ro_web_vhost_domain.lng b/interface/web/sites/lib/lang/ro_web_vhost_domain.lng
index fc0fb571cab855347850af4aa725c64cb750f1ee..9554f4643fd9ae6c5d5b961c778cac085fff0622 100644
--- a/interface/web/sites/lib/lang/ro_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/ro_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/ru_web_vhost_domain.lng b/interface/web/sites/lib/lang/ru_web_vhost_domain.lng
index be4bd0e90cf75c9366f702533e0d9e7290913632..538b329fb4d47129ab7852a6a9223e1d2f426916 100644
--- a/interface/web/sites/lib/lang/ru_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/ru_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Пакеты программ Jailkit chroot';
+$wb['jailkit_chroot_app_programs_txt'] = 'Программы Jailkit chrooted';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Пакеты программ Jailkit chroot отсутствуют.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Некорректные пакеты программ Jailkit chroot.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/se_web_vhost_domain.lng b/interface/web/sites/lib/lang/se_web_vhost_domain.lng
index 28b2779d8791d9830cb1fd5518d3a8f947dbd283..af1a6f1b9e7412f171320319fc026ebff2ff31fa 100644
--- a/interface/web/sites/lib/lang/se_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/se_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sections';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted applications';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/sk_web_vhost_domain.lng b/interface/web/sites/lib/lang/sk_web_vhost_domain.lng
index 2cff2260e38eab15c0079a755e317720bd5b2cbf..e2cfa27c0f786e7cfdc8711fca39fa5306d4f88b 100644
--- a/interface/web/sites/lib/lang/sk_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/sk_web_vhost_domain.lng
@@ -186,4 +186,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot app sekcia';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chrooted aplikácia';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot app sections is empty.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chrooted applications is empty.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Invalid jaikit chroot sections.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Invalid jaikit chroot app programs.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/lib/lang/tr_web_vhost_domain.lng b/interface/web/sites/lib/lang/tr_web_vhost_domain.lng
index 6105e15b6914796001035acde09c84f074aa9586..6b7fe3793edbe1d50d26b17ad8e9517c473a2f0b 100644
--- a/interface/web/sites/lib/lang/tr_web_vhost_domain.lng
+++ b/interface/web/sites/lib/lang/tr_web_vhost_domain.lng
@@ -188,4 +188,13 @@ $wb['error_ipv4_change_forbidden'] = 'The IP cannot be changed. Please contact y
 $wb['error_ipv6_change_forbidden'] = 'The IP cannot be changed. Please contact your administrator if you want to change the IPv6 address.';
 $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Please contact your administrator if you want to change the domain name.';
 $wb['error_server_change_not_possible'] = 'The server cannot be changed.';
-?>
+$wb['jailkit_chroot_app_sections_txt'] = 'Jailkit chroot Uygulama Bölümleri';
+$wb['jailkit_chroot_app_programs_txt'] = 'Jailkit chroot Uygulamaları';
+$wb['jailkit_chroot_app_sections_error_empty'] = 'Jailkit chroot uygulama bölümleri boş olamaz.';
+$wb['jailkit_chroot_app_programs_error_empty'] = 'Jailkit chroot uygulamaları boş olamaz.';
+$wb['jailkit_chroot_app_sections_error_regex'] = 'Jailkit chroot bölümleri geçersiz.';
+$wb['jailkit_chroot_app_programs_error_regex'] = 'Jailkit chroot app uygulama yazılımları geçersiz.';
+$wb['tooltip_jailkit_chroot_app_sections_txt'] = 'When empty, uses Jailkit chroot app sections from Server Config';
+$wb['tooltip_jailkit_chroot_app_programs_txt'] = 'When empty, uses Jailkit chroot applications from Server Config';
+$wb['delete_unused_jailkit_txt'] = 'Delete unused jailkit chroot';
+$wb['tooltip_delete_unused_jailkit_txt'] = 'Delete the jailkit chroot environment when there are no shell users or cron jobs which require it.';
diff --git a/interface/web/sites/templates/web_vhost_domain_advanced.htm b/interface/web/sites/templates/web_vhost_domain_advanced.htm
index e878a06fbbc6477d818f70c348188fdd7af5c96d..12b01c21b8aad9df8a03e248eab054d3824bda95 100644
--- a/interface/web/sites/templates/web_vhost_domain_advanced.htm
+++ b/interface/web/sites/templates/web_vhost_domain_advanced.htm
@@ -130,6 +130,26 @@
     <b>{tmpl_var name="available_proxy_directive_snippets_txt"}</b><br><br>&nbsp;{tmpl_var name="proxy_directive_snippets_txt"}
   </div>
 </div>
+<div class="jailkit">
+  <div class="form-group">
+    <label class="col-sm-3 control-label">{tmpl_var name='jailkit_chroot_app_sections_txt'}</label>
+    <div class="col-sm-9">
+      <input name="jailkit_chroot_app_sections" id="jailkit_chroot_app_sections" value="{tmpl_var name='jailkit_chroot_app_sections'}" data-toggle="tooltip" title="{tmpl_var name='tooltip_jailkit_chroot_app_sections_txt'}" type="text" class="form-control" />
+    </div>
+  </div>
+  <div class="form-group">
+    <label class="col-sm-3 control-label">{tmpl_var name='jailkit_chroot_app_programs_txt'}</label>
+    <div class="col-sm-9">
+      <input name="jailkit_chroot_app_programs" id="jailkit_chroot_app_programs" value="{tmpl_var name='jailkit_chroot_app_programs'}" data-toggle="tooltip" title="{tmpl_var name='tooltip_jailkit_chroot_app_programs_txt'}" type="text" class="form-control" />
+    </div>
+  </div>
+  <div class="form-group">
+    <label class="col-sm-3 control-label">{tmpl_var name='delete_unused_jailkit_txt'}</label>
+    <div class="col-sm-9">
+      <a href="#" data-toggle="tooltip" title="{tmpl_var name='tooltip_delete_unused_jailkit_txt'}">{tmpl_var name='delete_unused_jailkit'}</a>
+    </div>
+  </div>
+</div>
 <input type="hidden" name="id" value="{tmpl_var name='id'}">
 <div class="clear">
   <div class="right">
@@ -137,6 +157,7 @@
     <button class="btn btn-default formbutton-default" type="button" value="{tmpl_var name='btn_cancel_txt'}" data-load-content="sites/web_vhost_domain_list.php">{tmpl_var name='btn_cancel_txt'}</button>
   </div>
 </div>
+
 <script language="JavaScript" type="text/javascript">
   var webId = jQuery('input[name="id"]').val();
   var serverId;
diff --git a/server/lib/classes/cron.d/600-jailkit_maintenance.inc.php b/server/lib/classes/cron.d/600-jailkit_maintenance.inc.php
new file mode 100644
index 0000000000000000000000000000000000000000..d04fd87cf69dd1c2b1f3a0fa860429f464a2120e
--- /dev/null
+++ b/server/lib/classes/cron.d/600-jailkit_maintenance.inc.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+Copyright (c) 2020, Jesse Norell <jesse@kci.net>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of ISPConfig nor the names of its contributors
+      may be used to endorse or promote products derived from this software without
+      specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+class cronjob_jailkit_maintenance extends cronjob {
+
+	// job schedule
+	protected $_schedule = '*/5 * * * *';
+	protected $_run_at_new = true;
+
+	//private $_tools = null;
+
+	/* this function is optional if it contains no custom code */
+	public function onPrepare() {
+		global $app;
+
+		parent::onPrepare();
+	}
+
+	/* this function is optional if it contains no custom code */
+	public function onBeforeRun() {
+		global $app;
+
+		return parent::onBeforeRun();
+	}
+
+	public function onRunJob() {
+		global $app, $conf;
+
+		$app->uses('system,getconf');
+
+		$server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
+		if(isset($server_config['migration_mode']) && $server_config['migration_mode'] == 'y') {
+			//$app->log('Migration mode active, not running Jailkit updates.', LOGLEVEL_DEBUG);
+			print "Migration mode active, not running Jailkit updates.\n";
+
+			return;
+		}
+
+		$jailkit_config = $app->getconf->get_server_config($conf['server_id'], 'jailkit');
+		if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
+			if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
+				$update_options = array('hardlink');
+			} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
+				$update_options = array();
+			}
+		} else {
+			$update_options = array('allow_hardlink');
+		}
+
+		// limit the number of jails we update at one time according to time of day
+		$num_jails_to_update = (date('H') < 6) ? 25 : 3;
+
+		$sql = "SELECT domain_id, domain, document_root, php_fpm_chroot, jailkit_chroot_app_sections, jailkit_chroot_app_programs, delete_unused_jailkit, last_jailkit_hash FROM web_domain WHERE type = 'vhost' AND last_jailkit_update < (NOW() - INTERVAL 24 HOUR) AND server_id = ? ORDER by last_jailkit_update LIMIT ?";
+		$records = $app->db->queryAllRecords($sql, $conf['server_id'], $num_jails_to_update);
+
+		foreach($records as $rec) {
+			if (!is_dir($rec['document_root']) || !is_dir($rec['document_root'].'/etc/jailkit')) {
+				continue;
+			}
+
+			//$app->log('Beginning jailkit maintenance for domain '.$rec['domain'].' at '.$rec['document_root'], LOGLEVEL_DEBUG);
+			print 'Beginning jailkit maintenance for domain '.$rec['domain'].' at '.$rec['document_root']."\n";
+
+			// check for any shell_user using this jail
+			$shell_user_inuse = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `parent_domain_id` = ? AND `chroot` = ? AND `server_id` = ?', $rec['domain_id'], 'jailkit', $conf['server_id']);
+
+			// check for any cron job using this jail
+			$cron_inuse = $app->db->queryOneRecord('SELECT id FROM `cron` WHERE `parent_domain_id` = ? AND `type` = ? AND `server_id` = ?', $rec['domain_id'], 'chrooted', $conf['server_id']);
+
+			if ($shell_user_inuse || $cron_inuse || $rec['php_fpm_chroot'] == 'y' || $rec['delete_unused_jailkit'] != 'y') {
+				$sections = $jailkit_config['jailkit_chroot_app_sections'];
+				if (isset($rec['jailkit_chroot_app_sections']) && $rec['jailkit_chroot_app_sections'] != '') {
+					$sections = $rec['jailkit_chroot_app_sections'];
+				}
+				$programs = $jailkit_config['jailkit_chroot_app_programs'];
+				if (isset($rec['jailkit_chroot_app_programs']) && $rec['jailkit_chroot_app_programs'] != '') {
+					$programs = $rec['jailkit_chroot_app_programs'];
+				}
+				$programs .= ' '.$jailkit_config['jailkit_chroot_cron_programs'];
+
+				$last_updated = preg_split('/[\s,]+/', $sections.' '.$programs);
+				$last_updated = array_unique($last_updated, SORT_REGULAR);
+				sort($last_updated, SORT_STRING);
+				$update_hash = hash('md5', implode(' ', $last_updated));
+
+				if ($update_hash != $rec['last_jailkit_hash']) {
+					$app->system->web_folder_protection($rec['document_root'], false);
+					$app->system->update_jailkit_chroot($rec['document_root'], $sections, $programs, $update_options);
+					$app->system->web_folder_protection($rec['document_root'], true);
+					$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $update_hash, $rec['document_root']);
+				} else {
+					$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW() WHERE `document_root` = ?", $rec['document_root']);
+				}
+			} elseif ($rec['delete_unused_jailkit'] == 'y') {
+				//$app->log('Removing unused jail: '.$rec['document_root'], LOGLEVEL_DEBUG);
+				print 'Removing unused jail: '.$rec['document_root']."\n";
+				$app->system->web_folder_protection($rec['document_root'], false);
+				$app->system->delete_jailkit_chroot($rec['document_root']);
+				$app->system->web_folder_protection($rec['document_root'], true);
+
+				$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = NULL WHERE `document_root` = ?", $rec['document_root']);
+			} else {
+				$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW() WHERE `document_root` = ?", $rec['document_root']);
+			}
+		}
+
+		parent::onRunJob();
+	}
+
+	/* this function is optional if it contains no custom code */
+	public function onAfterRun() {
+		parent::onAfterRun();
+	}
+
+}
+
diff --git a/server/lib/classes/functions.inc.php b/server/lib/classes/functions.inc.php
index 1d9dd67569448a2cee200ec71281685fd568517a..5da1f3d713029b069b3a89c954dc001a541e1271 100644
--- a/server/lib/classes/functions.inc.php
+++ b/server/lib/classes/functions.inc.php
@@ -118,6 +118,26 @@ class functions {
 		return $out;
 	}
 
+	public function array_unset_by_value($array, $value) {
+		if (!is_array($array)) {
+			return $array;
+		}
+		if (is_array($value)) {
+			foreach ($array as $key => $val){
+				if (in_array($val, $value)) {
+					unset($array[$key]);
+				}
+			}
+		} else {
+			foreach ($array as $key => $val){
+				if ($val == $value) {
+					unset($array[$key]);
+				}
+			}
+		}
+		return $array;
+	}
+
 	public function currency_format($number, $view = '') {
 		global $app;
 		if($view != '') $number_format_decimals = (int)$app->lng('number_format_decimals_'.$view);
diff --git a/server/lib/classes/ini_parser.inc.php b/server/lib/classes/ini_parser.inc.php
index d4c94543c6acaf75f5c24ffe1e6a0c0c58bda20d..f75f4b4cb756ae4d07b2eb732e340122c09b8dab 100644
--- a/server/lib/classes/ini_parser.inc.php
+++ b/server/lib/classes/ini_parser.inc.php
@@ -52,6 +52,75 @@ class ini_parser{
 
 
 
+	function parse_ini_file($file) {
+		if(!is_file($file)) {
+			return false;
+		}
+		return $this->parse_ini_string(file_get_contents($file));
+	}
+
+
+
+	function array_to_ini($array,$out="") {
+		if(!is_array($array)) {
+			return $array;
+		}
+		$t="";
+		$q=false;
+		foreach($array as $c=>$d) {
+			if(is_array($d)) {
+				$t .= $this->array_to_ini($d,$c);
+			} else {
+				if($c===intval($c)) {
+					if(!empty($out)) {
+						$t.="\r\n".$out." = \"".$d."\"";
+						if($q!=2) {
+							$q=true;
+						}
+					} else {
+						$t.="\r\n".$d;
+					}
+				} else {
+					$t.="\r\n".$c." = \"".$d."\"";
+					$q=2;
+				}
+			}
+		}
+		if($q!=true && !empty($out))
+			return "[".$out."]\r\n".$t;
+		if(!empty($out))
+			return  $t;
+		return trim($t);
+	}
+
+
+
+	function write_ini_file($array, $file) {
+		$ret = false;
+		$ini = $this->array_to_ini($array);
+
+		if ($fp = fopen($file, 'w')) {
+			$startTime = microtime();
+			do
+			{
+				$canWrite = flock($fp, LOCK_EX);
+				// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
+				if(!$canWrite) usleep(round(rand(0, 100)*1000));
+			} while ((!$canWrite) and ((microtime()-$startTime) < 1000));
+
+			// file was locked so now we can store information
+			if ($canWrite) {
+				$ret = fwrite($fp, $ini);
+				flock($fp, LOCK_UN);
+			}
+			fclose($fp);
+		}
+		return $ret;
+	}
+
+
+
+	// unused function, and misleading arg ($file is unused)
 	function get_ini_string($file) {
 		$content = '';
 		foreach($this->config as $section => $data) {
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 6974265c5ef67ccc4a253ac616d8cad3d6e61779..738c3acadd3f9079e21601488e89deafcb8a41c2 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -941,6 +941,32 @@ class system{
                 return $return_var == 0 ? true : false;
         }
 
+	function rmdir($path, $recursive=false) {
+		// Disallow operating on root directory
+		if(realpath($path) == '/') {
+			$app->log("rmdir: afraid I might delete root: $path", LOGLEVEL_WARN);
+			return false;
+		}
+
+		$path = rtrim($path, '/');
+		if (is_dir($path) && !is_link($path)) {
+			$objects = array_diff(scandir($path), array('.', '..'));
+			foreach ($objects as $object) {
+				if ($recursive) {
+					if (is_dir("$path/$object") && !is_link("$path/$object")) {
+						$this->rmdir("$path/$object", $recursive);
+					} else {
+						unlink ("$path/$object");
+					}
+				} else {
+					$app->log("rmdir: invoked non-recursive, not removing $path (expect rmdir failure)", LOGLEVEL_DEBUG);
+				}
+			}
+			return rmdir($path);
+		}
+		return false;
+	}
+
 	function touch($file, $allow_symlink = false){
 		global $app;
 		if($allow_symlink == false && @file_exists($file) && $this->checkpath($file) == false) {
@@ -983,6 +1009,28 @@ class system{
 		return symlink($cfrom, $to);
 	}
 
+	function remove_broken_symlinks($path, $recursive=false) {
+		global $app;
+
+		if ($path != '/') {
+			$path = rtrim($path, '/');
+		}
+		if (is_dir($path)) {
+			$objects = array_diff(scandir($path), array('.', '..'));
+			foreach ($objects as $object) {
+				if (is_dir("$path/$object") && $recursive) {
+					$this->remove_broken_symlinks("$path/$object", $recursive);
+				} elseif (is_link("$path/$object") && !file_exists("$path/$object")) {
+					$app->log("removing broken symlink $path/$object", LOGLEVEL_DEBUG);
+					unlink ("$path/$object");
+				}
+			}
+		} elseif (is_link("$path") && !file_exists("$path")) {
+			$app->log("removing broken symlink $path", LOGLEVEL_DEBUG);
+			unlink ("$path");
+		}
+	}
+
 	function checkpath($path) {
 		$path = trim($path);
 		//* We allow only absolute paths
@@ -2201,6 +2249,12 @@ class system{
 	}
 
 	public function create_jailkit_user($username, $home_dir, $user_home_dir, $shell = '/bin/bash', $p_user = null, $p_user_home_dir = null) {
+		// Disallow operating on root directory
+		if(realpath($home_dir) == '/') {
+			$app->log("create_jailkit_user: invalid home_dir: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
 		// Check if USERHOMEDIR already exists
 		if(!is_dir($home_dir . '/.' . $user_home_dir)) {
 			$this->mkdirpath($home_dir . '/.' . $user_home_dir, 0755, $username);
@@ -2223,59 +2277,416 @@ class system{
 		return true;
 	}
 
-	public function create_jailkit_programs($home_dir, $programs = array()) {
+	public function create_jailkit_chroot($home_dir, $app_sections = array(), $options = array()) {
+		// Disallow operating on root directory
+		if(realpath($home_dir) == '/') {
+			$app->log("create_jailkit_chroot: invalid home_dir: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
+		if(!is_dir($home_dir)) {
+			$app->log("create_jailkit_chroot: jail directory does not exist: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+		if(empty($app_sections)) {
+			return true;
+		} elseif(is_string($app_sections)) {
+			$app_sections = preg_split('/[\s,]+/', $app_sections);
+		}
+
+		// Change ownership of the chroot directory to root
+		$this->chown($home_dir, 'root');
+		$this->chgrp($home_dir, 'root');
+
+		$program_args = '';
+		foreach ($options as $opt) {
+			switch ($opt) {
+			case '-k':
+			case 'hardlink':
+				$program_args .= ' -k';
+				break;
+			case '-f':
+			case 'force':
+				$program_args .= ' -f';
+				break;
+			}
+		}
+		# /etc/jailkit/jk_init.ini is the default path, probably not needed?
+		$program_args .= ' -c /etc/jailkit/jk_init.ini -j ?';
+		foreach($app_sections as $app_section) {
+			# should check that section exists with jk_init --list ?
+			$program_args .= ' ' . escapeshellarg($app_section);
+		}
+
+		// Initialize the chroot into the specified directory with the specified applications
+		$cmd = 'jk_init' . $program_args;
+		$this->exec_safe($cmd, $home_dir);
+
+		// Create the tmp and /var/run directories
+		if(!is_dir($home_dir . '/tmp')) {
+			$this->mkdirpath($home_dir . '/tmp', 0770);
+		} else {
+			$this->chmod($home_dir . '/tmp', 0770, true);
+		}
+		if(!is_dir($home_dir . '/var/run')) {
+			$this->mkdirpath($home_dir . '/var/run', 0755);
+		} else {
+			$this->chmod($home_dir . '/var/run', 0755, true);
+		}
+		if(!is_dir($home_dir . '/var/tmp')) {
+			$this->mkdirpath($home_dir . '/var/tmp', 0770);
+		} else {
+			$this->chmod($home_dir . '/var/tmp', 0770, true);
+		}
+
+		// Fix permissions of the root directory
+		$this->chmod($home_dir . '/bin', 0755, true);  // was chmod g-w $CHROOT_HOMEDIR/bin
+
+		return true;
+	}
+
+	public function create_jailkit_programs($home_dir, $programs = array(), $options = array()) {
+		// Disallow operating on root directory
+		if(realpath($home_dir) == '/') {
+			$app->log("create_jailkit_programs: invalid home_dir: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
+		if(!is_dir($home_dir)) {
+			$app->log("create_jailkit_programs: jail directory does not exist: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
 		if(empty($programs)) {
 			return true;
 		} elseif(is_string($programs)) {
 			$programs = preg_split('/[\s,]+/', $programs);
 		}
+
+		# prohibit ill-advised copying paths known to be sensitive/problematic
+		# (easy to bypass if needed, eg. use /./etc)
+		$blacklisted_paths_regex = array(
+			'@^/$@',
+			'@^/proc(/.*)?$@',
+			'@^/sys(/.*)?$@',
+			'@^/etc/?$@',
+			'@^/dev/?$@',
+			'@^/tmp/?$@',
+			'@^/run/?$@',
+			'@^/boot/?$@',
+			'@^/var(/?|/backups?/?)?$@',
+		);
+
 		$program_args = '';
+		foreach ($options as $opt) {
+			switch ($opt) {
+			case '-k':
+			case 'hardlink':
+				$program_args .= ' -k';
+				break;
+			case '-f':
+			case 'force':
+				$program_args .= ' -f';
+				break;
+			}
+		}
+		$program_args .= ' -j ?';
+
+		$bad_paths = array();
 		foreach($programs as $prog) {
-			$program_args .= ' ' . escapeshellarg($prog);
+			foreach ($blacklisted_paths_regex as $re) {
+				if (preg_match($re, $prog, $matches)) {
+					$bad_paths[] = $matches[0];
+				}
+			}
+			if (count($bad_paths) > 0) {
+				$app->log("Prohibited path not added to jail $home_dir: " . implode(", ", $bad_paths), LOGLEVEL_WARN);
+			} else {
+				$program_args .= ' ' . escapeshellarg($prog);
+			}
 		}
 
-		$cmd = 'jk_cp -j ?' . $program_args;
-		$this->exec_safe($cmd, $home_dir);
+		if (count($programs) > count($bad_paths)) {
+			$cmd = 'jk_cp' . $program_args;
+			$this->exec_safe($cmd, $home_dir);
+		}
 
 		return true;
 	}
 
-	public function create_jailkit_chroot($home_dir, $app_sections = array()) {
-		if(empty($app_sections)) {
-			return true;
-		} elseif(is_string($app_sections)) {
-			$app_sections = preg_split('/[\s,]+/', $app_sections);
+	public function update_jailkit_chroot($home_dir, $sections = array(), $programs = array(), $options = array()) {
+		global $app;
+
+$app->log("update_jailkit_chroot called for $home_dir with options ".print_r($options, true), LOGLEVEL_DEBUG);
+		$app->uses('ini_parser');
+
+		// Disallow operating on root directory
+		if(realpath($home_dir) == '/') {
+			$app->log("update_jailkit_chroot: invalid home_dir: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
+		if(!is_dir($home_dir)) {
+			$app->log("update_jailkit_chroot: jail directory does not exist: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
+		$opts = array();
+		$jk_update_args = '';
+		$jk_cp_args = '';
+		foreach ($options as $opt) {
+			switch ($opt) {
+			case '-k':
+			case 'hardlink':
+				$opts[] = 'hardlink';
+				$jk_update_args .= ' -k';
+				$jk_cp_args .= ' -k';
+				break;
+			case '-f':
+			case 'force':
+				$opts[] = 'force';
+				$jk_cp_args .= ' -f';
+				break;
+			}
 		}
 
 		// Change ownership of the chroot directory to root
 		$this->chown($home_dir, 'root');
 		$this->chgrp($home_dir, 'root');
 
-		$app_args = '';
-		foreach($app_sections as $app_section) {
-			$app_args .= ' ' . escapeshellarg($app_section);
+		$jailkit_directories = array(
+			'bin',
+			'dev',
+			'etc',
+			'lib',
+			'lib32',
+			'lib64',
+			'opt',
+			'sys',
+			'usr',
+			'var',
+		);
+
+		$skips = '';
+		$multiple_links = array();
+		foreach ($jailkit_directories as $dir) {
+			$root_dir = '/'.$dir;
+			$jail_dir = rtrim($home_dir, '/') . '/'.$dir;
+
+			if (!is_dir($jail_dir)) {
+				$skips .= " --skip=/$dir";
+				continue;
+			}
+
+			// if directory exists in jail but not in root, remove it
+			if (is_dir($jail_dir) && !is_dir($root_dir)) {
+				$this->rmdir($jail_dir, true);
+				$skips .= " --skip=/$dir";
+				continue;
+			}
+
+			$this->remove_broken_symlinks($jail_dir, true);
+
+			// save list of hardlinked files
+			if (!(in_array('hardlink', $opts) || in_array('allow_hardlink', $options))) {
+$app->log("update_jailkit_chroot: searching for hardlinks in $jail_dir", LOGLEVEL_DEBUG);
+                                $find_multiple_links = function ( $path ) use ( &$find_multiple_links ) {
+					$found = array();
+					if (is_dir($path) && !is_link($path)) {
+						$objects = array_diff(scandir($path), array('.', '..'));
+						foreach ($objects as $object) {
+							$ret = $find_multiple_links( "$path/$object" );
+							if (count($ret) > 0) {
+								$found = array_merge($found, $ret);
+							}
+						}
+					} elseif (is_file($path)) {
+						$stat = lstat($path);
+						if ($stat['nlink'] > 1) {
+							$found[$path] = $path;
+						}
+					}
+					return $found;
+				};
+
+				$ret = $find_multiple_links($jail_dir);
+				if (count($ret) > 0) {
+					$multiple_links = array_merge($multiple_links, $ret);
+				}
+
+				// remove broken symlinks a second time after hardlink cleanup
+				$this->remove_broken_symlinks($jail_dir, true);
+			}
+else { $app->log("update_jailkit_chroot: NOT searching for hardlinks in $jail_dir, options: ".print_r($options, true), LOGLEVEL_DEBUG); }
 		}
 
-		// Initialize the chroot into the specified directory with the specified applications
-		$cmd = 'jk_init -f -c /etc/jailkit/jk_init.ini -j ?' . $app_args;
+		foreach ($multiple_links as $file) {
+			$app->log("update_jailkit_chroot: removing hardlinked file: $file", LOGLEVEL_DEBUG);
+			unlink($file);
+		}
+
+		$cmd = 'jk_update --jail=?' . $jk_update_args . $skips;
 		$this->exec_safe($cmd, $home_dir);
+$app->log('jk_update returned: '.print_r($this->_last_exec_out, true), LOGLEVEL_DEBUG);
+		foreach ($this->_last_exec_out as $line) {
+			if (substr( $line, 0, 4 ) === "skip") {
+				continue;
+			}
+			if (preg_match('/^(WARNING|ERROR)/', $line, $matches)) {
+				$app->log("jk_update: $line", LOGLEVEL_DEBUG);
+			} elseif (preg_match('@^(?: [^ ]+){6}(.+)'.preg_quote($home_dir, '@').'$@', $line, $matches)) {
+				# remove deprecated files that jk_update failed to remove
+				if (is_file($matches[1])) {
+$app->log("update_jailkit_chroot: removing deprecated file which jk_update failed to remove:  ".$matches[1], LOGLEVEL_DEBUG);
+					unlink($matches[1]);
+				} elseif (is_dir($matches[1])) {
+$app->log("update_jailkit_chroot: removing deprecated directory which jk_update failed to remove:  ".$matches[1], LOGLEVEL_DEBUG);
+					$this->rmdir($matches[1], true);
+				}
+               			# unhandled error
+				//$app->log("jk_update error for jail $home_dir:  ".$matches[1], LOGLEVEL_DEBUG);
+				// at least for 3.2 beta, lets gather some of this info:
+				$app->log("jk_update error for jail $home_dir, feel free to pass to ispconfig developers:  ".print_r( $matches, true), LOGLEVEL_DEBUG);
+			}
+		}
+
+		// reinstall jailkit sections and programs
+		if(!(empty($sections) && empty($programs))) {
+			$this->create_jailkit_chroot($home_dir, $sections, $opts);
+			$this->create_jailkit_programs($home_dir, $programs, $opts);
+		}
 
-		// Create the temp directory
+		// Create the tmp and /var/run directories
 		if(!is_dir($home_dir . '/tmp')) {
-			$this->mkdirpath($home_dir . '/tmp', 0777);
+			$this->mkdirpath($home_dir . '/tmp', 0770);
+		} else {
+			$this->chmod($home_dir . '/tmp', 0770, true);
+		}
+		if(!is_dir($home_dir . '/var/run')) {
+			$this->mkdirpath($home_dir . '/var/run', 0755);
 		} else {
-			$this->chmod($home_dir . '/tmp', 0777, true);
+			$this->chmod($home_dir . '/var/run', 0755, true);
+		}
+		if(!is_dir($home_dir . '/var/tmp')) {
+			$this->mkdirpath($home_dir . '/var/tmp', 0770);
+		} else {
+			$this->chmod($home_dir . '/var/tmp', 0770, true);
+		}
+
+		// TODO: Set /usr/bin/php symlink to php version of the website.
+		//
+		// Currently server_php does not have a field for the cli path;
+		// we can guess/determing according to OS-specific conventions or add that field.
+		// Then symlink /usr/bin/php (or correct OS-specific path) to that location.
+
+		// search for any hardlinked files which are now missing
+		if (!(in_array('hardlink', $opts) || in_array('allow_hardlink', $options))) {
+			foreach ($multiple_links as $file) {
+				if (!is_file($file)) {
+					// strip $home_dir from $file
+					if (substr($file, 0, strlen(rtrim($home_dir, '/'))) == rtrim($home_dir, '/')) {
+						$file = substr($file, strlen(rtrim($home_dir, '/')));
+					}
+					if (is_file($file)) { // file exists in root
+						$app->log("update_jailkit_chroot: previously hardlinked file still missing, running jk_cp to restore: $file", LOGLEVEL_DEBUG);
+						$cmd = 'jk_cp -j ? ' . $jk_cp_args . ' ' . escapeshellarg($file);
+						$this->exec_safe($cmd, $home_dir);
+					} else {
+						// not necessarily an error
+						$app->log("update_jailkit_chroot: previously hardlinked file was not restored and is no longer present in system: $file", LOGLEVEL_DEBUG);
+					}
+				}
+			}
 		}
 
 		// Fix permissions of the root firectory
 		$this->chmod($home_dir . '/bin', 0755, true);  // was chmod g-w $CHROOT_HOMEDIR/bin
 
-		// mysql needs the socket in the chrooted environment
-		$this->mkdirpath($home_dir . '/var/run/mysqld');
+		// remove non-existent jails from /etc/jailkit/jk_socketd.ini
+		if (is_file('/etc/jailkit/jk_socketd.ini')) {
+			$rewrite = false;
+			$jk_socketd_ini = $app->ini_parser->parse_ini_file('/etc/jailkit/jk_socketd.ini');
+			foreach ($jk_socketd_ini as $log => $settings) {
+				$jail = preg_replace('@/dev/log$@', '', $log);
+				if ($jail != $log && !is_dir($jail)) {
+					unset($jk_socketd_ini[$log]);
+					$rewrite=true;
+				}
+			}
+			if ($rewrite) {
+				$app->log('update_jailkit_chroot: writing /etc/jailkit/jk_socketd.ini', LOGLEVEL_DEBUG);
+				$app->ini_parse->write_ini_file($jk_socketd_ini, '/etc/jailkit/jk_socketd.ini');
+			}
+		}
+
+		return true;
+	}
+
+	public function delete_jailkit_chroot($home_dir) {
+		global $app;
+
+		$app->uses('ini_parser');
 
-		// ln /var/run/mysqld/mysqld.sock $CHROOT_HOMEDIR/var/run/mysqld/mysqld.sock
-		if(!file_exists("/var/run/mysqld/mysqld.sock")) {
-			$this->exec_safe('ln ? ?', '/var/run/mysqld/mysqld.sock', $home_dir . '/var/run/mysqld/mysqld.sock');
+		// Disallow operating on root directory
+		if(realpath($home_dir) == '/') {
+			$app->log("delete_jailkit_chroot: invalid home_dir: $home_dir", LOGLEVEL_WARN);
+			return false;
+		}
+
+		if(!is_dir($home_dir)) {
+			$app->log("delete_jailkit_chroot: jail directory does not exist: $home_dir", LOGLEVEL_DEBUG);
+			return false;
+		}
+
+		$jailkit_directories = array(
+			'bin',
+			'dev',
+			'etc',
+			'lib',
+			'lib32',
+			'lib64',
+			'opt',
+			'sys',
+			'usr',
+			'var',
+			'run',		# not used by jailkit, but added for cleanup
+		);
+
+		$removed = '';
+		foreach ($jailkit_directories as $dir) {
+			$jail_dir = rtrim($home_dir, '/') . '/'.$dir;
+
+			if (is_link($jail_dir)) {
+				unlink($jail_dir);
+				$removed .= ' /'.$dir;
+			} elseif (is_dir($jail_dir)) {
+				$this->rmdir($jail_dir, true);
+				$removed .= ' /'.$dir;
+			}
+
+		}
+
+		$app->log("delete_jailkit_chroot: removed from jail $home_dir: $removed", LOGLEVEL_DEBUG);
+
+		// remove /home if empty
+		$home = rtrim($home_dir, '/') . '/home';
+		@rmdir($home);  # ok to fail if non-empty
+
+		// otherwise archive under /private
+		$private = rtrim($home_dir, '/') . '/private';
+		if (is_dir($home) && is_dir($private)) {
+			$archive = $private.'/home-'.date('c');
+			rename($home, $archive);
+		}
+
+		// remove $home_dir from /etc/jailkit/jk_socketd.ini
+		if (is_file('/etc/jailkit/jk_socketd.ini')) {
+			$jk_socketd_ini = $app->ini_parser->parse_ini_file('/etc/jailkit/jk_socketd.ini');
+			$log = $home . '/dev/log';
+			if (isset($jk_socketd_ini[$log])) {
+				unset($jk_socketd_ini[$log]);
+				$app->log('delete_jailkit_chroot: writing /etc/jailkit/jk_socketd.ini', LOGLEVEL_DEBUG);
+				$app->ini_parse->write_ini_file($jk_socketd_ini, '/etc/jailkit/jk_socketd.ini');
+			}
 		}
 
 		return true;
diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php
index 882b39903a9a5a56ee40ba55f4343b6f4627514c..424ac15e92509a5ad7d522374d2c4264daac0257 100644
--- a/server/plugins-available/apache2_plugin.inc.php
+++ b/server/plugins-available/apache2_plugin.inc.php
@@ -37,6 +37,8 @@ class apache2_plugin {
 	var $action = '';
 	var $ssl_certificate_changed = false;
 	var $update_letsencrypt = false;
+	var $website = null;
+	var $jailkit_config = null;
 
 	//* This function is called during ispconfig installation to determine
 	//  if a symlink shall be created for this plugin.
@@ -779,7 +781,7 @@ class apache2_plugin {
 		if($data['new']['stats_type'] != '' && !is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/stats');
 		if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
 		if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
-		if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
+		if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp', 0770);
 		if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
 
 		if(!is_dir($data['new']['document_root'].'/.ssh')) {
@@ -797,6 +799,77 @@ class apache2_plugin {
 			$app->system->chgrp($data['new']['document_root'].'/private', $groupname);
 		}
 
+		// load jailkit server config
+		$jailkit_config = $app->getconf->get_server_config($conf['server_id'], 'jailkit');
+
+		// website overrides
+		if (isset($data['new']['jailkit_chroot_app_sections']) && $data['new']['jailkit_chroot_app_sections'] != '' ) {
+			$jailkit_config['jailkit_chroot_app_sections'] = $data['new']['jailkit_chroot_app_sections'];
+		}
+		if (isset($data['new']['jailkit_chroot_app_programs']) && $data['new']['jailkit_chroot_app_programs'] != '' ) {
+			$jailkit_config['jailkit_chroot_app_programs'] = $data['new']['jailkit_chroot_app_programs'];
+		}
+
+		$last_updated = preg_split('/[\s,]+/', $jailkit_config['jailkit_chroot_app_sections']
+						  .' '.$jailkit_config['jailkit_chroot_app_programs']
+						  .' '.$jailkit_config['jailkit_chroot_cron_programs']);
+		$last_updated = array_unique($last_updated, SORT_REGULAR);
+		sort($last_updated, SORT_STRING);
+		$update_hash = hash('md5', implode(' ', $last_updated));
+
+		// Create jailkit chroot when enabling php_fpm_chroot
+		if($data['new']['php_fpm_chroot'] == 'y' && $data['old']['php_fpm_chroot'] != 'y') {
+			$website = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ?', $data['new']['domain_id']);
+			$this->website = array_merge($website, $data['new'], array('new_jailkit_hash' => $update_hash));
+			$this->jailkit_config = $jailkit_config;
+			$this->_setup_jailkit_chroot();
+			$this->_add_jailkit_user();
+			$check_for_jailkit_updates=false;
+		// else delete if unused
+		} elseif ($data['new']['delete_unused_jailkit'] == 'y' && $data['new']['php_fpm_chroot'] != 'y') {
+			$check_for_jailkit_updates=false;
+			$this->_delete_jailkit_if_unused($data['new']['domain_id']);
+			if(is_dir($data['new']['document_root'].'/etc/jailkit')) {
+				$check_for_jailkit_updates=true;
+			}
+		// else update if needed
+		} elseif ($data['new']['delete_unused_jailkit'] != 'y') {
+			$check_for_jailkit_updates=true;
+		}
+
+		// If jail exists (and wasn't deleted), we may need to update it
+		if($check_for_jailkit_updates &&
+		   ( ($data['old']['jailkit_chroot_app_sections'] != $data['new']['jailkit_chroot_app_sections']) ||
+		     ($data['old']['jailkit_chroot_app_programs'] != $data['new']['jailkit_chroot_app_programs']) ) )
+		{
+
+			if (isset($jailkit_config['jailkit_hardlinks'])) {
+				if ($jailkit_config['jailkit_hardlinks'] == 'yes') {
+					$options = array('hardlink');
+				} elseif ($jailkit_config['jailkit_hardlinks'] == 'no') {
+					$options = array();
+				}
+			} else {
+				$options = array('allow_hardlink');
+			}
+
+			$options[] = 'force';
+
+			$sections = $jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $jailkit_config['jailkit_chroot_cron_programs'];
+
+			// don't update if last_jailkit_hash is the same
+			$tmp = $app->db->queryOneRecord('SELECT `last_jailkit_hash` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
+			if ($update_hash != $tmp['last_jailkit_hash']) {
+				$app->system->update_jailkit_chroot($data['new']['document_root'], $sections, $programs, $options);
+
+				// this gets last_jailkit_update out of sync with master db, but that is ok,
+				// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+				$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $update_hash, $data['new']['document_root']);
+			}
+			unset($tmp);
+		}
 
 		// Remove the symlink for the site, if site is renamed
 		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
@@ -1342,13 +1415,13 @@ class apache2_plugin {
 
 			switch($data['new']['subdomain']) {
 			case 'www':
-				$rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
+				$rewrite_rules[] = array('rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
 					'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 					'rewrite_target'  => $rewrite_target,
 					'rewrite_target_ssl' => $rewrite_target_ssl,
 					'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
 					'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
-				$rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
+				$rewrite_rules[] = array('rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
 					'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
 					'rewrite_target'  => $rewrite_target,
 					'rewrite_target_ssl' => $rewrite_target_ssl,
@@ -3632,6 +3705,156 @@ class apache2_plugin {
 		return $seo_redirects;
 	}
 
+	function _setup_jailkit_chroot()
+	{
+		global $app;
+
+		$app->uses('system');
+
+		if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
+			if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
+				$options = array( 'hardlink');
+			} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
+				$options = array();
+			}
+		} else {
+			$options = array( 'allow_hardlink');
+		}
+
+		// should move return here if $this->website['new_jailkit_hash'] == $this->website['last_jailkit_hash'] ?
+
+		// check if the chroot environment is created yet if not create it with a list of program sections from the config
+		if (!is_dir($this->website['document_root'].'/etc/jailkit'))
+		{
+			$app->system->create_jailkit_chroot($this->website['document_root'], $this->jailkit_config['jailkit_chroot_app_sections'], $options);
+			$app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
+
+			$this->_add_jailkit_programs($options);
+
+			$app->load('tpl');
+
+			$tpl = new tpl();
+			$tpl->newTemplate("bash.bashrc.master");
+
+			$tpl->setVar('jailkit_chroot', true);
+			$tpl->setVar('domain', $this->website['domain']);
+			$tpl->setVar('home_dir', $this->_get_home_dir(""));
+
+			$bashrc = $this->website['document_root'].'/etc/bash.bashrc';
+			if(@is_file($bashrc) || @is_link($bashrc)) unlink($bashrc);
+
+			file_put_contents($bashrc, $tpl->grab());
+			unset($tpl);
+
+			$app->log("Added bashrc script: ".$bashrc, LOGLEVEL_DEBUG);
+
+			$tpl = new tpl();
+			$tpl->newTemplate("motd.master");
+
+			$tpl->setVar('domain', $this->website['domain']);
+
+			$motd = $this->website['document_root'].'/var/run/motd';
+			if(@is_file($motd) || @is_link($motd)) unlink($motd);
+
+			$app->system->file_put_contents($motd, $tpl->grab());
+
+		} else {
+			// force update existing jails
+			$options[] = 'force';
+
+			$sections = $this->jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $this->jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $this->jailkit_config['jailkit_chroot_cron_programs'];
+
+			if ($this->website['new_jailkit_hash'] == $this->website['last_jailkit_hash']) {
+				return;
+			}
+
+			$app->system->update_jailkit_chroot($this->website['document_root'], $sections, $programs, $options);
+		}
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $this->website['new_jailkit_hash'], $this->website['document_root']);
+	}
+
+	function _add_jailkit_programs($opts=array())
+	{
+		global $app;
+
+		$app->uses('system');
+
+		//copy over further programs and its libraries
+		$app->system->create_jailkit_programs($this->website['document_root'], $this->jailkit_config['jailkit_chroot_app_programs'], $opts);
+		$app->log("Added app programs to jailkit chroot", LOGLEVEL_DEBUG);
+
+		$app->system->create_jailkit_programs($this->website['document_root'], $this->jailkit_config['jailkit_chroot_cron_programs'], $opts);
+		$app->log("Added cron programs to jailkit chroot", LOGLEVEL_DEBUG);
+	}
+
+	function _get_home_dir($username)
+	{
+		return str_replace("[username]", $username, $this->jailkit_config['jailkit_chroot_home']);
+	}
+
+	function _add_jailkit_user()
+	{
+		global $app;
+
+		// add the user to the chroot
+		$jailkit_chroot_userhome = $this->_get_home_dir($this->website['system_user']);
+
+		if(!is_dir($this->website['document_root'].'/etc')) $app->system->mkdir($this->website['document_root'].'/etc', 0755, true);
+		if(!is_file($this->website['document_root'].'/etc/passwd')) $app->system->exec_safe('touch ?', $this->website['document_root'].'/etc/passwd');
+
+		// IMPORTANT!
+		// ALWAYS create the user. Even if the user was created before
+		// if we check if the user exists, then a update (no shell -> jailkit) will not work
+		// and the user has FULL ACCESS to the root of the server!
+		$app->system->create_jailkit_user($this->website['system_user'], $this->website['document_root'], $jailkit_chroot_userhome);
+
+		if(!is_dir($this->website['document_root'].$jailkit_chroot_userhome)) {
+			$app->system->mkdir($this->website['document_root'].$jailkit_chroot_userhome, 0750, true);
+			$app->system->chown($this->website['document_root'].$jailkit_chroot_userhome, $this->website['system_user']);
+			$app->system->chgrp($this->website['document_root'].$jailkit_chroot_userhome, $this->website['system_group']);
+		}
+
+		$app->log("Added created jailkit user home in : ".$this->website['document_root'].$jailkit_chroot_userhome, LOGLEVEL_DEBUG);
+	}
+
+	private function _delete_jailkit_if_unused($parent_domain_id) {
+		global $app, $conf;
+
+		// get jail directory
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ? OR `parent_domain_id` = ? AND `document_root` IS NOT NULL", $parent_domain_id, $parent_domain_id);
+		if (!is_dir($parent_domain['document_root'])) {
+			return;
+		}
+
+		// chroot is used by php-fpm
+		if (isset($parent_domain['php_fpm_chroot']) && $parent_domain['php_fpm_chroot'] == 'y') {
+			return;
+		}
+
+		// check for any shell_user using this jail
+		$inuse = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `parent_domain_id` = ? AND `chroot` = ?', $parent_domain_id, 'jailkit');
+		if($inuse) {
+			return;
+		}
+
+		// check for any cron job using this jail
+		$inuse = $app->db->queryOneRecord('SELECT id FROM `cron` WHERE `parent_domain_id` = ? AND `type` = ?', $parent_domain_id, 'chrooted');
+		if($inuse) {
+			return;
+		}
+
+		$app->system->delete_jailkit_chroot($parent_domain['document_root']);
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = NULL WHERE `document_root` = ?", $parent_domain['document_root']);
+	}
+
 } // end class
 
 ?>
diff --git a/server/plugins-available/cron_jailkit_plugin.inc.php b/server/plugins-available/cron_jailkit_plugin.inc.php
index 0650ad87a3aefee4057d4d78d6a40214c2454852..deb6211f0e47bd9d82659e8a4286a64cc885ad2a 100644
--- a/server/plugins-available/cron_jailkit_plugin.inc.php
+++ b/server/plugins-available/cron_jailkit_plugin.inc.php
@@ -76,7 +76,7 @@ class cron_jailkit_plugin {
 		}
 
 		//* get data from web
-		$parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `domain` FROM `web_domain` WHERE `domain_id` = ?", $data["new"]["parent_domain_id"]);
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ?", $data["new"]["parent_domain_id"]);
 		if(!$parent_domain["domain_id"]) {
 			$app->log("Parent domain not found", LOGLEVEL_WARN);
 			return 0;
@@ -105,8 +105,12 @@ class cron_jailkit_plugin {
 				// load the server configuration options
 				$app->uses("getconf");
 				$this->data = $data;
-				$this->app = $app;
 				$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+				foreach (array('jailkit_chroot_app_sections', 'jailkit_chroot_app_programs') as $section) {
+					if (isset($parent_domain[$section]) && $parent_domain[$section] != '' ) {
+						$this->jailkit_config[$section] = $parent_domain[$section];
+					}
+				}
 
 				$this->_update_website_security_level();
 
@@ -141,7 +145,7 @@ class cron_jailkit_plugin {
 			return 0;
 		}
 		//* get data from web
-		$parent_domain = $app->db->queryOneRecord("SELECT `domain_id`, `system_user`, `system_group`, `document_root`, `domain` FROM `web_domain` WHERE `domain_id` = ?", $data["new"]["parent_domain_id"]);
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ?", $data["new"]["parent_domain_id"]);
 		if(!$parent_domain["domain_id"]) {
 			$app->log("Parent domain not found", LOGLEVEL_WARN);
 			return 0;
@@ -167,29 +171,25 @@ class cron_jailkit_plugin {
 			{
 				$app->log("Jailkit Plugin (Cron) -> setting up jail", LOGLEVEL_DEBUG);
 				// load the server configuration options
-				/*
 				$app->uses("getconf");
 				$this->data = $data;
-				$this->app = $app;
-				$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
-                $this->parent_domain = $parent_domain;
-
-				$this->_setup_jailkit_chroot();
-				$this->_add_jailkit_user();
-				*/
-				$app->uses("getconf");
-				$this->data = $data;
-				$this->app = $app;
 				$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+				foreach (array('jailkit_chroot_app_sections', 'jailkit_chroot_app_programs') as $section) {
+					if (isset($parent_domain[$section]) && $parent_domain[$section] != '' ) {
+						$this->jailkit_config[$section] = $parent_domain[$section];
+					}
+				}
 
 				$this->_update_website_security_level();
 
 				$app->system->web_folder_protection($parent_domain['document_root'], false);
 
 				$this->_setup_jailkit_chroot();
+
 				$this->_add_jailkit_user();
 
 				$this->_update_website_security_level();
+
 				$app->system->web_folder_protection($parent_domain['document_root'], true);
 			}
 
@@ -205,22 +205,59 @@ class cron_jailkit_plugin {
 	function delete($event_name, $data) {
 		global $app, $conf;
 
-		//* nothing to do here!
+		if($data["old"]["parent_domain_id"] == '') {
+			$app->log("Parent domain not set", LOGLEVEL_WARN);
+			return 0;
+		}
+
+		$app->uses('system');
+
+		if ($data['old']['type'] == "chrooted")
+		{
+			$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ?", $data['old']['parent_domain_id']);
 
+			// should copy some _delete_homedir() functionality from shelluser_jailkit_plugin ?
+
+			if (isset($parent_domain['delete_unused_jailkit']) && $parent_domain['delete_unused_jailkit'] == 'y') {
+				$app->system->web_folder_protection($parent_domain['document_root'], false);
+				$this->_delete_jailkit_if_unused($parent_domain['domain_id']);
+				$app->system->web_folder_protection($parent_domain['document_root'], true);
+			}
+		}
 	}
 
 	function _setup_jailkit_chroot()
 	{
 		global $app;
 
-		//check if the chroot environment is created yet if not create it with a list of program sections from the config
+		if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
+			if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
+				$options = array('hardlink');
+			} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
+				$options = array();
+			}
+		} else {
+			$options = array('allow_hardlink');
+		}
+
+		$last_updated = preg_split('/[\s,]+/', $this->jailkit_config['jailkit_chroot_app_sections']
+						  .' '.$this->jailkit_config['jailkit_chroot_app_programs']
+						  .' '.$this->jailkit_config['jailkit_chroot_cron_programs']);
+		$last_updated = array_unique($last_updated, SORT_REGULAR);
+		sort($last_updated, SORT_STRING);
+		$update_hash = hash('md5', implode(' ', $last_updated));
+
+		// should move return here if $update_hash == $parent_domain['last_jailkit_hash'] ?
+
+		// check if the chroot environment is created yet if not create it with a list of program sections from the config
 		if (!is_dir($this->parent_domain['document_root'].'/etc/jailkit'))
 		{
-			$app->system->create_jailkit_chroot($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_sections']);
+			$app->system->create_jailkit_chroot($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_sections'], $options);
+			$app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
 
-			$this->app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
+			$this->_add_jailkit_programs($options);
 
-			$this->app->load('tpl');
+			$app->load('tpl');
 
 			$tpl = new tpl();
 			$tpl->newTemplate("bash.bashrc.master");
@@ -235,7 +272,7 @@ class cron_jailkit_plugin {
 			$app->system->file_put_contents($bashrc, $tpl->grab());
 			unset($tpl);
 
-			$this->app->log('Added bashrc script: '.$bashrc, LOGLEVEL_DEBUG);
+			$app->log('Added bashrc script: '.$bashrc, LOGLEVEL_DEBUG);
 
 			$tpl = new tpl();
 			$tpl->newTemplate('motd.master');
@@ -247,30 +284,46 @@ class cron_jailkit_plugin {
 
 			$app->system->file_put_contents($motd, $tpl->grab());
 
+		} else {
+			// force update existing jails
+			$options[] = 'force';
+
+			$sections = $this->jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $this->jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $this->jailkit_config['jailkit_chroot_cron_programs'];
+
+			if ($update_hash == $parent_domain['last_jailkit_hash']) {
+				return;
+			}
+
+			$app->system->update_jailkit_chroot($this->parent_domain['document_root'], $sections, $programs, $options);
 		}
-		$this->_add_jailkit_programs();
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $update_hash, $this->parent_domain['document_root']);
 	}
 
-	function _add_jailkit_programs()
+	function _add_jailkit_programs($opts=array())
 	{
 		global $app;
 
 		//copy over further programs and its libraries
-		$app->system->create_jailkit_programs($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_programs']);
-		$this->app->log("Added app programs to jailkit chroot", LOGLEVEL_DEBUG);
-		
-		$app->system->create_jailkit_programs($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_cron_programs']);
-		$this->app->log("Added cron programs to jailkit chroot", LOGLEVEL_DEBUG);
+		$app->system->create_jailkit_programs($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_programs'], $opts);
+		$app->log("Added app programs to jailkit chroot", LOGLEVEL_DEBUG);
+
+		$app->system->create_jailkit_programs($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_cron_programs'], $opts);
+		$app->log("Added cron programs to jailkit chroot", LOGLEVEL_DEBUG);
 	}
 
 	function _add_jailkit_user()
 	{
 		global $app;
 
-		//add the user to the chroot
+		// add the user to the chroot
 		$jailkit_chroot_userhome = $this->_get_home_dir($this->parent_domain['system_user']);
 
-		if(!is_dir($this->parent_domain['document_root'].'/etc')) mkdir($this->parent_domain['document_root'].'/etc');
+		if(!is_dir($this->parent_domain['document_root'].'/etc')) $app->system->mkdir($this->parent_domain['document_root'].'/etc', 0755, true);
 		if(!is_file($this->parent_domain['document_root'].'/etc/passwd')) $app->system->exec_safe('touch ?', $this->parent_domain['document_root'].'/etc/passwd');
 
 		// IMPORTANT!
@@ -279,9 +332,11 @@ class cron_jailkit_plugin {
 		// and the user has FULL ACCESS to the root of the server!
 		$app->system->create_jailkit_user($this->parent_domain['system_user'], $this->parent_domain['document_root'], $jailkit_chroot_userhome);
 
-		$app->system->mkdir($this->parent_domain['document_root'].$jailkit_chroot_userhome, 0755, true);
-		$app->system->chown($this->parent_domain['document_root'].$jailkit_chroot_userhome, $this->parent_domain['system_user']);
-		$app->system->chgrp($this->parent_domain['document_root'].$jailkit_chroot_userhome, $this->parent_domain['system_group']);
+		if(!is_dir($this->parent_domain['document_root'].$jailkit_chroot_userhome)) {
+			$app->system->mkdir($this->parent_domain['document_root'].$jailkit_chroot_userhome, 0750, true);
+			$app->system->chown($this->parent_domain['document_root'].$jailkit_chroot_userhome, $this->parent_domain['system_user']);
+			$app->system->chgrp($this->parent_domain['document_root'].$jailkit_chroot_userhome, $this->parent_domain['system_group']);
+		}
 
 	}
 
@@ -311,5 +366,38 @@ class cron_jailkit_plugin {
 		}
 	}
 
+	private function _delete_jailkit_if_unused($parent_domain_id) {
+		global $app, $conf;
+
+		// get jail directory
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ? OR `parent_domain_id` = ? AND `document_root` IS NOT NULL", $parent_domain_id, $parent_domain_id);
+		if (!is_dir($parent_domain['document_root'])) {
+			return;
+		}
+
+		// chroot is used by php-fpm
+		if (isset($parent_domain['php_fpm_chroot']) && $parent_domain['php_fpm_chroot'] == 'y') {
+			return;
+		}
+
+		// check for any shell_user using this jail
+		$inuse = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `parent_domain_id` = ? AND `chroot` = ?', $parent_domain_id, 'jailkit');
+		if($inuse) {
+			return;
+		}
+
+		// check for any cron job using this jail
+		$inuse = $app->db->queryOneRecord('SELECT id FROM `cron` WHERE `parent_domain_id` = ? AND `type` = ?', $parent_domain_id, 'chrooted');
+		if($inuse) {
+			return;
+		}
+
+		$app->system->delete_jailkit_chroot($parent_domain['document_root']);
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = NULL WHERE `document_root` = ?", $parent_domain['document_root']);
+	}
+
 } // end class
 
diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php
index 28611ce1784b42983f8f1eeb2fd4e1b91fd6caa9..d688ccc9e6ae7438c5a8bf5c2d438247704c9963 100644
--- a/server/plugins-available/nginx_plugin.inc.php
+++ b/server/plugins-available/nginx_plugin.inc.php
@@ -37,6 +37,8 @@ class nginx_plugin {
 	var $action = '';
 	var $ssl_certificate_changed = false;
 	var $update_letsencrypt = false;
+	var $website = null;
+	var $jailkit_config = null;
 
 	//* This function is called during ispconfig installation to determine
 	//  if a symlink shall be created for this plugin.
@@ -636,6 +638,78 @@ class nginx_plugin {
 		}
 
 
+		// load jailkit server config
+		$jailkit_config = $app->getconf->get_server_config($conf['server_id'], 'jailkit');
+
+		// website overrides
+		if (isset($data['new']['jailkit_chroot_app_sections']) && $data['new']['jailkit_chroot_app_sections'] != '' ) {
+			$jailkit_config['jailkit_chroot_app_sections'] = $data['new']['jailkit_chroot_app_sections'];
+		}
+		if (isset($data['new']['jailkit_chroot_app_programs']) && $data['new']['jailkit_chroot_app_programs'] != '' ) {
+			$jailkit_config['jailkit_chroot_app_programs'] = $data['new']['jailkit_chroot_app_programs'];
+		}
+
+		$last_updated = preg_split('/[\s,]+/', $jailkit_config['jailkit_chroot_app_sections']
+						  .' '.$jailkit_config['jailkit_chroot_app_programs']
+						  .' '.$jailkit_config['jailkit_chroot_cron_programs']);
+		$last_updated = array_unique($last_updated, SORT_REGULAR);
+		sort($last_updated, SORT_STRING);
+		$update_hash = hash('md5', implode(' ', $last_updated));
+
+		// Create jailkit chroot when enabling php_fpm_chroot
+		if($data['new']['php_fpm_chroot'] == 'y' && $data['old']['php_fpm_chroot'] != 'y') {
+			$website = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ?', $data['new']['domain_id']);
+			$this->website = array_merge($website, $data['new'], array('new_jailkit_hash' => $update_hash));
+			$this->jailkit_config = $jailkit_config;
+			$this->_setup_jailkit_chroot();
+			$this->_add_jailkit_user();
+			$check_for_jailkit_updates=false;
+		// else delete if unused
+		} elseif ($data['new']['delete_unused_jailkit'] == 'y' && $data['new']['php_fpm_chroot'] != 'y') {
+			$check_for_jailkit_updates=false;
+			$this->_delete_jailkit_if_unused($data['new']['domain_id']);
+			if(is_dir($data['new']['document_root'].'/etc/jailkit')) {
+				$check_for_jailkit_updates=true;
+			}
+		// else update if needed
+		} elseif ($data['new']['delete_unused_jailkit'] != 'y') {
+			$check_for_jailkit_updates=true;
+		}
+
+		// If jail exists (and wasn't deleted), we may need to update it
+		if($check_for_jailkit_updates &&
+		   ( ($data['old']['jailkit_chroot_app_sections'] != $data['new']['jailkit_chroot_app_sections']) ||
+		     ($data['old']['jailkit_chroot_app_programs'] != $data['new']['jailkit_chroot_app_programs']) ) )
+		{
+
+			if (isset($jailkit_config['jailkit_hardlinks'])) {
+				if ($jailkit_config['jailkit_hardlinks'] == 'yes') {
+					$options = array('hardlink');
+				} elseif ($jailkit_config['jailkit_hardlinks'] == 'no') {
+					$options = array();
+				}
+			} else {
+				$options = array('allow_hardlink');
+			}
+
+			$options[] = 'force';
+
+			$sections = $jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $jailkit_config['jailkit_chroot_cron_programs'];
+
+			// don't update if last_jailkit_hash is the same
+			$tmp = $app->db->queryOneRecord('SELECT `last_jailkit_hash` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
+			if ($update_hash != $tmp['last_jailkit_hash']) {
+				$app->system->update_jailkit_chroot($data['new']['document_root'], $sections, $programs, $options);
+
+				// this gets last_jailkit_update out of sync with master db, but that is ok,
+				// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+				$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $update_hash, $data['new']['document_root']);
+			}
+			unset($tmp);
+		}
+
 		// Remove the symlink for the site, if site is renamed
 		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
 			if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) $app->system->exec_safe('rm -rf ?', '/var/log/ispconfig/httpd/'.$data['old']['domain']);
@@ -3403,6 +3477,155 @@ class nginx_plugin {
 		return $seo_redirects;
 	}
 
+	function _setup_jailkit_chroot()
+	{
+		global $app;
+
+		$app->uses('system');
+
+		if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
+			if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
+				$options = array( 'hardlink');
+			} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
+				$options = array();
+			}
+		} else {
+			$options = array( 'allow_hardlink');
+		}
+
+		// should move return here if $this->website['new_jailkit_hash'] == $this->website['last_jailkit_hash'] ?
+
+		// check if the chroot environment is created yet if not create it with a list of program sections from the config
+		if (!is_dir($this->website['document_root'].'/etc/jailkit'))
+		{
+			$app->system->create_jailkit_chroot($this->website['document_root'], $this->jailkit_config['jailkit_chroot_app_sections'], $options);
+			$app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
+
+			$this->_add_jailkit_programs($options);
+
+			$app->load('tpl');
+
+			$tpl = new tpl();
+			$tpl->newTemplate("bash.bashrc.master");
+
+			$tpl->setVar('jailkit_chroot', true);
+			$tpl->setVar('domain', $this->website['domain']);
+			$tpl->setVar('home_dir', $this->_get_home_dir(""));
+
+			$bashrc = $this->website['document_root'].'/etc/bash.bashrc';
+			if(@is_file($bashrc) || @is_link($bashrc)) unlink($bashrc);
+
+			file_put_contents($bashrc, $tpl->grab());
+			unset($tpl);
+
+			$app->log("Added bashrc script: ".$bashrc, LOGLEVEL_DEBUG);
+
+			$tpl = new tpl();
+			$tpl->newTemplate("motd.master");
+
+			$tpl->setVar('domain', $this->website['domain']);
+
+			$motd = $this->website['document_root'].'/var/run/motd';
+			if(@is_file($motd) || @is_link($motd)) unlink($motd);
+
+			$app->system->file_put_contents($motd, $tpl->grab());
+
+		} else {
+			// force update existing jails
+			$options[] = 'force';
+
+			$sections = $this->jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $this->jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $this->jailkit_config['jailkit_chroot_cron_programs'];
+
+			if ($this->website['new_jailkit_hash'] == $this->website['last_jailkit_hash']) {
+				return;
+			}
+
+			$app->system->update_jailkit_chroot($this->website['document_root'], $sections, $programs, $options);
+		}
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $this->website['new_jailkit_hash'], $this->website['document_root']);
+	}
+
+	function _add_jailkit_programs($opts=array())
+	{
+		global $app;
+
+		$app->uses('system');
+
+		//copy over further programs and its libraries
+		$app->system->create_jailkit_programs($this->website['document_root'], $this->jailkit_config['jailkit_chroot_app_programs'], $opts);
+		$app->log("Added app programs to jailkit chroot", LOGLEVEL_DEBUG);
+
+		$app->system->create_jailkit_programs($this->website['document_root'], $this->jailkit_config['jailkit_chroot_cron_programs'], $opts);
+		$app->log("Added cron programs to jailkit chroot", LOGLEVEL_DEBUG);
+	}
+
+	function _get_home_dir($username)
+	{
+		return str_replace("[username]", $username, $this->jailkit_config['jailkit_chroot_home']);
+	}
+
+	function _add_jailkit_user()
+	{
+		global $app;
+
+		// add the user to the chroot
+		$jailkit_chroot_userhome = $this->_get_home_dir($this->website['system_user']);
+
+		if(!is_dir($this->website['document_root'].'/etc')) $app->system->mkdir($this->website['document_root'].'/etc', 0755, true);
+		if(!is_file($this->website['document_root'].'/etc/passwd')) $app->system->exec_safe('touch ?', $this->website['document_root'].'/etc/passwd');
+
+		// IMPORTANT!
+		// ALWAYS create the user. Even if the user was created before
+		// if we check if the user exists, then a update (no shell -> jailkit) will not work
+		// and the user has FULL ACCESS to the root of the server!
+		$app->system->create_jailkit_user($this->website['system_user'], $this->website['document_root'], $jailkit_chroot_userhome);
+
+		if(!is_dir($this->website['document_root'].$jailkit_chroot_userhome)) {
+			$app->system->mkdir($this->website['document_root'].$jailkit_chroot_userhome, 0750, true);
+			$app->system->chown($this->website['document_root'].$jailkit_chroot_userhome, $this->website['system_user']);
+			$app->system->chgrp($this->website['document_root'].$jailkit_chroot_userhome, $this->website['system_group']);
+		}
+		$app->log("Added created jailkit user home in : ".$this->website['document_root'].$jailkit_chroot_userhome, LOGLEVEL_DEBUG);
+	}
+
+	private function _delete_jailkit_if_unused($parent_domain_id) {
+		global $app, $conf;
+
+		// get jail directory
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ? OR `parent_domain_id` = ? AND `document_root` IS NOT NULL", $parent_domain_id, $parent_domain_id);
+		if (!is_dir($parent_domain['document_root'])) {
+			return;
+		}
+
+		// chroot is used by php-fpm
+		if (isset($parent_domain['php_fpm_chroot']) && $parent_domain['php_fpm_chroot'] == 'y') {
+			return;
+		}
+
+		// check for any shell_user using this jail
+		$inuse = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `parent_domain_id` = ? AND `chroot` = ?', $parent_domain_id, 'jailkit');
+		if($inuse) {
+			return;
+		}
+
+		// check for any cron job using this jail
+		$inuse = $app->db->queryOneRecord('SELECT id FROM `cron` WHERE `parent_domain_id` = ? AND `type` = ?', $parent_domain_id, 'chrooted');
+		if($inuse) {
+			return;
+		}
+
+		$app->system->delete_jailkit_chroot($parent_domain['document_root']);
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = NULL WHERE `document_root` = ?", $parent_domain['document_root']);
+	}
+
 } // end class
 
 ?>
diff --git a/server/plugins-available/shelluser_base_plugin.inc.php b/server/plugins-available/shelluser_base_plugin.inc.php
index e3276755bed03a99f0faa84d9e8983bed48f4e20..71653cf5c2d6fc9e36dcf914eefc02365ff3336b 100755
--- a/server/plugins-available/shelluser_base_plugin.inc.php
+++ b/server/plugins-available/shelluser_base_plugin.inc.php
@@ -146,7 +146,6 @@ class shelluser_base_plugin {
 				// call the ssh-rsa update function
 				$app->uses("getconf");
 				$this->data = $data;
-				$this->app = $app;
 				$this->_setup_ssh_rsa();
 
 				//* Create .bash_history file
@@ -233,7 +232,6 @@ class shelluser_base_plugin {
 					$app->system->web_folder_protection($web['document_root'], false);
 
 					if($homedir != $homedir_old){
-						$app->system->web_folder_protection($web['document_root'], false);
 						// Rename dir, in case the new directory exists already.
 						if(is_dir($homedir)) {
 							$app->log("New Homedir exists, renaming it to ".$homedir.'_bak', LOGLEVEL_DEBUG);
@@ -245,10 +243,8 @@ class shelluser_base_plugin {
 						$app->file->mkdirs($homedir, '0750');
 						$app->system->chown($homedir,$data['new']['puser']);
 						$app->system->chgrp($homedir,$data['new']['pgroup']);
-						$app->system->web_folder_protection($web['document_root'], true);
 					} else {
 						if(!is_dir($homedir)){
-							$app->system->web_folder_protection($web['document_root'], false);
 							if(!is_dir($data['new']['dir'].'/home')){
 								$app->file->mkdirs($data['new']['dir'].'/home', '0755');
 								$app->system->chown($data['new']['dir'].'/home','root');
@@ -257,7 +253,6 @@ class shelluser_base_plugin {
 							$app->file->mkdirs($homedir, '0750');
 							$app->system->chown($homedir,$data['new']['puser']);
 							$app->system->chgrp($homedir,$data['new']['pgroup']);
-							$app->system->web_folder_protection($web['document_root'], true);
 						}
 					}
 					$app->system->usermod($data['old']['username'], 0, $app->system->getgid($data['new']['pgroup']), $homedir, $data['new']['shell'], $data['new']['password'], $data['new']['username']);
@@ -266,7 +261,6 @@ class shelluser_base_plugin {
 					// call the ssh-rsa update function
 					$app->uses("getconf");
 					$this->data = $data;
-					$this->app = $app;
 					$this->_setup_ssh_rsa();
 
 					//* Create .bash_history file
@@ -361,7 +355,7 @@ class shelluser_base_plugin {
 
 				// We delete only non jailkit users, jailkit users will be deleted by the jailkit plugin.
 				if ($data['old']['chroot'] != "jailkit") {
-					// if this web uses PHP-FPM, that PPH-FPM service must be stopped before we can delete this user
+					// if this web uses PHP-FPM, that PHP-FPM service must be stopped before we can delete this user
 					if($web['php'] == 'php-fpm'){
 						if($web['server_php_id'] != 0){
 							$default_php_fpm = false;
@@ -405,13 +399,13 @@ class shelluser_base_plugin {
 
 	private function _setup_ssh_rsa() {
 		global $app;
-		$this->app->log("ssh-rsa setup shelluser_base", LOGLEVEL_DEBUG);
+		$app->log("ssh-rsa setup shelluser_base", LOGLEVEL_DEBUG);
 		// Get the client ID, username, and the key
-		$domain_data = $this->app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
-		$sys_group_data = $this->app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
+		$domain_data = $app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
+		$sys_group_data = $app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
 		$id = intval($sys_group_data['client_id']);
 		$username= $sys_group_data['name'];
-		$client_data = $this->app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
+		$client_data = $app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
 		$userkey = $client_data['ssh_rsa'];
 		unset($domain_data);
 		unset($client_data);
@@ -443,7 +437,7 @@ class shelluser_base_plugin {
 			//Generate ssh-rsa-keys
 			$app->uses('functions');
 			$app->functions->generate_ssh_key($id, $username);
-			$this->app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
+			$app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
 		};
 
 		if (!file_exists($sshkeys)){
@@ -466,7 +460,7 @@ class shelluser_base_plugin {
 			// add the user's key
 			$app->system->file_put_contents($sshkeys, $final_keys);
 			$app->file->remove_blank_lines($sshkeys);
-			$this->app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
+			$app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
 		}
 
 		//* Get the keys
@@ -502,7 +496,7 @@ class shelluser_base_plugin {
 		// add the custom key
 		$app->system->file_put_contents($sshkeys, $final_keys);
 		$app->file->remove_blank_lines($sshkeys);
-		$this->app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);
+		$app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);
 
 		// set proper file permissions
 		$app->system->exec_safe("chown -R ?:? ?", $this->data['new']['puser'], $this->data['new']['pgroup'], $sshdir);
diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php
index 43d636500808fdc59fc9637a8c1128a73c985b68..7c003e44683e6a3dda2585b179fef099e0ad03fd 100755
--- a/server/plugins-available/shelluser_jailkit_plugin.inc.php
+++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php
@@ -59,11 +59,11 @@ class shelluser_jailkit_plugin {
 		/*
 		Register for the events
 		*/
-		
+
 		$app->plugins->registerEvent('shell_user_insert', $this->plugin_name, 'insert');
 		$app->plugins->registerEvent('shell_user_update', $this->plugin_name, 'update');
 		$app->plugins->registerEvent('shell_user_delete', $this->plugin_name, 'delete');
-		
+
 
 	}
 
@@ -72,14 +72,14 @@ class shelluser_jailkit_plugin {
 		global $app, $conf;
 
 		$app->uses('system,getconf');
-		
+
 		$security_config = $app->getconf->get_security_config('permissions');
 		if($security_config['allow_shell_user'] != 'yes') {
 			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
 			return false;
 		}
-		
-		
+
+
 		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
 
 		if(!$app->system->is_allowed_user($data['new']['username'], false, false)
@@ -93,7 +93,7 @@ class shelluser_jailkit_plugin {
 			// Get the UID of the parent user
 			$uid = intval($app->system->getuid($data['new']['puser']));
 			if($uid > $this->min_uid) {
-			
+
 				if($app->system->is_user($data['new']['username'])) {
 
 					/**
@@ -107,8 +107,12 @@ class shelluser_jailkit_plugin {
 						// load the server configuration options
 						$app->uses("getconf");
 						$this->data = $data;
-						$this->app = $app;
 						$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+						foreach (array('jailkit_chroot_app_sections', 'jailkit_chroot_app_programs') as $section) {
+							if (isset($web[$section]) && $web[$section] != '' ) {
+								$this->jailkit_config[$section] = $web[$section];
+							}
+						}
 
 						$this->_update_website_security_level();
 
@@ -128,6 +132,7 @@ class shelluser_jailkit_plugin {
 						$app->system->exec_safe($command, $data['new']['username']);
 
 						$this->_update_website_security_level();
+
 						$app->system->web_folder_protection($web['document_root'], true);
 						$app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG);
 					} else {
@@ -151,14 +156,12 @@ class shelluser_jailkit_plugin {
 		global $app, $conf;
 
 		$app->uses('system,getconf');
-		
+
 		$security_config = $app->getconf->get_security_config('permissions');
 		if($security_config['allow_shell_user'] != 'yes') {
 			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
 			return false;
 		}
-		
-		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
 
 		if(!$app->system->is_allowed_user($data['new']['username'], false, false)
 			|| !$app->system->is_allowed_user($data['new']['puser'], true, true)
@@ -168,11 +171,13 @@ class shelluser_jailkit_plugin {
 		}
 
 		if($app->system->is_user($data['new']['puser'])) {
+			$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']);
+
 			// Get the UID of the parent user
 			$uid = intval($app->system->getuid($data['new']['puser']));
 			if($uid > $this->min_uid) {
-			
-			
+
+
 				if($app->system->is_user($data['new']['username'])) {
 
 					/**
@@ -184,14 +189,19 @@ class shelluser_jailkit_plugin {
 						// load the server configuration options
 						$app->uses("getconf");
 						$this->data = $data;
-						$this->app = $app;
 						$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+						foreach (array('jailkit_chroot_app_sections', 'jailkit_chroot_app_programs') as $section) {
+							if (isset($web[$section]) && $web[$section] != '' ) {
+								$this->jailkit_config[$section] = $web[$section];
+							}
+						}
 
 						$this->_update_website_security_level();
 
 						$app->system->web_folder_protection($web['document_root'], false);
 
 						$this->_setup_jailkit_chroot();
+
 						$this->_add_jailkit_user();
 
 						//* call the ssh-rsa update function
@@ -224,65 +234,90 @@ class shelluser_jailkit_plugin {
 		global $app, $conf;
 
 		$app->uses('system,getconf');
-		
+
 		$security_config = $app->getconf->get_security_config('permissions');
 		if($security_config['allow_shell_user'] != 'yes') {
 			$app->log('Shell user plugin disabled by security settings.',LOGLEVEL_WARN);
 			return false;
 		}
 
-		$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['old']['parent_domain_id']);
-
 		if ($data['old']['chroot'] == "jailkit")
 		{
+			$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['old']['parent_domain_id']);
+
 			$app->uses("getconf");
 			$this->jailkit_config = $app->getconf->get_server_config($conf["server_id"], 'jailkit');
+			foreach (array('jailkit_chroot_app_sections', 'jailkit_chroot_app_programs', 'jailkit_do_not_remove_paths') as $section) {
+				if (isset($web[$section]) && $web[$section] != '' ) {
+					$this->jailkit_config[$section] = $web[$section];
+				}
+			}
 
 			$jailkit_chroot_userhome = $this->_get_home_dir($data['old']['username']);
 
 			$app->system->web_folder_protection($web['document_root'], false);
-			
+
 			$userid = intval($app->system->getuid($data['old']['username']));
 			$command = 'killall -u ? ; ';
 			$command .= 'userdel -f ? &> /dev/null';
 			$app->system->exec_safe($command, $data['old']['username'], $data['old']['username']);
-			
+
 			// Remove the jailed user from passwd and shadow file inside the jail
-			$app->system->removeLine($data['old']['dir'].'/etc/passwd', $data['old']['username']);
-			$app->system->removeLine($data['old']['dir'].'/etc/shadow', $data['old']['username']);
+			$app->system->removeLine($data['old']['dir'].'/etc/passwd', $data['old']['username'].':');
+			$app->system->removeLine($data['old']['dir'].'/etc/shadow', $data['old']['username'].':');
 
 			if(@is_dir($data['old']['dir'].$jailkit_chroot_userhome)) {
 				$this->_delete_homedir($data['old']['dir'].$jailkit_chroot_userhome,$userid,$data['old']['parent_domain_id']);
-				
+
 				$app->log("Jailkit Plugin -> delete chroot home:".$data['old']['dir'].$jailkit_chroot_userhome, LOGLEVEL_DEBUG);
 			}
 
+			if (isset($web['delete_unused_jailkit']) && $web['delete_unused_jailkit'] == 'y') {
+				$this->_delete_jailkit_if_unused($web['domain_id']);
+			}
+
 			$app->system->web_folder_protection($web['document_root'], true);
 
 		}
 
 		$app->log("Jailkit Plugin -> delete username:".$data['old']['username'], LOGLEVEL_DEBUG);
 
-
 	}
 
 	function _setup_jailkit_chroot()
 	{
 		global $app;
 
-		//check if the chroot environment is created yet if not create it with a list of program sections from the config
+		if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
+			if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
+				$options = array('hardlink');
+			} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
+				$options = array();
+			}
+		} else {
+			$options = array('allow_hardlink');
+		}
+
+		$web = $app->db->queryOneRecord("SELECT domain, last_jailkit_hash FROM web_domain WHERE domain_id = ?", $this->data['new']["parent_domain_id"]);
+
+		$last_updated = preg_split('/[\s,]+/', $this->jailkit_config['jailkit_chroot_app_sections']
+						  .' '.$this->jailkit_config['jailkit_chroot_app_programs']
+						  .' '.$this->jailkit_config['jailkit_chroot_cron_programs']);
+		$last_updated = array_unique($last_updated, SORT_REGULAR);
+		sort($last_updated, SORT_STRING);
+		$update_hash = hash('md5', implode(' ', $last_updated));
+
+		// should move return here if $update_hash == $web['last_jailkit_hash'] ?
+
+		// check if the chroot environment is created yet if not create it with a list of program sections from the config
 		if (!is_dir($this->data['new']['dir'].'/etc/jailkit'))
 		{
-			$app->system->create_jailkit_chroot($this->data['new']['dir'], $this->jailkit_config['jailkit_chroot_app_sections']);
-			$this->app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
-
-			$this->_add_jailkit_programs();
+			$app->system->create_jailkit_chroot($this->data['new']['dir'], $this->jailkit_config['jailkit_chroot_app_sections'], $options);
+			$app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
 
-			//add bash.bashrc script
-			//we need to collect the domain name to be used as the HOSTNAME in the bashrc script
-			$web = $this->app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ?", $this->data['new']["parent_domain_id"]);
+			$this->_add_jailkit_programs($options);
 
-			$this->app->load('tpl');
+			$app->load('tpl');
 
 			$tpl = new tpl();
 			$tpl->newTemplate("bash.bashrc.master");
@@ -297,7 +332,7 @@ class shelluser_jailkit_plugin {
 			file_put_contents($bashrc, $tpl->grab());
 			unset($tpl);
 
-			$this->app->log("Added bashrc script: ".$bashrc, LOGLEVEL_DEBUG);
+			$app->log("Added bashrc script: ".$bashrc, LOGLEVEL_DEBUG);
 
 			$tpl = new tpl();
 			$tpl->newTemplate("motd.master");
@@ -309,20 +344,37 @@ class shelluser_jailkit_plugin {
 
 			$app->system->file_put_contents($motd, $tpl->grab());
 
+		} else {
+			// force update existing jails
+			$options[] = 'force';
+
+			$sections = $this->jailkit_config['jailkit_chroot_app_sections'];
+			$programs = $this->jailkit_config['jailkit_chroot_app_programs'] . ' '
+				  . $this->jailkit_config['jailkit_chroot_cron_programs'];
+
+			if ($update_hash == $web['last_jailkit_hash']) {
+				return;
+			}
+
+			$app->system->update_jailkit_chroot($this->data['new']['dir'], $sections, $programs, $options);
 		}
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = ? WHERE `document_root` = ?", $update_hash, $this->data['new']['dir']);
 	}
 
-	function _add_jailkit_programs()
+	function _add_jailkit_programs($opts=array())
 	{
 		global $app;
 		$jailkit_chroot_app_programs = preg_split("/[\s,]+/", $this->jailkit_config['jailkit_chroot_app_programs']);
 		if(is_array($jailkit_chroot_app_programs) && !empty($jailkit_chroot_app_programs)){
 			foreach($jailkit_chroot_app_programs as $jailkit_chroot_app_program){
 				$jailkit_chroot_app_program = trim($jailkit_chroot_app_program);
-				if(is_file($jailkit_chroot_app_program) || is_dir($jailkit_chroot_app_program)){			
+				if(is_file($jailkit_chroot_app_program) || is_dir($jailkit_chroot_app_program)){
 					//copy over further programs and its libraries
-					$app->system->create_jailkit_programs($this->data['new']['dir'], $jailkit_chroot_app_program);
-					$this->app->log("Added programs to jailkit chroot", LOGLEVEL_DEBUG);
+					$app->system->create_jailkit_programs($this->data['new']['dir'], $jailkit_chroot_app_program, $opts);
+					$app->log("Added programs to jailkit chroot", LOGLEVEL_DEBUG);
 				}
 			}
 		}
@@ -337,7 +389,7 @@ class shelluser_jailkit_plugin {
 	{
 		global $app;
 
-		//add the user to the chroot
+		// add the user to the chroot
 		$jailkit_chroot_userhome = $this->_get_home_dir($this->data['new']['username']);
 		if(isset($this->data['old']['username'])) {
 			$jailkit_chroot_userhome_old = $this->_get_home_dir($this->data['old']['username']);
@@ -346,7 +398,7 @@ class shelluser_jailkit_plugin {
 		}
 		$jailkit_chroot_puserhome = $this->_get_home_dir($this->data['new']['puser']);
 
-		if(!is_dir($this->data['new']['dir'].'/etc')) mkdir($this->data['new']['dir'].'/etc', 0755);
+		if(!is_dir($this->data['new']['dir'].'/etc')) $app->system->mkdir($this->data['new']['dir'].'/etc', 0755, true);
 		if(!is_file($this->data['new']['dir'].'/etc/passwd')) touch($this->data['new']['dir'].'/etc/passwd', 0755);
 
 		// IMPORTANT!
@@ -357,7 +409,7 @@ class shelluser_jailkit_plugin {
 
 		$shell = '/usr/sbin/jk_chrootsh';
 		if($this->data['new']['active'] != 'y') $shell = '/bin/false';
-		
+
 		$app->system->usermod($this->data['new']['username'], 0, 0, $this->data['new']['dir'].'/.'.$jailkit_chroot_userhome, $shell);
 		$app->system->usermod($this->data['new']['puser'], 0, 0, $this->data['new']['dir'].'/.'.$jailkit_chroot_puserhome, '/usr/sbin/jk_chrootsh');
 
@@ -365,19 +417,19 @@ class shelluser_jailkit_plugin {
 			if(is_dir($this->data['old']['dir'].$jailkit_chroot_userhome_old)) {
 				$app->system->rename($this->data['old']['dir'].$jailkit_chroot_userhome_old,$this->data['new']['dir'].$jailkit_chroot_userhome);
 			} else {
-				mkdir($this->data['new']['dir'].$jailkit_chroot_userhome, 0750, true);
+				$app->system->mkdir($this->data['new']['dir'].$jailkit_chroot_userhome, 0750, true);
 			}
 		}
 		$app->system->chown($this->data['new']['dir'].$jailkit_chroot_userhome, $this->data['new']['username']);
 		$app->system->chgrp($this->data['new']['dir'].$jailkit_chroot_userhome, $this->data['new']['pgroup']);
 
-		$this->app->log("Added created jailkit user home in : ".$this->data['new']['dir'].$jailkit_chroot_userhome, LOGLEVEL_DEBUG);
+		$app->log("Added created jailkit user home in : ".$this->data['new']['dir'].$jailkit_chroot_userhome, LOGLEVEL_DEBUG);
 
 		if(!is_dir($this->data['new']['dir'].$jailkit_chroot_puserhome)) mkdir($this->data['new']['dir'].$jailkit_chroot_puserhome, 0750, true);
 		$app->system->chown($this->data['new']['dir'].$jailkit_chroot_puserhome, $this->data['new']['puser']);
 		$app->system->chgrp($this->data['new']['dir'].$jailkit_chroot_puserhome, $this->data['new']['pgroup']);
 
-		$this->app->log("Added jailkit parent user home in : ".$this->data['new']['dir'].$jailkit_chroot_puserhome, LOGLEVEL_DEBUG);
+		$app->log("Added jailkit parent user home in : ".$this->data['new']['dir'].$jailkit_chroot_puserhome, LOGLEVEL_DEBUG);
 
 
 	}
@@ -406,13 +458,13 @@ class shelluser_jailkit_plugin {
 
 	private function _setup_ssh_rsa() {
 		global $app;
-		$this->app->log("ssh-rsa setup shelluser_jailkit", LOGLEVEL_DEBUG);
+		$app->log("ssh-rsa setup shelluser_jailkit", LOGLEVEL_DEBUG);
 		// Get the client ID, username, and the key
-		$domain_data = $this->app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
-		$sys_group_data = $this->app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
+		$domain_data = $app->db->queryOneRecord('SELECT sys_groupid FROM web_domain WHERE web_domain.domain_id = ?', $this->data['new']['parent_domain_id']);
+		$sys_group_data = $app->db->queryOneRecord('SELECT * FROM sys_group WHERE sys_group.groupid = ?', $domain_data['sys_groupid']);
 		$id = intval($sys_group_data['client_id']);
 		$username= $sys_group_data['name'];
-		$client_data = $this->app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
+		$client_data = $app->db->queryOneRecord('SELECT * FROM client WHERE client.client_id = ?', $id);
 		$userkey = $client_data['ssh_rsa'];
 		unset($domain_data);
 		unset($client_data);
@@ -432,8 +484,8 @@ class shelluser_jailkit_plugin {
 			//Generate ssh-rsa-keys
 			$app->uses('functions');
 			$app->functions->generate_ssh_key($id, $username);
-			
-			$this->app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
+
+			$app->log("ssh-rsa keypair generated for ".$username, LOGLEVEL_DEBUG);
 		};
 
 		if (!file_exists($sshkeys)){
@@ -457,7 +509,7 @@ class shelluser_jailkit_plugin {
 			// add the user's key
 			file_put_contents($sshkeys, $final_keys);
 			$app->file->remove_blank_lines($sshkeys);
-			$this->app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
+			$app->log("ssh-rsa authorisation keyfile created in ".$sshkeys, LOGLEVEL_DEBUG);
 		}
 		//* Get the keys
 		$existing_keys = file($sshkeys, FILE_IGNORE_NEW_LINES);
@@ -492,7 +544,7 @@ class shelluser_jailkit_plugin {
 		// add the custom key
 		$app->system->file_put_contents($sshkeys, $final_keys);
 		$app->file->remove_blank_lines($sshkeys);
-		$this->app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);
+		$app->log("ssh-rsa key updated in ".$sshkeys, LOGLEVEL_DEBUG);
 
 		// set proper file permissions
 		$app->system->exec_safe("chown -R ?:? ?", $this->data['new']['puser'], $this->data['new']['pgroup'], $sshdir);
@@ -500,17 +552,17 @@ class shelluser_jailkit_plugin {
 		$app->system->exec_safe("chmod 600 ?", $sshkeys);
 
 	}
-	
+
 	private function _delete_homedir($homedir,$userid,$parent_domain_id) {
 		global $app, $conf;
-		
+
 		// check if we have to delete the dir
 				$check = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `dir` = ?', $homedir);
-				
+
 				if(!$check && is_dir($homedir)) {
 					$web = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $parent_domain_id);
 					$app->system->web_folder_protection($web['document_root'], false);
-					
+
 					// delete dir
 					if(substr($homedir, -1) !== '/') $homedir .= '/';
 					$files = array('.bash_logout', '.bash_history', '.bashrc', '.profile');
@@ -537,10 +589,43 @@ class shelluser_jailkit_plugin {
 					}
 					unset($files);
 					unset($dirs);
-					
+
 					$app->system->web_folder_protection($web['document_root'], true);
 				}
-	
+
+	}
+
+	private function _delete_jailkit_if_unused($parent_domain_id) {
+		global $app, $conf;
+
+		// get jail directory
+		$parent_domain = $app->db->queryOneRecord("SELECT * FROM `web_domain` WHERE `domain_id` = ? OR `parent_domain_id` = ? AND `document_root` IS NOT NULL", $parent_domain_id, $parent_domain_id);
+		if (!is_dir($parent_domain['document_root'])) {
+			return;
+		}
+
+		// chroot is used by php-fpm
+		if (isset($parent_domain['php_fpm_chroot']) && $parent_domain['php_fpm_chroot'] == 'y') {
+			return;
+		}
+
+		// check for any shell_user using this jail
+		$inuse = $app->db->queryOneRecord('SELECT shell_user_id FROM `shell_user` WHERE `parent_domain_id` = ? AND `chroot` = ?', $parent_domain_id, 'jailkit');
+		if($inuse) {
+			return;
+		}
+
+		// check for any cron job using this jail
+		$inuse = $app->db->queryOneRecord('SELECT id FROM `cron` WHERE `parent_domain_id` = ? AND `type` = ?', $parent_domain_id, 'chrooted');
+		if($inuse) {
+			return;
+		}
+
+		$app->system->delete_jailkit_chroot($parent_domain['document_root']);
+
+		// this gets last_jailkit_update out of sync with master db, but that is ok,
+		// as it is only used as a timestamp to moderate the frequency of updating on the slaves
+		$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW(), `last_jailkit_hash` = NULL WHERE `document_root` = ?", $parent_domain['document_root']);
 	}
 
 } // end class
diff --git a/server/plugins-available/webserver_plugin.inc.php b/server/plugins-available/webserver_plugin.inc.php
index 3dae9216fa9371f9fac93c648441bfeaa11aeda7..0873826bde4de220e63b8533f965a7f08e511efd 100644
--- a/server/plugins-available/webserver_plugin.inc.php
+++ b/server/plugins-available/webserver_plugin.inc.php
@@ -56,6 +56,7 @@ class webserver_plugin {
 		global $app;
 
 		$app->plugins->registerAction('server_plugins_loaded', $this->plugin_name, 'check_phpini_changes');
+		$app->plugins->registerEvent('server_update', $this->plugin_name, 'server_update');
 	}
 
 	/**
@@ -164,6 +165,87 @@ class webserver_plugin {
 		unset($processed);
 	}
 
+
+	/*
+	 * Checks for changes to jailkit settings in server config and schedules affected jails to be updated.
+	 */
+	function server_update($event_name, $data) {
+		global $app, $conf;
+
+		// load the server configuration options
+		$app->uses('ini_parser,system');
+
+		$old = $app->ini_parser->parse_ini_string($data['old']['config']);
+		$new = $app->ini_parser->parse_ini_string($data['new']['config']);
+		if (is_array($old) && is_array($new) && isset($old['jailkit']) && isset($new['jailkit'])) {
+			$old = $old['jailkit'];
+			$new = $new['jailkit'];
+		} else {
+			$app->log('server_update: could not parse jailkit section of server config.', LOGLEVEL_WARN);
+			return;
+		}
+
+		$hardlink_mode_changed = (boolean)(($old['jailkit_hardlinks'] != $new['jailkit_hardlinks']) && $new['jailkit_hardlinks'] != 'allow');
+
+		if (($old['jailkit_chroot_app_sections'] != $new['jailkit_chroot_app_sections']) ||
+		    ($old['jailkit_chroot_app_programs'] != $new['jailkit_chroot_app_programs']) ||
+		    ($old['jailkit_chroot_cron_programs'] != $new['jailkit_chroot_cron_programs']) ||
+		    ($hardlink_mode_changed && $new['jailkit_hardlinks'] != 'allow'))
+		{
+			$app->log('Jailkit config has changed, scheduling affected chroot jails to be updated.', LOGLEVEL_DEBUG);
+
+			$web_domains = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE type = 'vhost' AND server_id = ?", $conf['server_id']);
+
+			foreach ($web_domains as $web) {
+				// we could check (php_fpm_chroot == y || jailkit shell user exists || jailkit cron exists),
+				// but will just shortcut the db checks to see if jailkit was setup previously:
+				if (!is_dir($web['document_root'].'/etc/jailkit')) {
+					continue;
+				}
+
+				if ($hardlink_mode_changed ||
+				    // chroot cron programs changed
+				    ($old['jailkit_chroot_cron_programs'] != $new['jailkit_chroot_cron_programs']) ||
+				    // jailkit sections changed and website does not overwrite
+				    (($old['jailkit_chroot_app_sections'] != $new['jailkit_chroot_app_sections']) &&
+				     (!(isset($web['jailkit_chroot_app_sections']) && $web['jailkit_chroot_app_sections'] != '' ))) ||
+				    // jailkit apps changed and website does not overwrite
+				    (($old['jailkit_chroot_app_programs'] != $new['jailkit_chroot_app_programs']) &&
+				     (!(isset($web['jailkit_chroot_app_programs']) && $web['jailkit_chroot_app_programs'] != '' ))))
+				{
+
+					$sections = $new['jailkit_chroot_app_sections'];
+					if (isset($web['jailkit_chroot_app_sections']) && $web['jailkit_chroot_app_sections'] != '' ) {
+						$sections = $web['jailkit_chroot_app_sections'];
+					}
+
+					$programs = $new['jailkit_chroot_app_programs'];
+					if (isset($web['jailkit_chroot_app_sections']) && $web['jailkit_chroot_app_sections'] != '' ) {
+						$programs = $web['jailkit_chroot_app_sections'];
+					}
+
+					if (isset($new['jailkit_hardlinks'])) {
+						if ($new['jailkit_hardlinks'] == 'yes') {
+							$options = array('hardlink');
+						} elseif ($new['jailkit_hardlinks'] == 'no') {
+							$options = array();
+						}
+					} else {
+						$options = array('allow_hardlink');
+					}
+
+					$options[] = 'force';
+
+					// we could add a server config setting to allow updating these immediately:
+					//   $app->system->update_jailkit_chroot($new['document_root'], $sections, $programs, $options);
+					//
+					// but to mitigate disk contention, will just queue "update needed"
+					// for jailkit maintenance cronjob via last_jailkit_update timestamp
+					$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = FROM_UNIXTIME(0) WHERE `document_root` = ?", $web['document_root']);
+				}
+			}
+		}
+	}
 }
 
 ?>