From ea97ae1a715910acf76c1e86029748b398783120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 001/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- interface/web/dns/form/dns_soa.tform.php | 14 +++++++++++++ interface/web/dns/list/dns_soa.list.php | 20 +++++++++++++++++++ .../web/dns/templates/dns_soa_admin_list.htm | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 6 ++++++ interface/web/dns/templates/dns_soa_list.htm | 2 +- server/plugins-available/bind_plugin.inc.php | 13 +++++++++--- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/interface/web/dns/form/dns_soa.tform.php b/interface/web/dns/form/dns_soa.tform.php index 02afa86c5..bb571e30a 100644 --- a/interface/web/dns/form/dns_soa.tform.php +++ b/interface/web/dns/form/dns_soa.tform.php @@ -80,6 +80,20 @@ $form["tabs"]['dns_soa'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'status' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'PENDING', + 'value' => 'PENDING' + ), + 'status_txt' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '10000' + ), 'origin' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/dns/list/dns_soa.list.php b/interface/web/dns/list/dns_soa.list.php index 2f4233e06..0b76b27fc 100644 --- a/interface/web/dns/list/dns_soa.list.php +++ b/interface/web/dns/list/dns_soa.list.php @@ -61,7 +61,27 @@ $liste["item"][] = array( 'field' => "active", 'width' => "", 'value' => array('Y' => "
".$app->lng('yes_txt')."
", 'N' => "
".$app->lng('no_txt')."
")); + +$liste["item"][] = array( 'field' => "status", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('OK' => '', 'ERROR' => 'background-color:red', 'PENDING' => 'background-color:yellow')); + + +$liste["item"][] = array( 'field' => "status_txt", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ''); + $liste["item"][] = array( 'field' => "server_id", 'datatype' => "VARCHAR", 'formtype' => "SELECT", diff --git a/interface/web/dns/templates/dns_soa_admin_list.htm b/interface/web/dns/templates/dns_soa_admin_list.htm index 0f14534c5..19c074c40 100644 --- a/interface/web/dns/templates/dns_soa_admin_list.htm +++ b/interface/web/dns/templates/dns_soa_admin_list.htm @@ -57,7 +57,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="origin"} diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index 33d429884..120f6f082 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -5,6 +5,11 @@ DNS Zone + +
+
+
+
@@ -127,6 +132,7 @@ +
diff --git a/interface/web/dns/templates/dns_soa_list.htm b/interface/web/dns/templates/dns_soa_list.htm index 516211990..d151d4b89 100644 --- a/interface/web/dns/templates/dns_soa_list.htm +++ b/interface/web/dns/templates/dns_soa_list.htm @@ -55,7 +55,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="origin"} {tmpl_var name="ns"} diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index c538cb957..13557ae1a 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -123,22 +123,28 @@ class bind_plugin { $filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($zone['origin'], 0, -1))); } - file_put_contents($filename, $tpl->grab()); + file_put_contents($filename.'.pending', $tpl->grab()); chown($filename, escapeshellcmd($dns_config['bind_user'])); chgrp($filename, escapeshellcmd($dns_config['bind_group'])); //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); - exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename), $out, $return_status); + $out=array(); + exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + $statustext=''; + foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_DEBUG); } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - rename($filename, $filename.'.err'); + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename.'.err'); } unset($tpl); unset($records); @@ -163,6 +169,7 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); + if(is_file($filename.'.pending')) unlink($filename.'.pending'); } //* Restart bind nameserver if update_acl is not empty, otherwise reload it -- GitLab From ad3fe598beb5cb266ff150464aad20b825608c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 002/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 3 +++ install/sql/ispconfig3.sql | 2 ++ 2 files changed, 5 insertions(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 624d748a5..599c59da5 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -203,3 +203,6 @@ CREATE TABLE `ftp_traffic` ( ALTER TABLE `mail_forwarding` ADD COLUMN `allow_send_as` ENUM('n','y') NOT NULL DEFAULT 'n' AFTER `active`; UPDATE `mail_forwarding` SET `allow_send_as` = 'y' WHERE `type` = 'alias'; + +ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; +ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index f77bbf456..c1bd0caab 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -536,6 +536,8 @@ CREATE TABLE `dns_soa` ( `minimum` int(11) unsigned NOT NULL default '3600', `ttl` int(11) unsigned NOT NULL default '3600', `active` enum('N','Y') NOT NULL DEFAULT 'N', + `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK', + `status_txt` text, `xfer` varchar(255) NOT NULL DEFAULT '', `also_notify` varchar(255) default NULL, `update_acl` varchar(255) default NULL, -- GitLab From de078e69bc255585a0a07dfd2995138f30acfe2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 003/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 13557ae1a..58ab5f07b 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -130,7 +130,7 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); - exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From d459ec8f47c84d7a355bb6f95ded6227c23a709c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 004/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- interface/web/dns/form/dns_soa.tform.php | 14 +++++++++++++ interface/web/dns/list/dns_soa.list.php | 20 +++++++++++++++++++ .../web/dns/templates/dns_soa_admin_list.htm | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 6 ++++++ interface/web/dns/templates/dns_soa_list.htm | 2 +- server/plugins-available/bind_plugin.inc.php | 16 ++++++++++----- 6 files changed, 53 insertions(+), 7 deletions(-) diff --git a/interface/web/dns/form/dns_soa.tform.php b/interface/web/dns/form/dns_soa.tform.php index 05e915740..d76578286 100644 --- a/interface/web/dns/form/dns_soa.tform.php +++ b/interface/web/dns/form/dns_soa.tform.php @@ -80,6 +80,20 @@ $form["tabs"]['dns_soa'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'status' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'PENDING', + 'value' => 'PENDING' + ), + 'status_txt' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '10000' + ), 'origin' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/dns/list/dns_soa.list.php b/interface/web/dns/list/dns_soa.list.php index 2f4233e06..0b76b27fc 100644 --- a/interface/web/dns/list/dns_soa.list.php +++ b/interface/web/dns/list/dns_soa.list.php @@ -61,7 +61,27 @@ $liste["item"][] = array( 'field' => "active", 'width' => "", 'value' => array('Y' => "
".$app->lng('yes_txt')."
", 'N' => "
".$app->lng('no_txt')."
")); + +$liste["item"][] = array( 'field' => "status", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('OK' => '', 'ERROR' => 'background-color:red', 'PENDING' => 'background-color:yellow')); + + +$liste["item"][] = array( 'field' => "status_txt", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ''); + $liste["item"][] = array( 'field' => "server_id", 'datatype' => "VARCHAR", 'formtype' => "SELECT", diff --git a/interface/web/dns/templates/dns_soa_admin_list.htm b/interface/web/dns/templates/dns_soa_admin_list.htm index 0f14534c5..19c074c40 100644 --- a/interface/web/dns/templates/dns_soa_admin_list.htm +++ b/interface/web/dns/templates/dns_soa_admin_list.htm @@ -57,7 +57,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="origin"} diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index be2e7fa83..d18b84018 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -5,6 +5,11 @@ DNS Zone + +
+
+
+
@@ -137,6 +142,7 @@
+
diff --git a/interface/web/dns/templates/dns_soa_list.htm b/interface/web/dns/templates/dns_soa_list.htm index 516211990..d151d4b89 100644 --- a/interface/web/dns/templates/dns_soa_list.htm +++ b/interface/web/dns/templates/dns_soa_list.htm @@ -55,7 +55,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="origin"} {tmpl_var name="ns"} diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index cede1cb82..4abd53b47 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -261,22 +261,28 @@ class bind_plugin { $filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($zone['origin'], 0, -1))); } - file_put_contents($filename, $tpl->grab()); + file_put_contents($filename.'.pending', $tpl->grab()); chown($filename, escapeshellcmd($dns_config['bind_user'])); chgrp($filename, escapeshellcmd($dns_config['bind_group'])); //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); - exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename), $out, $return_status); + $out=array(); + exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + $statustext=''; + foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_DEBUG); } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - rename($filename, $filename.'.err'); + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename.'.err'); } unset($tpl); unset($records); @@ -319,9 +325,9 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); + if(is_file($filename.'.pending')) unlink($filename.'.pending'); if(is_file($filename.'.signed')) unlink($filename.'.signed'); - } - + //* Restart bind nameserver if update_acl is not empty, otherwise reload it if($data['new']['update_acl'] != '') { $app->services->restartServiceDelayed('bind', 'restart'); -- GitLab From 7b7bfa4bcc55fc1be1955ba011a9e51a9db20638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 005/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 2 ++ install/sql/ispconfig3.sql | 2 ++ 2 files changed, 4 insertions(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 2c4300a67..ae2910963 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -226,3 +226,5 @@ ALTER TABLE `web_database` ADD COLUMN `quota_exceeded` enum('n','y') NOT NULL DE ALTER TABLE `client` ADD COLUMN `limit_database_user` int(11) NOT NULL DEFAULT '-1' after limit_database; ALTER TABLE `client_template` ADD COLUMN `limit_database_user` int(11) NOT NULL DEFAULT '-1' after limit_database; +ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; +ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 9d7509506..867be895a 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -542,6 +542,8 @@ CREATE TABLE `dns_soa` ( `minimum` int(11) unsigned NOT NULL default '3600', `ttl` int(11) unsigned NOT NULL default '3600', `active` enum('N','Y') NOT NULL DEFAULT 'N', + `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK', + `status_txt` text, `xfer` varchar(255) NOT NULL DEFAULT '', `also_notify` varchar(255) default NULL, `update_acl` varchar(255) default NULL, -- GitLab From 163ce6dc2237b69c46fe831bf5699ef36401a2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 006/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 4abd53b47..da9071b6c 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -268,7 +268,7 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); - exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From 202920e75836823dce6c39b24e0a24fd14aac514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 8 Apr 2016 10:31:48 +0200 Subject: [PATCH 007/310] bind plugin set to access master db; installer setting rights initially --- install/lib/installer_base.lib.php | 16 ++++++++++++++++ server/plugins-available/bind_plugin.inc.php | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 7621df30d..c38caa02c 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -658,6 +658,22 @@ class installer_base { if(!$this->dbmaster->query($query, $value['db'] . '.mail_backup', $value['user'], $host)) { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } + + $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } + + $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } } } diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index da9071b6c..0c0165e5d 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,7 +273,7 @@ class bind_plugin { foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); - $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { @@ -281,7 +281,7 @@ class bind_plugin { } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename.'.err'); } unset($tpl); -- GitLab From 7e8e7355a45b605fc47a2998f52e783cf482c136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 10:53:43 +0200 Subject: [PATCH 008/310] both dbs to be updated --- server/plugins-available/bind_plugin.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 01d8a5c68..711af3fa2 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,7 +273,8 @@ class bind_plugin { foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); - $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + if ($app->dbmaster) $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { @@ -281,7 +282,8 @@ class bind_plugin { } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + if ($app->dbmaster) $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename.'.err'); } unset($tpl); -- GitLab From 96cbb50c4a5232d3fbc954ae9a190a03e6d98967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 12:31:47 +0200 Subject: [PATCH 009/310] removed db permirrion patch and moved it into dns-dnssec-fix-dbmaster --- install/lib/installer_base.lib.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index c38caa02c..cc7626c36 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -659,21 +659,6 @@ class installer_base { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } - $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; - if ($verbose){ - echo $query ."\n"; - } - if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { - $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); - } - - $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; - if ($verbose){ - echo $query ."\n"; - } - if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { - $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); - } } } -- GitLab From 86a7f8c6dbd073aa87fc68b4b7d1a90387864c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 010/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- interface/web/dns/form/dns_soa.tform.php | 14 +++++++++++++ interface/web/dns/list/dns_soa.list.php | 20 +++++++++++++++++++ .../web/dns/templates/dns_soa_admin_list.htm | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 6 ++++++ interface/web/dns/templates/dns_soa_list.htm | 2 +- server/plugins-available/bind_plugin.inc.php | 17 +++++++++++----- 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/interface/web/dns/form/dns_soa.tform.php b/interface/web/dns/form/dns_soa.tform.php index 05e915740..d76578286 100644 --- a/interface/web/dns/form/dns_soa.tform.php +++ b/interface/web/dns/form/dns_soa.tform.php @@ -80,6 +80,20 @@ $form["tabs"]['dns_soa'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'status' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'PENDING', + 'value' => 'PENDING' + ), + 'status_txt' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '10000' + ), 'origin' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/dns/list/dns_soa.list.php b/interface/web/dns/list/dns_soa.list.php index 2f4233e06..0b76b27fc 100644 --- a/interface/web/dns/list/dns_soa.list.php +++ b/interface/web/dns/list/dns_soa.list.php @@ -61,7 +61,27 @@ $liste["item"][] = array( 'field' => "active", 'width' => "", 'value' => array('Y' => "
".$app->lng('yes_txt')."
", 'N' => "
".$app->lng('no_txt')."
")); + +$liste["item"][] = array( 'field' => "status", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('OK' => '', 'ERROR' => 'background-color:red', 'PENDING' => 'background-color:yellow')); + + +$liste["item"][] = array( 'field' => "status_txt", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ''); + $liste["item"][] = array( 'field' => "server_id", 'datatype' => "VARCHAR", 'formtype' => "SELECT", diff --git a/interface/web/dns/templates/dns_soa_admin_list.htm b/interface/web/dns/templates/dns_soa_admin_list.htm index 0f14534c5..19c074c40 100644 --- a/interface/web/dns/templates/dns_soa_admin_list.htm +++ b/interface/web/dns/templates/dns_soa_admin_list.htm @@ -57,7 +57,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="origin"} diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index be2e7fa83..d18b84018 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -5,6 +5,11 @@ DNS Zone + +
+
+
+
@@ -137,6 +142,7 @@
+
diff --git a/interface/web/dns/templates/dns_soa_list.htm b/interface/web/dns/templates/dns_soa_list.htm index 516211990..d151d4b89 100644 --- a/interface/web/dns/templates/dns_soa_list.htm +++ b/interface/web/dns/templates/dns_soa_list.htm @@ -55,7 +55,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="origin"} {tmpl_var name="ns"} diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index cede1cb82..e9852a8e1 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -261,22 +261,28 @@ class bind_plugin { $filename = escapeshellcmd($dns_config['bind_zonefiles_dir'].'/pri.'.str_replace("/", "_", substr($zone['origin'], 0, -1))); } - file_put_contents($filename, $tpl->grab()); + file_put_contents($filename.'.pending', $tpl->grab()); chown($filename, escapeshellcmd($dns_config['bind_user'])); chgrp($filename, escapeshellcmd($dns_config['bind_group'])); //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); - exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename), $out, $return_status); + $out=array(); + exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + $statustext=''; + foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_DEBUG); } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - rename($filename, $filename.'.err'); + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename.'.err'); } unset($tpl); unset($records); @@ -320,8 +326,9 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); if(is_file($filename.'.signed')) unlink($filename.'.signed'); - } - + if(is_file($filename.'.pending')) unlink($filename.'.pending'); + } + //* Restart bind nameserver if update_acl is not empty, otherwise reload it if($data['new']['update_acl'] != '') { $app->services->restartServiceDelayed('bind', 'restart'); -- GitLab From a8488777be8801656cfc540f5357cac19c8aae44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 011/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 4 +++- install/sql/ispconfig3.sql | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 4f67ccc0d..80e061586 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -249,4 +249,6 @@ UPDATE `sys_session` SET `last_updated` = NULL WHERE `last_updated` = '0000-00-0 UPDATE `web_domain` SET `added_date` = NULL WHERE `added_date` = '0000-00-00'; UPDATE `web_traffic` SET `traffic_date` = NULL WHERE `traffic_date` = '0000-00-00'; - +-- DNS-Status (2 lines) +ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; +ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 17b08b628..ccfa4da8e 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -542,6 +542,8 @@ CREATE TABLE `dns_soa` ( `minimum` int(11) unsigned NOT NULL default '3600', `ttl` int(11) unsigned NOT NULL default '3600', `active` enum('N','Y') NOT NULL DEFAULT 'N', + `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK', + `status_txt` text, `xfer` varchar(255) NOT NULL DEFAULT '', `also_notify` varchar(255) default NULL, `update_acl` varchar(255) default NULL, -- GitLab From 05c924ea11197e00c3a831bb8f9a17324ad6ae08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 012/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index e9852a8e1..dec9f9d85 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -268,7 +268,7 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); - exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From 8cde6289b9fd65fa4cfdd515a03d028ab63d0f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 013/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- server/plugins-available/bind_plugin.inc.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index dec9f9d85..e5f407211 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -268,7 +268,11 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); +<<<<<<< HEAD exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); +======= + exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); +>>>>>>> Zone-Checking improved $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { @@ -325,8 +329,8 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); - if(is_file($filename.'.signed')) unlink($filename.'.signed'); if(is_file($filename.'.pending')) unlink($filename.'.pending'); + if(is_file($filename.'.signed')) unlink($filename.'.signed'); } //* Restart bind nameserver if update_acl is not empty, otherwise reload it -- GitLab From 3a203e1f3bd7bc53345256b19803d64021354fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 014/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 80e061586..0dd25a2a1 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -252,3 +252,4 @@ UPDATE `web_traffic` SET `traffic_date` = NULL WHERE `traffic_date` = '0000-00-0 -- DNS-Status (2 lines) ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; + -- GitLab From 2f47487017ffab6e4d81d1fd234c8714aa16de22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 015/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index e5f407211..c7efac708 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -268,11 +268,7 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); -<<<<<<< HEAD exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); -======= - exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); ->>>>>>> Zone-Checking improved $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From 8739ef8cbee67f0f7075c3da9ccff9d041c8fff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 8 Apr 2016 10:31:48 +0200 Subject: [PATCH 016/310] bind plugin set to access master db; installer setting rights initially --- install/lib/installer_base.lib.php | 16 ++++++++++++++++ server/plugins-available/bind_plugin.inc.php | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 7621df30d..c38caa02c 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -658,6 +658,22 @@ class installer_base { if(!$this->dbmaster->query($query, $value['db'] . '.mail_backup', $value['user'], $host)) { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } + + $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } + + $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } } } diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index c7efac708..01d8a5c68 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,7 +273,7 @@ class bind_plugin { foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); - $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { @@ -281,7 +281,7 @@ class bind_plugin { } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename.'.err'); } unset($tpl); -- GitLab From 7b3806ec9884b9fab692c2ef6f62640a567f8f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 10:53:43 +0200 Subject: [PATCH 017/310] both dbs to be updated --- server/plugins-available/bind_plugin.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 01d8a5c68..711af3fa2 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,7 +273,8 @@ class bind_plugin { foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); - $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + if ($app->dbmaster) $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename); } else { if($dns_config['disable_bind_log'] === 'y') { @@ -281,7 +282,8 @@ class bind_plugin { } else { $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), LOGLEVEL_WARN); } - $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + if ($app->dbmaster) $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); rename($filename.'.pending', $filename.'.err'); } unset($tpl); -- GitLab From 37e4127afa37e1242b011e01facf4ada50b66aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 12:31:47 +0200 Subject: [PATCH 018/310] removed db permirrion patch and moved it into dns-dnssec-fix-dbmaster --- install/lib/installer_base.lib.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index c38caa02c..cc7626c36 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -659,21 +659,6 @@ class installer_base { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } - $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; - if ($verbose){ - echo $query ."\n"; - } - if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { - $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); - } - - $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; - if ($verbose){ - echo $query ."\n"; - } - if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { - $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); - } } } -- GitLab From 0ea967089ad30dcd582a9aa7a783e65ad62b2e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Tue, 12 Apr 2016 11:07:44 +0200 Subject: [PATCH 019/310] db permissions --- install/lib/installer_base.lib.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index cc7626c36..9a876b45f 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -659,6 +659,14 @@ class installer_base { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } + $query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`, `status`, `status_txt`) ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } + } } -- GitLab From fa78df2fb280226e211218bdd15dda230212ec9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 020/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- interface/web/dns/form/dns_soa.tform.php | 14 +++++++++++++ interface/web/dns/list/dns_soa.list.php | 20 +++++++++++++++++++ .../web/dns/templates/dns_soa_admin_list.htm | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 6 ++++++ interface/web/dns/templates/dns_soa_list.htm | 2 +- server/plugins-available/bind_plugin.inc.php | 12 ++++++++--- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/interface/web/dns/form/dns_soa.tform.php b/interface/web/dns/form/dns_soa.tform.php index d76c40344..a39f48c17 100644 --- a/interface/web/dns/form/dns_soa.tform.php +++ b/interface/web/dns/form/dns_soa.tform.php @@ -80,6 +80,20 @@ $form["tabs"]['dns_soa'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'status' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'PENDING', + 'value' => 'PENDING' + ), + 'status_txt' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXTAREA', + 'default' => '', + 'value' => '', + 'width' => '30', + 'maxlength' => '10000' + ), 'origin' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/dns/list/dns_soa.list.php b/interface/web/dns/list/dns_soa.list.php index 2f4233e06..0b76b27fc 100644 --- a/interface/web/dns/list/dns_soa.list.php +++ b/interface/web/dns/list/dns_soa.list.php @@ -61,7 +61,27 @@ $liste["item"][] = array( 'field' => "active", 'width' => "", 'value' => array('Y' => "
".$app->lng('yes_txt')."
", 'N' => "
".$app->lng('no_txt')."
")); + +$liste["item"][] = array( 'field' => "status", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('OK' => '', 'ERROR' => 'background-color:red', 'PENDING' => 'background-color:yellow')); + + +$liste["item"][] = array( 'field' => "status_txt", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ''); + $liste["item"][] = array( 'field' => "server_id", 'datatype' => "VARCHAR", 'formtype' => "SELECT", diff --git a/interface/web/dns/templates/dns_soa_admin_list.htm b/interface/web/dns/templates/dns_soa_admin_list.htm index fbdc0398e..6315223a0 100644 --- a/interface/web/dns/templates/dns_soa_admin_list.htm +++ b/interface/web/dns/templates/dns_soa_admin_list.htm @@ -57,7 +57,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="origin"} diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index 87853d1ed..150007fa5 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -11,6 +11,11 @@ DNS Zone + +
+
+
+
@@ -145,6 +150,7 @@ +
diff --git a/interface/web/dns/templates/dns_soa_list.htm b/interface/web/dns/templates/dns_soa_list.htm index 22cd19484..eb2258df4 100644 --- a/interface/web/dns/templates/dns_soa_list.htm +++ b/interface/web/dns/templates/dns_soa_list.htm @@ -55,7 +55,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="origin"} {tmpl_var name="ns"} diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 80d302bee..80fcb640b 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -272,9 +272,13 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); - exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename), $out, $return_status); + $out=array(); + exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename).' 2>&1', $out, $return_status); + $statustext=''; + foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); + $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); } else { $loglevel = @($dns_config['disable_bind_log'] === 'y')?'LOGLEVEL_DEBUG':'LOGLEVEL_WARN'; $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel); @@ -290,6 +294,7 @@ class bind_plugin { } else { rename($filename, $filename.'.err'); } + $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); } unset($tpl); unset($records); @@ -333,8 +338,9 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); if(is_file($filename.'.signed')) unlink($filename.'.signed'); - } - + if(is_file($filename.'.pending')) unlink($filename.'.pending'); + } + //* Restart bind nameserver if update_acl is not empty, otherwise reload it if($data['new']['update_acl'] != '') { $app->services->restartServiceDelayed('bind', 'restart'); -- GitLab From 7568eaf4e41da1cd13796d40ff2150755afad288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 021/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 2 ++ install/sql/ispconfig3.sql | 2 ++ 2 files changed, 4 insertions(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 0de0a980a..b2090a4db 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -12,3 +12,5 @@ ALTER TABLE `mail_mailinglist` ADD `posting_policy` enum('closed','moderated','f ALTER TABLE `web_domain` CHANGE `folder_directive_snippets` `folder_directive_snippets` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL; ALTER TABLE `sys_user` ADD `last_login_ip` VARCHAR(50) NULL AFTER `lost_password_reqtime`; ALTER TABLE `sys_user` ADD `last_login_at` BIGINT(20) NULL AFTER `last_login_ip`; +ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; +ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 6de0ce049..c3e2b9b11 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -547,6 +547,8 @@ CREATE TABLE `dns_soa` ( `minimum` int(11) unsigned NOT NULL default '3600', `ttl` int(11) unsigned NOT NULL default '3600', `active` enum('N','Y') NOT NULL DEFAULT 'N', + `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK', + `status_txt` text, `xfer` varchar(255) NOT NULL DEFAULT '', `also_notify` varchar(255) default NULL, `update_acl` varchar(255) default NULL, -- GitLab From 4930e96d181fdf3a5f3e221b8b5499d0f8409b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 022/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 80fcb640b..45d8ee449 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,7 +273,8 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); - exec('/usr/sbin/named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename).' 2>&1', $out, $return_status); + exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From dc3c29e7d2429045cf521dbc53a6908cde49f99d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 023/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- server/plugins-available/bind_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 45d8ee449..f908814dd 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -338,8 +338,8 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); - if(is_file($filename.'.signed')) unlink($filename.'.signed'); if(is_file($filename.'.pending')) unlink($filename.'.pending'); + if(is_file($filename.'.signed')) unlink($filename.'.signed'); } //* Restart bind nameserver if update_acl is not empty, otherwise reload it -- GitLab From e3126af8922189185261271948d5f9e5899980be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 024/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index b2090a4db..6a02b31bd 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -14,3 +14,4 @@ ALTER TABLE `sys_user` ADD `last_login_ip` VARCHAR(50) NULL AFTER `lost_password ALTER TABLE `sys_user` ADD `last_login_at` BIGINT(20) NULL AFTER `last_login_ip`; ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; + -- GitLab From 3ecc352745f8b3e4bb28fb23521d8a777fc1549d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 025/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index f908814dd..60d5ea7b4 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -274,7 +274,6 @@ class bind_plugin { if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); - $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From f3e314ae6a3519f3746e1ed25c76850426488d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 8 Apr 2016 10:31:48 +0200 Subject: [PATCH 026/310] bind plugin set to access master db; installer setting rights initially --- install/lib/installer_base.lib.php | 9 ++++++++- server/plugins-available/bind_plugin.inc.php | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 5226394f3..136827dfe 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -667,7 +667,7 @@ class installer_base { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } - $query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`) ON ?? TO ?@?"; + $query = "GRANT SELECT, UPDATE(`dnssec_initialized`, `dnssec_info`, `dnssec_last_signed`, `status`, `status_txt`) ON ?? TO ?@?"; if ($verbose){ echo $query ."\n"; } @@ -675,6 +675,13 @@ class installer_base { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } + $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; + if ($verbose){ + echo $query ."\n"; + } + if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { + $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); + } } } diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 60d5ea7b4..0e727fe13 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -279,6 +279,7 @@ class bind_plugin { if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); } else { $loglevel = @($dns_config['disable_bind_log'] === 'y')?'LOGLEVEL_DEBUG':'LOGLEVEL_WARN'; $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel); @@ -295,6 +296,8 @@ class bind_plugin { rename($filename, $filename.'.err'); } $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); + rename($filename.'.pending', $filename.'.err'); } unset($tpl); unset($records); -- GitLab From cff5e787a0f5ec62c1a536d04134850275a4ceb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 10:53:43 +0200 Subject: [PATCH 027/310] both dbs to be updated --- server/plugins-available/bind_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 0e727fe13..53970f696 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -280,6 +280,7 @@ class bind_plugin { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); + } else { $loglevel = @($dns_config['disable_bind_log'] === 'y')?'LOGLEVEL_DEBUG':'LOGLEVEL_WARN'; $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel); @@ -297,7 +298,6 @@ class bind_plugin { } $app->db->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); $app->dbmaster->query('UPDATE dns_soa SET status=\'ERROR\', status_txt=\''.str_replace(array('"', '\''), '', $statustext).'\' WHERE id='.$data['new']['id']); - rename($filename.'.pending', $filename.'.err'); } unset($tpl); unset($records); -- GitLab From dd1d83c9c343980f2835fcac8d704e7940d8c8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Mon, 11 Apr 2016 12:31:47 +0200 Subject: [PATCH 028/310] removed db permirrion patch and moved it into dns-dnssec-fix-dbmaster --- install/lib/installer_base.lib.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 136827dfe..0cfb2ff4e 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -674,14 +674,7 @@ class installer_base { if(!$this->dbmaster->query($query, $value['db'] . '.dns_soa', $value['user'], $host)) { $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); } - - $query = "GRANT SELECT, UPDATE ON ?? TO ?@?"; - if ($verbose){ - echo $query ."\n"; - } - if(!$this->dbmaster->query($query, $value['db'] . '.dns_rr', $value['user'], $host)) { - $this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage); - } + } } -- GitLab From 3e2544defd735017cc9abcd5dae700a169d16585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 029/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- server/plugins-available/bind_plugin.inc.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 53970f696..75fe44d38 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -273,14 +273,13 @@ class bind_plugin { //* Check the zonefile if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); - exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename.'.pending').' 2>&1', $out, $return_status); + exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename).' 2>&1', $out, $return_status); $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { $app->log("Writing BIND domain file: ".$filename, LOGLEVEL_DEBUG); $app->db->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); $app->dbmaster->query('UPDATE dns_soa SET status=\'OK\', status_txt=\'\' WHERE id='.$data['new']['id']); - } else { $loglevel = @($dns_config['disable_bind_log'] === 'y')?'LOGLEVEL_DEBUG':'LOGLEVEL_WARN'; $app->log("Writing BIND domain file failed: ".$filename." ".implode(' ', $out), $loglevel); @@ -340,7 +339,6 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); - if(is_file($filename.'.pending')) unlink($filename.'.pending'); if(is_file($filename.'.signed')) unlink($filename.'.signed'); } -- GitLab From 1ec7cda79f5d61df91f4a0f39fe32312a42b82b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 030/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 6a02b31bd..b2090a4db 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -14,4 +14,3 @@ ALTER TABLE `sys_user` ADD `last_login_ip` VARCHAR(50) NULL AFTER `lost_password ALTER TABLE `sys_user` ADD `last_login_at` BIGINT(20) NULL AFTER `last_login_ip`; ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; - -- GitLab From 3a3e2fc6d8c644d73883dd2754dc543dd1971b3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 031/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 75fe44d38..0472a7e96 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -274,6 +274,7 @@ class bind_plugin { if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename).' 2>&1', $out, $return_status); + $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From ad9183ff120d8b75b1894fab536cca93366fd3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:08:07 +0100 Subject: [PATCH 032/310] Zone-Checking improved Implements a colored background if bind fails to load the zone due to errors Implements a status text if errors occured Implements not removing a zone if errors occur. instead old zone stays loaded --- server/plugins-available/bind_plugin.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 0472a7e96..75fe44d38 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -274,7 +274,6 @@ class bind_plugin { if(is_file($filename.'.err')) unlink($filename.'.err'); $out=array(); exec('named-checkzone '.escapeshellarg($zone['origin']).' '.escapeshellarg($filename).' 2>&1', $out, $return_status); - $statustext=''; foreach ($out as $line) $statustext .= $line."\n"; if($return_status === 0) { -- GitLab From 74a2d62eb522e090b9ce09a27f4615034d9b000a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Fri, 22 Jan 2016 17:14:53 +0100 Subject: [PATCH 033/310] added sql changes --- install/sql/incremental/upd_dev_collection.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index b2090a4db..6a02b31bd 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -14,3 +14,4 @@ ALTER TABLE `sys_user` ADD `last_login_ip` VARCHAR(50) NULL AFTER `lost_password ALTER TABLE `sys_user` ADD `last_login_at` BIGINT(20) NULL AFTER `last_login_ip`; ALTER TABLE `dns_soa` ADD COLUMN `status` enum('OK','ERROR','PENDING') NOT NULL DEFAULT 'OK' AFTER `active`; ALTER TABLE `dns_soa` ADD COLUMN `status_txt` text AFTER `status`; + -- GitLab From 1f3370de07b035ec28a2784fbb612ab976ce72cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Sat, 23 Jan 2016 23:15:02 +0100 Subject: [PATCH 034/310] absolute path -> relative path --- server/plugins-available/bind_plugin.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index 75fe44d38..faadc7f2c 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -591,4 +591,5 @@ class bind_plugin { } // end class + ?> -- GitLab From 4fb99c9c04b51b07a228cff30fb477f21f18cc39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Thu, 29 Dec 2016 15:51:37 +0100 Subject: [PATCH 035/310] fixed status into new design, fixed status message --- interface/web/dns/list/dns_soa.list.php | 2 +- interface/web/dns/templates/dns_soa_admin_list.htm | 2 +- interface/web/dns/templates/dns_soa_list.htm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/web/dns/list/dns_soa.list.php b/interface/web/dns/list/dns_soa.list.php index 0b76b27fc..dba460b91 100644 --- a/interface/web/dns/list/dns_soa.list.php +++ b/interface/web/dns/list/dns_soa.list.php @@ -74,7 +74,7 @@ $liste["item"][] = array( 'field' => "status", $liste["item"][] = array( 'field' => "status_txt", 'datatype' => "VARCHAR", - 'formtype' => "SELECT", + 'formtype' => "TEXT", 'op' => "=", 'prefix' => "", 'suffix' => "", diff --git a/interface/web/dns/templates/dns_soa_admin_list.htm b/interface/web/dns/templates/dns_soa_admin_list.htm index 6315223a0..08a4b0438 100644 --- a/interface/web/dns/templates/dns_soa_admin_list.htm +++ b/interface/web/dns/templates/dns_soa_admin_list.htm @@ -57,7 +57,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name='status_txt'} {tmpl_var name="sys_groupid"} {tmpl_var name="server_id"} {tmpl_var name="origin"} diff --git a/interface/web/dns/templates/dns_soa_list.htm b/interface/web/dns/templates/dns_soa_list.htm index eb2258df4..27e07afd2 100644 --- a/interface/web/dns/templates/dns_soa_list.htm +++ b/interface/web/dns/templates/dns_soa_list.htm @@ -55,7 +55,7 @@ - {tmpl_var name="active"} + {tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="origin"} {tmpl_var name="ns"} -- GitLab From 0c811fda1a978835448238d2c0570354f209e48a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?A=2E=20T=C3=A4ffner?= Date: Thu, 29 Dec 2016 16:04:50 +0100 Subject: [PATCH 036/310] ooops... Missed that while updating my MR to current implementetion (you guys actually somehow reinvented the wheel :laughing: ) --- server/plugins-available/bind_plugin.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/server/plugins-available/bind_plugin.inc.php b/server/plugins-available/bind_plugin.inc.php index b1c747501..faadc7f2c 100644 --- a/server/plugins-available/bind_plugin.inc.php +++ b/server/plugins-available/bind_plugin.inc.php @@ -339,7 +339,6 @@ class bind_plugin { if(is_file($filename)) unlink($filename); if(is_file($filename.'.err')) unlink($filename.'.err'); - if(is_file($filename.'.pending')) unlink($filename.'.pending'); if(is_file($filename.'.signed')) unlink($filename.'.signed'); } -- GitLab From 42cfa6e71cd5034e3b4acc52652d382a1341d85b Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 29 Dec 2017 11:10:13 +0100 Subject: [PATCH 037/310] Added internal htmlentities function with array support and ENT_QUOTES. --- interface/lib/classes/functions.inc.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index da35a3700..136448eef 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -454,6 +454,25 @@ class functions { $app->log("Failed to create SSH keypair for ".$username, LOGLEVEL_WARN); } } + + public function htmlentities($value) { + global $conf; + + if(is_array($value)) { + $out = array(); + foreach($values as $key => $val) { + if(is_array($val)) { + $out[$key] = $this->htmlentities($val); + } else { + $out[$key] = htmlentities($val, ENT_QUOTES, $conf["html_content_encoding"]); + } + } + } else { + $out = htmlentities($value, ENT_QUOTES, $conf["html_content_encoding"]); + } + + return $out; + } } ?> -- GitLab From 1e232fffbffbfc012c68df715bfbb782f54fe9ce Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 29 Dec 2017 12:03:30 +0100 Subject: [PATCH 038/310] Fixed #4893 Stored XSS issue in email name field --- interface/lib/classes/listform.inc.php | 14 +++----------- interface/lib/classes/quota_lib.inc.php | 3 ++- interface/lib/classes/tform_base.inc.php | 18 +++++++++++++----- interface/web/mail/form/mail_user.tform.php | 6 ++++++ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php index 4999f7e54..15a1a53ad 100644 --- a/interface/lib/classes/listform.inc.php +++ b/interface/lib/classes/listform.inc.php @@ -179,6 +179,7 @@ class listform { && $k == $_SESSION['search'][$list_name][$search_prefix.$field] && $_SESSION['search'][$list_name][$search_prefix.$field] != '') ? ' SELECTED' : ''; + $v = $app->functions->htmlentities($v); $out .= "\r\n"; } } @@ -610,17 +611,8 @@ class listform { } function escapeArrayValues($search_values) { - global $conf; - - $out = array(); - if(is_array($search_values)) { - foreach($search_values as $key => $val) { - $out[$key] = htmlentities($val, ENT_QUOTES, $conf["html_content_encoding"]); - } - } - - return $out; - + global $app; + return $app->functions->htmlentities($search_values); } } diff --git a/interface/lib/classes/quota_lib.inc.php b/interface/lib/classes/quota_lib.inc.php index 93d8baa5d..e5d55ff80 100644 --- a/interface/lib/classes/quota_lib.inc.php +++ b/interface/lib/classes/quota_lib.inc.php @@ -243,7 +243,8 @@ class quota_lib { if(is_array($emails) && !empty($emails)){ for($i=0;$ifunctions->htmlentities($emails[$i]['name']); $emails[$i]['used'] = isset($monitor_data[$email]['used']) ? $monitor_data[$email]['used'] : array(1 => 0); if (!is_numeric($emails[$i]['used'])) $emails[$i]['used']=$emails[$i]['used'][1]; diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php index c60321bd8..06c016f25 100644 --- a/interface/lib/classes/tform_base.inc.php +++ b/interface/lib/classes/tform_base.inc.php @@ -475,6 +475,7 @@ class tform_base { $selected = ($k == $val)?' SELECTED':''; if(isset($this->wordbook[$v])) $v = $this->wordbook[$v]; + $v = $app->functions->htmlentities($v); $out .= "\r\n"; } } @@ -494,7 +495,7 @@ class tform_base { foreach($vals as $tvl) { if(trim($tvl) == trim($k)) $selected = ' SELECTED'; } - + $v = $app->functions->htmlentities($v); $out .= "\r\n"; } } @@ -577,7 +578,7 @@ class tform_base { default: if(isset($record[$key])) { - $new_record[$key] = htmlspecialchars($record[$key]); + $new_record[$key] = $app->functions->htmlentities($record[$key]); } else { $new_record[$key] = ''; } @@ -608,7 +609,8 @@ class tform_base { $out = ''; foreach($field['value'] as $k => $v) { $selected = ($k == $field["default"])?' SELECTED':''; - $out .= "\r\n"; + $v = $app->functions->htmlentities($this->lng($v)); + $out .= "\r\n"; } } if(isset($out)) $new_record[$key] = $out; @@ -622,7 +624,7 @@ class tform_base { // HTML schreiben $out = ''; foreach($field['value'] as $k => $v) { - + $v = $app->functions->htmlentities($v); $out .= "\r\n"; } } @@ -693,7 +695,7 @@ class tform_base { break; default: - $new_record[$key] = htmlspecialchars($field['default']); + $new_record[$key] = $app->functions->htmlentities($field['default']); } } @@ -911,6 +913,12 @@ class tform_base { case 'NOWHITESPACE': $returnval = preg_replace('/\s+/', '', $returnval); break; + case 'STRIPTAGS': + $returnval = strip_tags(preg_replace('/]*>/is', '', $returnval)); + break; + case 'STRIPNL': + $returnval = str_replace(array("\n","\r"),'', $returnval); + break; default: $this->errorMessage .= "Unknown Filter: ".$filter['type']; break; diff --git a/interface/web/mail/form/mail_user.tform.php b/interface/web/mail/form/mail_user.tform.php index 7ba568882..3d2b66daa 100644 --- a/interface/web/mail/form/mail_user.tform.php +++ b/interface/web/mail/form/mail_user.tform.php @@ -144,6 +144,12 @@ $form["tabs"]['mailuser'] = array( 'name' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', + 'filters' => array( + 0 => array( 'event' => 'SAVE', + 'type' => 'STRIPTAGS'), + 1 => array( 'event' => 'SAVE', + 'type' => 'STRIPNL') + ), 'default' => '', 'value' => '', 'width' => '30', -- GitLab From bdac538e96f7e50b88e63f9915332b44eb95c32f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 25 May 2018 12:00:51 +0200 Subject: [PATCH 039/310] - fixed html typo --- interface/web/dns/templates/dns_dmarc_edit.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/dns/templates/dns_dmarc_edit.htm b/interface/web/dns/templates/dns_dmarc_edit.htm index 178ec815e..630c18559 100644 --- a/interface/web/dns/templates/dns_dmarc_edit.htm +++ b/interface/web/dns/templates/dns_dmarc_edit.htm @@ -147,7 +147,7 @@
- +
-- GitLab From b5375ab34471bbba3ad6534e607a8b8e365c1471 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 25 May 2018 17:02:03 +0200 Subject: [PATCH 040/310] Patch file to fix amavisd-neew on Ubuntu 18.04 temporarily. --- helper_scripts/ubuntu-amavisd-new-2.11.patch | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 helper_scripts/ubuntu-amavisd-new-2.11.patch diff --git a/helper_scripts/ubuntu-amavisd-new-2.11.patch b/helper_scripts/ubuntu-amavisd-new-2.11.patch new file mode 100644 index 000000000..ac0ecb2dc --- /dev/null +++ b/helper_scripts/ubuntu-amavisd-new-2.11.patch @@ -0,0 +1,18 @@ +--- amavisd-new.orig 2017-11-16 11:51:19.000000000 +0100 ++++ amavisd-new 2018-05-25 16:53:45.623398108 +0200 +@@ -22829,6 +22829,7 @@ + } + # load policy banks from the 'client_ipaddr_policy' lookup + Amavis::load_policy_bank($_,$msginfo) for @bank_names_cl; ++ $msginfo->originating(c('originating')); + + $msginfo->client_addr($cl_ip); # ADDR + $msginfo->client_port($cl_port); # PORT +@@ -34361,6 +34362,7 @@ + $sig_ind++; + } + Amavis::load_policy_bank($_,$msginfo) for @bank_names; ++ $msginfo->originating(c('originating')); + $msginfo->dkim_signatures_valid(\@signatures_valid) if @signatures_valid; + # if (ll(5) && $sig_ind > 0) { + # # show which header fields are covered by which signature -- GitLab From ed46ade140dca708e597634fb6e6324f1e7ddf92 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sat, 26 May 2018 03:37:02 +0200 Subject: [PATCH 041/310] Update ispconfig.css to fix #select_server a that is affected by #sidebar a padding of 10px. Already pr'ed and merged in master via https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/766. Perhaps can be merged with stable too? --- interface/web/themes/default/assets/stylesheets/ispconfig.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css index aeb6f9ecd..d432c7c59 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.css +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css @@ -165,6 +165,9 @@ body { #sidebar header a { padding: 0; } +#select_server a { + padding:0 10px; } + .page-header { margin: 20px 0; padding: 0; } -- GitLab From e3a1292ead0fae92635f14b7d3bf00a29121766e Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sat, 26 May 2018 03:43:38 +0200 Subject: [PATCH 042/310] Update letsencrypt.inc.php as per the discussion at https://git.ispconfig.org/ispconfig/ispconfig3/issues/5030. Already pr'ed and merged in master via https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/778. Perhaps can be merged with stable too? --- server/lib/classes/letsencrypt.inc.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index 12e43a9d5..4f681cc48 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -275,7 +275,16 @@ class letsencrypt { $letsencrypt = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); $letsencrypt = reset($letsencrypt); if(is_executable($letsencrypt)) { - $letsencrypt_cmd = $letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server https://acme-v01.api.letsencrypt.org/directory --rsa-key-size 4096 --email postmaster@$domain $cli_domain_arg --webroot-path /usr/local/ispconfig/interface/acme"; + $letsencrypt_version = exec($letsencrypt . ' --version 2>&1', $ret, $val); + if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $letsencrypt_version, $matches)) { + $letsencrypt_version = $matches[2]; + } + if ($letsencrypt_version >=0.22) { + $acme_version = 'https://acme-v02.api.letsencrypt.org/directory'; + } else { + $acme_version = 'https://acme-v01.api.letsencrypt.org/directory'; + } + $letsencrypt_cmd = $letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server $acme_version --rsa-key-size 4096 --email postmaster@$domain $cli_domain_arg --webroot-path /usr/local/ispconfig/interface/acme"; $success = $app->system->_exec($letsencrypt_cmd); } } else { -- GitLab From a25fa66c1b97217940863317cce5d41d5568fdc4 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 11 Jun 2018 17:12:39 +0200 Subject: [PATCH 043/310] Added remote functions config_value_get, config_value_add, config_value_update, config_value_replace and config_value_delete to access the sys_config key / value store in ISPConfig from remote api. --- interface/lib/classes/remote.d/admin.inc.php | 116 +++++++++++++++++++ interface/web/admin/lib/remote.conf.php | 2 +- 2 files changed, 117 insertions(+), 1 deletion(-) diff --git a/interface/lib/classes/remote.d/admin.inc.php b/interface/lib/classes/remote.d/admin.inc.php index 347f8520b..8b0c4730e 100644 --- a/interface/lib/classes/remote.d/admin.inc.php +++ b/interface/lib/classes/remote.d/admin.inc.php @@ -156,6 +156,122 @@ class remoting_admin extends remoting { return false; } } + + // config_value_* functions --------------------------------------------------------------------------------------- + + //* Get config_value details + public function config_value_get($session_id, $group, $name) + { + global $app; + + if(!$this->checkPerm($session_id, 'config_value_get')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + // validate fields + if($group == '' || $name == '') { + throw new SoapFault('field_empty_error', 'Group and name parameter may not be empty.'); + return false; + } + + return $app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name); + } + + //* Add a config_value record + public function config_value_add($session_id, $group, $name, $value) + { + global $app; + + if(!$this->checkPerm($session_id, 'config_value_add')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + // validate fields + if($group == '' || $name == '' || $value == '') { + throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + return false; + } + + if(is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { + throw new SoapFault('record_unique_error', 'Group plus name field combination is not unique.'); + return false; + } + + return $app->db->query('INSERT INTO sys_config (`group`,`name`,`value`) VALUES (?,?,?)',$group,$name,$value); + } + + //* Update config_value record + public function config_value_update($session_id, $group, $name, $value) + { + global $app; + + if(!$this->checkPerm($session_id, 'config_value_update')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + // validate fields + if($group == '' || $name == '' || $value == '') { + throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + return false; + } + + if(!is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { + throw new SoapFault('record_nonexist_error', 'There is no record with this group plus name field combination.'); + return false; + } + + return $app->db->query('UPDATE sys_config SET `value` = ? WHERE `group` = ? AND `name` = ?',$value,$group,$name); + } + + //* Replace config_value record + public function config_value_replace($session_id, $group, $name, $value) + { + global $app; + + if(!$this->checkPerm($session_id, 'config_value_replace')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + // validate fields + if($group == '' || $name == '' || $value == '') { + throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + return false; + } + + if(is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { + return $app->db->query('UPDATE sys_config SET `value` = ? WHERE `group` = ? AND `name` = ?',$value,$group,$name); + } else { + return $app->db->query('INSERT INTO sys_config (`group`,`name`,`value`) VALUES (?,?,?)',$group,$name,$value); + } + } + + //* Delete config_value record + public function config_value_delete($session_id, $group, $name) + { + global $app; + + if(!$this->checkPerm($session_id, 'config_value_delete')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + // validate fields + if($group == '' || $name == '') { + throw new SoapFault('field_empty_error', 'Group and name parameter may not be empty.'); + return false; + } + + if(!is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { + throw new SoapFault('record_nonexist_error', 'There is no record with this group plus name field combination.'); + return false; + } + + return $app->db->query('DELETE FROM sys_config WHERE `group` = ? AND `name` = ?',$group,$name); + } } diff --git a/interface/web/admin/lib/remote.conf.php b/interface/web/admin/lib/remote.conf.php index 01e03695f..a1067a992 100644 --- a/interface/web/admin/lib/remote.conf.php +++ b/interface/web/admin/lib/remote.conf.php @@ -1,6 +1,6 @@ -- GitLab From f3de95cbaee74e18b2dd25b7b57f9cbcf150fc31 Mon Sep 17 00:00:00 2001 From: florian030 Date: Fri, 15 Jun 2018 16:28:38 +0200 Subject: [PATCH 044/310] re-creation for dkim keys fails (Fixes #5061) --- interface/web/mail/ajax_get_json.php | 10 ++++------ interface/web/mail/templates/mail_domain_edit.htm | 7 ------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/interface/web/mail/ajax_get_json.php b/interface/web/mail/ajax_get_json.php index 153b3e87e..1acbc4ce6 100644 --- a/interface/web/mail/ajax_get_json.php +++ b/interface/web/mail/ajax_get_json.php @@ -40,12 +40,11 @@ $domain_id = $_GET['domain_id']; if($type == 'create_dkim' && $domain_id != ''){ $dkim_public = $_GET['dkim_public']; $dkim_selector = $_GET['dkim_selector']; - $client_id = $_GET['client_group_id']; - $server_id = $_GET['server_id']; - $domain=@(is_numeric($domain_id))?$app->db->queryOneRecord("SELECT domain FROM domain WHERE domain_id = ?", $domain_id)['domain']:$domain_id; - $maildomain = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain = ?", $domain)['domain']; - + $rec = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = ?", $domain); + $server_id = $rec['server_id']; + $maildomain = $rec['domain']; + unset($rec); $mail_config = $app->getconf->get_server_config($server_id, 'mail'); $dkim_strength = $app->functions->intval($mail_config['dkim_strength']); if ($dkim_strength=='') $dkim_strength = 2048; @@ -75,7 +74,6 @@ if($type == 'create_dkim' && $domain_id != ''){ } else { $selector = 'invalid domain or selector'; } - } else { unset($dkim_public); exec('echo '.escapeshellarg($dkim_private).'|openssl rsa -pubout -outform PEM 2> /dev/null',$pubkey,$result); foreach($pubkey as $values) $dkim_public=$dkim_public.$values."\n"; diff --git a/interface/web/mail/templates/mail_domain_edit.htm b/interface/web/mail/templates/mail_domain_edit.htm index ab02aa2ce..71a6655e8 100644 --- a/interface/web/mail/templates/mail_domain_edit.htm +++ b/interface/web/mail/templates/mail_domain_edit.htm @@ -101,9 +101,6 @@
- {tmpl_var name='dkim_generate_txt'}
@@ -129,14 +126,10 @@ function getDKIM() { var domain_id = jQuery('#domain').val(); - var client_group_id = jQuery('#client_group_id').val(); - var server_id = jQuery('#server_id').val(); var dkim_selector = jQuery('#dkim_selector').val(); var dkim_public = jQuery('#dkim_public').val(); jQuery.getJSON('mail/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), { domain_id : domain_id, - client_group_id : client_group_id, - server_id : server_id, dkim_public : dkim_public, dkim_selector : dkim_selector, type : "create_dkim" -- GitLab From 641043555f12aa9b6d0d9ff944789045616d75e1 Mon Sep 17 00:00:00 2001 From: florian030 Date: Fri, 15 Jun 2018 19:25:54 +0200 Subject: [PATCH 045/310] update last commit --- interface/web/mail/ajax_get_json.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/mail/ajax_get_json.php b/interface/web/mail/ajax_get_json.php index 1acbc4ce6..f2ec3c3db 100644 --- a/interface/web/mail/ajax_get_json.php +++ b/interface/web/mail/ajax_get_json.php @@ -40,7 +40,7 @@ $domain_id = $_GET['domain_id']; if($type == 'create_dkim' && $domain_id != ''){ $dkim_public = $_GET['dkim_public']; $dkim_selector = $_GET['dkim_selector']; - $domain=@(is_numeric($domain_id))?$app->db->queryOneRecord("SELECT domain FROM domain WHERE domain_id = ?", $domain_id)['domain']:$domain_id; + $domain=@(is_numeric($domain_id))?$app->db->queryOneRecord("SELECT domain FROM domain WHERE domain_id = ? AND ".$app->tform->getAuthSQL('r'), $domain_id)['domain']:$domain_id; $rec = $app->db->queryOneRecord("SELECT server_id, domain FROM mail_domain WHERE domain = ?", $domain); $server_id = $rec['server_id']; $maildomain = $rec['domain']; -- GitLab From 7c05ac3970e3c5de5ab68f9d3fe7df4a6b2e81e3 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 19 Jun 2018 15:33:56 +0200 Subject: [PATCH 046/310] Fixed: #5062 log rotate ispconfig error.log.1.gz --- server/lib/classes/cron.d/200-logfiles.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/lib/classes/cron.d/200-logfiles.inc.php b/server/lib/classes/cron.d/200-logfiles.inc.php index 40778a8a1..6f38f0b40 100644 --- a/server/lib/classes/cron.d/200-logfiles.inc.php +++ b/server/lib/classes/cron.d/200-logfiles.inc.php @@ -150,8 +150,8 @@ class cronjob_logfiles extends cronjob { $error_logfile = escapeshellcmd($rec['document_root'].'/' . $log_folder . '/error.log'); // rename older files (move up by one) $num = $log_retention; - while($num >= 1 && is_file($error_logfile . '.' . $num . '.gz')) { - rename($error_logfile . '.' . $num . '.gz', $error_logfile . '.' . ($num + 1) . '.gz'); + while($num >= 1) { + if(is_file($error_logfile . '.' . $num . '.gz')) rename($error_logfile . '.' . $num . '.gz', $error_logfile . '.' . ($num + 1) . '.gz'); $num--; } // compress current logfile -- GitLab From 95d4d5cf93ce890c9c4a1b3635d730f040efb3db Mon Sep 17 00:00:00 2001 From: Choong Wei Tjeng Date: Tue, 3 Jul 2018 09:57:51 +0200 Subject: [PATCH 047/310] Also update sys_user language if it was specified through API client_update --- interface/lib/classes/remoting_lib.inc.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index 0f313de6b..a5a5d0c31 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -308,7 +308,9 @@ class remoting_lib extends tform_base { global $app; $username = $params["username"]; $clear_password = $params["password"]; + $language = $params['language']; $client_id = $app->functions->intval($client_id); + if(!isset($params['_ispconfig_pw_crypted']) || $params['_ispconfig_pw_crypted'] != 1) $password = $app->auth->crypt_password(stripslashes($clear_password)); else $password = $clear_password; $params = array($username); @@ -318,8 +320,15 @@ class remoting_lib extends tform_base { } else { $pwstring ="" ; } + + $langstring = ''; + if (!empty($language)) { + $langstring = ', language = ?'; + $params[] = $language; + } + $params[] = $client_id; - $sql = "UPDATE sys_user set username = ? $pwstring WHERE client_id = ?"; + $sql = "UPDATE sys_user set username = ? $pwstring $langstring WHERE client_id = ?"; $app->db->query($sql, true, $params); } -- GitLab From a1c15afc49444c4c32890caedcb82f314b59f671 Mon Sep 17 00:00:00 2001 From: Choong Wei Tjeng Date: Tue, 3 Jul 2018 10:52:16 +0200 Subject: [PATCH 048/310] MySQL connect with client flags. Fixes #4558 --- interface/lib/classes/db_mysql.inc.php | 9 +++++---- server/lib/classes/db_mysql.inc.php | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 948d4e81f..ee6e534b2 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -75,16 +75,17 @@ class db { $this->dbNewLink = $conf[$prefix.'db_new_link']; $this->dbClientFlags = $conf[$prefix.'db_client_flags']; - $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort); + $this->_iConnId = mysqli_init(); + $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); $try = 0; - while((!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5) { + while($this->_iConnId->connect_error && $try < 5) { if($try > 0) sleep(1); $try++; - $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort); + $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); } - if(!is_object($this->_iConnId) || mysqli_connect_error()) { + if($this->_iConnId->connect_error) { $this->_iConnId = null; $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!'); return false; diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 424867f09..21e9dc9aa 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -76,16 +76,17 @@ class db $this->dbNewLink = $conf['db_new_link']; $this->dbClientFlags = $conf['db_client_flags']; - $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort); + $this->_iConnId = mysqli_init(); + $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); $try = 0; - while((!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5) { + while($this->_iConnId->connect_error && $try < 5) { if($try > 0) sleep(1); $try++; - $this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort); + $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); } - if(!is_object($this->_iConnId) || mysqli_connect_error()) { + if($this->_iConnId->connect_error) { $this->_iConnId = null; $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); return false; -- GitLab From 1801e0657ce9bc566631a9f37e8182531b8711c3 Mon Sep 17 00:00:00 2001 From: florian030 Date: Thu, 5 Jul 2018 13:48:55 +0200 Subject: [PATCH 049/310] mail routing configuration allows every server to be selected (Fixes #5068) --- interface/web/mail/form/mail_transport.tform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/mail/form/mail_transport.tform.php b/interface/web/mail/form/mail_transport.tform.php index ee3c52b44..f55541346 100644 --- a/interface/web/mail/form/mail_transport.tform.php +++ b/interface/web/mail/form/mail_transport.tform.php @@ -68,7 +68,7 @@ $form["tabs"]['transport'] = array ( 'formtype' => 'SELECT', 'default' => '', 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT server_id,server_name FROM server WHERE mirror_server_id = 0 AND {AUTHSQL} ORDER BY server_name', + 'querystring' => 'SELECT server_id,server_name FROM server WHERE mirror_server_id = 0 AND mail_server = 1 AND {AUTHSQL} ORDER BY server_name', 'keyfield'=> 'server_id', 'valuefield'=> 'server_name' ), -- GitLab From ebe19f2109cca4e226a890e1b08d6b3719a73db5 Mon Sep 17 00:00:00 2001 From: florian030 Date: Fri, 6 Jul 2018 08:09:25 +0200 Subject: [PATCH 050/310] Show server hostname under system > server config (#5063) --- interface/web/admin/server_config_edit.php | 8 ++++++++ interface/web/admin/templates/server_config_cron_edit.htm | 4 ++-- interface/web/admin/templates/server_config_dns_edit.htm | 2 +- .../web/admin/templates/server_config_fastcgi_edit.htm | 4 ++-- .../web/admin/templates/server_config_getmail_edit.htm | 4 ++-- .../web/admin/templates/server_config_jailkit_edit.htm | 4 ++-- interface/web/admin/templates/server_config_mail_edit.htm | 2 +- .../web/admin/templates/server_config_rescue_edit.htm | 2 +- .../web/admin/templates/server_config_server_edit.htm | 2 +- interface/web/admin/templates/server_config_ufw_edit.htm | 4 ++-- .../web/admin/templates/server_config_vlogger_edit.htm | 4 ++-- interface/web/admin/templates/server_config_web_edit.htm | 2 +- interface/web/admin/templates/server_config_xmpp_edit.htm | 2 +- 13 files changed, 26 insertions(+), 18 deletions(-) diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index 4c03e7ee4..b4868e8fd 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -72,6 +72,14 @@ class page_action extends tform_actions { $app->tpl->setVar($record); } + function onShowEnd() { + global $app; + + $app->tpl->setVar('server_name', $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ? AND ((SELECT COUNT(*) FROM server) > 1)", $this->id)['server_name']); + + parent::onShowEnd(); + } + function onUpdateSave($sql) { global $app, $conf; diff --git a/interface/web/admin/templates/server_config_cron_edit.htm b/interface/web/admin/templates/server_config_cron_edit.htm index 908e6246b..62e6efea7 100644 --- a/interface/web/admin/templates/server_config_cron_edit.htm +++ b/interface/web/admin/templates/server_config_cron_edit.htm @@ -1,5 +1,5 @@

@@ -21,4 +21,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/admin/templates/server_config_dns_edit.htm b/interface/web/admin/templates/server_config_dns_edit.htm index b2b796657..a4f7a26ad 100644 --- a/interface/web/admin/templates/server_config_dns_edit.htm +++ b/interface/web/admin/templates/server_config_dns_edit.htm @@ -1,5 +1,5 @@

diff --git a/interface/web/admin/templates/server_config_fastcgi_edit.htm b/interface/web/admin/templates/server_config_fastcgi_edit.htm index b4c5cac19..c36b482e7 100644 --- a/interface/web/admin/templates/server_config_fastcgi_edit.htm +++ b/interface/web/admin/templates/server_config_fastcgi_edit.htm @@ -1,5 +1,5 @@

@@ -39,4 +39,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/admin/templates/server_config_getmail_edit.htm b/interface/web/admin/templates/server_config_getmail_edit.htm index 406dff412..84ca1ec73 100644 --- a/interface/web/admin/templates/server_config_getmail_edit.htm +++ b/interface/web/admin/templates/server_config_getmail_edit.htm @@ -1,5 +1,5 @@

@@ -15,4 +15,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/admin/templates/server_config_jailkit_edit.htm b/interface/web/admin/templates/server_config_jailkit_edit.htm index 3371fd8a3..b7a749147 100644 --- a/interface/web/admin/templates/server_config_jailkit_edit.htm +++ b/interface/web/admin/templates/server_config_jailkit_edit.htm @@ -1,5 +1,5 @@

@@ -24,4 +24,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm index 926be8e62..c1531c654 100644 --- a/interface/web/admin/templates/server_config_mail_edit.htm +++ b/interface/web/admin/templates/server_config_mail_edit.htm @@ -1,5 +1,5 @@

diff --git a/interface/web/admin/templates/server_config_rescue_edit.htm b/interface/web/admin/templates/server_config_rescue_edit.htm index 435449bf2..df8aa97c0 100644 --- a/interface/web/admin/templates/server_config_rescue_edit.htm +++ b/interface/web/admin/templates/server_config_rescue_edit.htm @@ -1,5 +1,5 @@

diff --git a/interface/web/admin/templates/server_config_server_edit.htm b/interface/web/admin/templates/server_config_server_edit.htm index be44a8555..66ead0899 100644 --- a/interface/web/admin/templates/server_config_server_edit.htm +++ b/interface/web/admin/templates/server_config_server_edit.htm @@ -1,5 +1,5 @@

diff --git a/interface/web/admin/templates/server_config_ufw_edit.htm b/interface/web/admin/templates/server_config_ufw_edit.htm index e84260bc7..85e9c7829 100644 --- a/interface/web/admin/templates/server_config_ufw_edit.htm +++ b/interface/web/admin/templates/server_config_ufw_edit.htm @@ -1,5 +1,5 @@

@@ -60,4 +60,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/admin/templates/server_config_vlogger_edit.htm b/interface/web/admin/templates/server_config_vlogger_edit.htm index edcbaeda8..a53ab7667 100644 --- a/interface/web/admin/templates/server_config_vlogger_edit.htm +++ b/interface/web/admin/templates/server_config_vlogger_edit.htm @@ -1,5 +1,5 @@

@@ -15,4 +15,4 @@
-
\ No newline at end of file + diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm index c1bae44c0..c0f148271 100644 --- a/interface/web/admin/templates/server_config_web_edit.htm +++ b/interface/web/admin/templates/server_config_web_edit.htm @@ -1,5 +1,5 @@

diff --git a/interface/web/admin/templates/server_config_xmpp_edit.htm b/interface/web/admin/templates/server_config_xmpp_edit.htm index acf019b9f..4e6eaf001 100644 --- a/interface/web/admin/templates/server_config_xmpp_edit.htm +++ b/interface/web/admin/templates/server_config_xmpp_edit.htm @@ -1,5 +1,5 @@

-- GitLab From cbd3cd11d56d2704daac8e1df442dbc66cf49229 Mon Sep 17 00:00:00 2001 From: florian030 Date: Fri, 6 Jul 2018 08:40:48 +0200 Subject: [PATCH 051/310] typo in resync-tool and fixed server-list for mailfilter --- interface/web/tools/resync.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/web/tools/resync.php b/interface/web/tools/resync.php index 7e3e9b4da..e5958c064 100644 --- a/interface/web/tools/resync.php +++ b/interface/web/tools/resync.php @@ -74,8 +74,8 @@ class page_action extends tform_actions { //* check the database for existing records $server_data = $this->server_has_data($server_type, $server['server_id']); foreach ($search as $needle) -// if (in_array($needle, $server_data) && strpos($options_servers, $server['server_name']) === false) { - if (in_array($needle, $server_data)) { + if (in_array($needle, $server_data) && strpos($options_servers, $server['server_name']) === false) { +// if (in_array($needle, $server_data)) { $options_servers .= ""; $server_count++; } @@ -525,7 +525,7 @@ class page_action extends tform_actions { $this->dataRecord['db_server_id'] = $this->dataRecord['all_server_id']; $this->dataRecord['mail_server_id'] = $this->dataRecord['all_server_id']; $this->dataRecord['mailbox_server_id'] = $this->dataRecord['all_server_id']; - $this->dataRecord['verserver_server_id'] = $this->dataRecord['all_server_id']; + $this->dataRecord['vserver_server_id'] = $this->dataRecord['all_server_id']; $this->dataRecord['dns_server_id'] = $this->dataRecord['all_server_id']; } @@ -596,7 +596,7 @@ class page_action extends tform_actions { //* vserver if($this->dataRecord['resync_vserver'] == 1) - $msg .= $this->do_resync('openvz_vm', 'vm_id', 'vserver', $this->dataRecord['verserver_server_id'], 'hostname', $app->tform->wordbook['do_vserver_txt']); + $msg .= $this->do_resync('openvz_vm', 'vm_id', 'vserver', $this->dataRecord['vserver_server_id'], 'hostname', $app->tform->wordbook['do_vserver_txt']); //* dns if($this->dataRecord['resync_dns'] == 1) { -- GitLab From bd449bbe02da00cc71bbac55c371d17b1627d43b Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sat, 14 Jul 2018 07:19:03 +0200 Subject: [PATCH 052/310] Add new file 100-monitor_kernel_version.inc.php to stable-3.1 in relation to recently merged commits of https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/790 and https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/791. There is a fix to the filename for master submitted via commit https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/804 that is still pending. --- .../cron.d/100-monitor_kernel_version.inc.php | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 server/lib/classes/cron.d/100-monitor_kernel_version.inc.php diff --git a/server/lib/classes/cron.d/100-monitor_kernel_version.inc.php b/server/lib/classes/cron.d/100-monitor_kernel_version.inc.php new file mode 100644 index 000000000..6ead20bdd --- /dev/null +++ b/server/lib/classes/cron.d/100-monitor_kernel_version.inc.php @@ -0,0 +1,107 @@ +load('monitor_tools'); + $this->_tools = new monitor_tools(); + /* end global section for monitor cronjobs */ + + /* the id of the server as int */ + $server_id = intval($conf['server_id']); + + /** The type of the data */ + + $type = 'kernel_info'; + + /* + Fetch the data into a array + */ + $kernel = shell_exec("uname -mrs"); + + $data['name'] = ''; + $data['version'] = $kernel; + + /* the OS has no state. It is, what it is */ + $state = 'no_state'; + + $res = array(); + $res['server_id'] = $server_id; + $res['type'] = $type; + $res['data'] = $data; + $res['state'] = $state; + + /* + * Insert the data into the database + */ + $sql = 'REPLACE INTO monitor_data (server_id, type, created, data, state) ' . + 'VALUES (?, ?, UNIX_TIMESTAMP(), ?, ?)'; + $app->dbmaster->query($sql, $res['server_id'], $res['type'], serialize($res['data']), $res['state']); + + /* The new data is written, now we can delete the old one */ + $this->_tools->delOldRecords($res['type'], $res['server_id']); + + parent::onRunJob(); + } + + /* this function is optional if it contains no custom code */ + public function onAfterRun() { + global $app; + + parent::onAfterRun(); + } + +} + +?> -- GitLab From aa5687d9dee57ce452714fe9996f01aa1f8ed94d Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sat, 14 Jul 2018 07:24:28 +0200 Subject: [PATCH 053/310] Update show_sys_state.php to display current kernel info for stable-3.1 in relation to recently merged commits of https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/790 and https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/791. There is a fix to the filename for master submitted via commit https://git.ispconfig.org/ispconfig/ispconfig3/merge_requests/804 that is still pending. -- GitLab From 8f688ff07e800176eade9652397f199e87724156 Mon Sep 17 00:00:00 2001 From: ahrasis Date: Sat, 14 Jul 2018 15:26:08 +0800 Subject: [PATCH 054/310] Add word "Kernel" to respective language files Add word "Kernel" to all respective language files in stable3.1. $wb['monitor_serverstate_kernel_txt'] = 'Kernel'; In relation with the earlier merged commits of !790 and !791. --- interface/web/monitor/lib/lang/ar.lng | 1 + interface/web/monitor/lib/lang/bg.lng | 1 + interface/web/monitor/lib/lang/br.lng | 1 + interface/web/monitor/lib/lang/ca.lng | 1 + interface/web/monitor/lib/lang/cz.lng | 1 + interface/web/monitor/lib/lang/de.lng | 1 + interface/web/monitor/lib/lang/dk.lng | 1 + interface/web/monitor/lib/lang/el.lng | 1 + interface/web/monitor/lib/lang/en.lng | 1 + interface/web/monitor/lib/lang/es.lng | 1 + interface/web/monitor/lib/lang/fi.lng | 1 + interface/web/monitor/lib/lang/fr.lng | 1 + interface/web/monitor/lib/lang/hr.lng | 1 + interface/web/monitor/lib/lang/hu.lng | 1 + interface/web/monitor/lib/lang/id.lng | 1 + interface/web/monitor/lib/lang/it.lng | 1 + interface/web/monitor/lib/lang/ja.lng | 1 + interface/web/monitor/lib/lang/nl.lng | 1 + interface/web/monitor/lib/lang/pl.lng | 1 + interface/web/monitor/lib/lang/pt.lng | 1 + interface/web/monitor/lib/lang/ro.lng | 1 + interface/web/monitor/lib/lang/ru.lng | 1 + interface/web/monitor/lib/lang/se.lng | 1 + interface/web/monitor/lib/lang/sk.lng | 1 + interface/web/monitor/lib/lang/tr.lng | 1 + 25 files changed, 25 insertions(+) diff --git a/interface/web/monitor/lib/lang/ar.lng b/interface/web/monitor/lib/lang/ar.lng index 7b7f74159..e00287a8e 100644 --- a/interface/web/monitor/lib/lang/ar.lng +++ b/interface/web/monitor/lib/lang/ar.lng @@ -65,6 +65,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_nosupportedraid1_txt'] = 'At the moment, we support mdadm or mpt-status for monitoring the RAID.
We cant find any of them at your server.

This means we can not support your RAID yet.'; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'State'; $wb['monitor_serverstate_unknown_txt'] = 'unknown'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/bg.lng b/interface/web/monitor/lib/lang/bg.lng index 526646bb5..0db4623d0 100644 --- a/interface/web/monitor/lib/lang/bg.lng +++ b/interface/web/monitor/lib/lang/bg.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Сървър'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Статус'; $wb['monitor_serverstate_unknown_txt'] = 'неизвестно'; $wb['monitor_serverstate_info_txt'] = 'инфо'; diff --git a/interface/web/monitor/lib/lang/br.lng b/interface/web/monitor/lib/lang/br.lng index e2a490e46..048fec64b 100644 --- a/interface/web/monitor/lib/lang/br.lng +++ b/interface/web/monitor/lib/lang/br.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Log do clamav '; $wb['monitor_logs_ispc_txt'] = 'Log do ispconfig'; $wb['monitor_norkhunter_txt'] = 'RKHunter não está instalado, então não existem logs a exibir'; $wb['monitor_serverstate_server_txt'] = 'Servidor'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Estado'; $wb['monitor_serverstate_unknown_txt'] = 'desconhecido(s)'; $wb['monitor_serverstate_info_txt'] = 'informação(es)'; diff --git a/interface/web/monitor/lib/lang/ca.lng b/interface/web/monitor/lib/lang/ca.lng index 29859cfae..4575be2ff 100644 --- a/interface/web/monitor/lib/lang/ca.lng +++ b/interface/web/monitor/lib/lang/ca.lng @@ -68,6 +68,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_nosupportedraid1_txt'] = 'Pour le moment, seuls mdadm ou mpt-status sont supportés pour surveiller le RAID.
Aucun des deux n\'a été trouvé sur votre serveur.

Nous ne supportons donc pas votre RAID.'; $wb['monitor_norkhunter_txt'] = 'RKHunter nest pas installé, il ny a donc pas de logs'; $wb['monitor_serverstate_server_txt'] = 'Serveur'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Etat'; $wb['monitor_serverstate_unknown_txt'] = 'inconnu'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/cz.lng b/interface/web/monitor/lib/lang/cz.lng index a4e670df6..dc3e3cb34 100644 --- a/interface/web/monitor/lib/lang/cz.lng +++ b/interface/web/monitor/lib/lang/cz.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'ClamAV - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter není nainstalován, proto zde nejsou žádna data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Stav'; $wb['monitor_serverstate_unknown_txt'] = 'neznámý'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/de.lng b/interface/web/monitor/lib/lang/de.lng index 6a342be1e..78954daee 100644 --- a/interface/web/monitor/lib/lang/de.lng +++ b/interface/web/monitor/lib/lang/de.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'ClamAV Protokoll'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig Protokoll'; $wb['monitor_norkhunter_txt'] = 'RKHunter ist nicht installiert, deshalb gibt es keine Protokolldatei'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Status'; $wb['monitor_serverstate_unknown_txt'] = 'unbekannt'; $wb['monitor_serverstate_info_txt'] = 'Info'; diff --git a/interface/web/monitor/lib/lang/dk.lng b/interface/web/monitor/lib/lang/dk.lng index da8aa1122..dc43c1306 100644 --- a/interface/web/monitor/lib/lang/dk.lng +++ b/interface/web/monitor/lib/lang/dk.lng @@ -68,6 +68,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_nosupportedraid1_txt'] = 'I øjeblikket støtter vi \'mdadm\' eller \'mpt-status\' til overvågning af RAID.
Vi kan ikke finde nogen af dem på din server.

Det betyder, at vi ikke kan støtte din RAID endnu.'; $wb['monitor_norkhunter_txt'] = 'RKHunter er ikke installeret, så der er ingen log data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Status'; $wb['monitor_serverstate_unknown_txt'] = 'ukendt'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/el.lng b/interface/web/monitor/lib/lang/el.lng index 1df165204..414642e2e 100644 --- a/interface/web/monitor/lib/lang/el.lng +++ b/interface/web/monitor/lib/lang/el.lng @@ -65,6 +65,7 @@ $wb['monitor_logs_ispc_txt'] = 'Αρχείο καταγραφής ISPConfig'; $wb['monitor_nosupportedraid1_txt'] = 'Προς το παρόν υποστηρίζουμε mdadm ή mpt-status για την εποπτεία του RAID.
Δεν μπορούμε να βρούμε κάποιο από αυτά στον server σας.

Αυτό σημαίνει ότι δεν μπορούμε να υποστηρίξουμε το RAID σας ακόμη.'; $wb['monitor_norkhunter_txt'] = 'Το RKHunter δεν είναι εγκατεστημένο, οπότε δεν υπάρχουν δεδομένα'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Κατάσταση'; $wb['monitor_serverstate_unknown_txt'] = 'άγνωστη'; $wb['monitor_serverstate_info_txt'] = 'πληροφορία'; diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index aa6472e58..f4dbbeff9 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -74,6 +74,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_nosupportedraid1_txt'] = "At the moment, we support 'mdadm' or 'mpt-status' for monitoring the RAID.
We can't find any of them at your server.

This means we can not support your RAID yet."; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'State'; $wb['monitor_serverstate_unknown_txt'] = 'unknown'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/es.lng b/interface/web/monitor/lib/lang/es.lng index 023a2ea0e..8cc87b480 100755 --- a/interface/web/monitor/lib/lang/es.lng +++ b/interface/web/monitor/lib/lang/es.lng @@ -74,6 +74,7 @@ $wb['monitor_serverstate_server_txt'] = 'Servidor'; $wb['monitor_serverstate_servicesoffline_txt'] = 'Uno o más servicios necesarios no están funcionando'; $wb['monitor_serverstate_servicesonline_txt'] = 'Todos los servicios necesarios están funcionando'; $wb['monitor_serverstate_servicesunknown_txt'] = 'Servicios: ¿?'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Estado'; $wb['monitor_serverstate_syslogerror_txt'] = 'Hay errores en su registro del sistema'; $wb['monitor_serverstate_syslogok_txt'] = 'El registro del sistema está bien'; diff --git a/interface/web/monitor/lib/lang/fi.lng b/interface/web/monitor/lib/lang/fi.lng index 73653e84b..44143f3d2 100755 --- a/interface/web/monitor/lib/lang/fi.lng +++ b/interface/web/monitor/lib/lang/fi.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav-päivitysloki'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig-pääloki'; $wb['monitor_norkhunter_txt'] = 'RKHunter ei ole asennettuna, joten siitä ei ole tulostietoja.'; $wb['monitor_serverstate_server_txt'] = 'Palvelin'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Tila'; $wb['monitor_serverstate_unknown_txt'] = 'tuntematonta'; $wb['monitor_serverstate_info_txt'] = 'viestiä'; diff --git a/interface/web/monitor/lib/lang/fr.lng b/interface/web/monitor/lib/lang/fr.lng index 49d118f34..9fb2ab5e8 100644 --- a/interface/web/monitor/lib/lang/fr.lng +++ b/interface/web/monitor/lib/lang/fr.lng @@ -68,6 +68,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_nosupportedraid1_txt'] = 'Pour le moment, seuls mdadm ou mpt-status sont supportés pour surveiller le RAID.
Aucun des deux n’a été trouvé sur votre serveur.

Nous ne supportons donc pas votre RAID.'; $wb['monitor_norkhunter_txt'] = 'RKHunter nest pas installé, il ny a donc pas de logs'; $wb['monitor_serverstate_server_txt'] = 'Serveur'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Etat'; $wb['monitor_serverstate_unknown_txt'] = 'inconnu'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/hr.lng b/interface/web/monitor/lib/lang/hr.lng index 923b68d00..d87856810 100644 --- a/interface/web/monitor/lib/lang/hr.lng +++ b/interface/web/monitor/lib/lang/hr.lng @@ -65,6 +65,7 @@ $wb['monitor_logs_ispc_txt'] = 'Control panel log-ovi'; $wb['monitor_nosupportedraid1_txt'] = 'Trenutno je podržan samo mdadm ili mpt-status za nadzor RAID-a.
Ne možemo pronaći niti jedan na vašem serveru.

To znači da ne možemo podržati vaš RAID.'; $wb['monitor_norkhunter_txt'] = 'RKHunter nije instaliran, stoga nema log podataka.'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Stanje'; $wb['monitor_serverstate_unknown_txt'] = 'nepoznatih'; $wb['monitor_serverstate_info_txt'] = 'informacija'; diff --git a/interface/web/monitor/lib/lang/hu.lng b/interface/web/monitor/lib/lang/hu.lng index acf7b40b4..85fda9790 100644 --- a/interface/web/monitor/lib/lang/hu.lng +++ b/interface/web/monitor/lib/lang/hu.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Szerver'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Státusz'; $wb['monitor_serverstate_unknown_txt'] = 'ismeretlen'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/id.lng b/interface/web/monitor/lib/lang/id.lng index ffb5a79c3..d77f14564 100644 --- a/interface/web/monitor/lib/lang/id.lng +++ b/interface/web/monitor/lib/lang/id.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Log - ClamAV'; $wb['monitor_logs_ispc_txt'] = 'Log - ISPConfig'; $wb['monitor_norkhunter_txt'] = 'RKHunter tidak terpasang, hingga tidak ada data log'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Kondisi'; $wb['monitor_serverstate_unknown_txt'] = 'tak diketahui'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/it.lng b/interface/web/monitor/lib/lang/it.lng index 47d9c4da0..c7a682368 100644 --- a/interface/web/monitor/lib/lang/it.lng +++ b/interface/web/monitor/lib/lang/it.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter non è installato, non sono disponibili dati nel log '; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Stato'; $wb['monitor_serverstate_unknown_txt'] = 'sconosciuto'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/ja.lng b/interface/web/monitor/lib/lang/ja.lng index 22d3b272e..bc2c7d2b5 100644 --- a/interface/web/monitor/lib/lang/ja.lng +++ b/interface/web/monitor/lib/lang/ja.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - ログ'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - ログ'; $wb['monitor_norkhunter_txt'] = 'RKHunterがインストールされていないため、データが存在しません。'; $wb['monitor_serverstate_server_txt'] = 'サーバー'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = '状態'; $wb['monitor_serverstate_unknown_txt'] = '不明'; $wb['monitor_serverstate_info_txt'] = '情報'; diff --git a/interface/web/monitor/lib/lang/nl.lng b/interface/web/monitor/lib/lang/nl.lng index 760803a5d..81caa02b7 100644 --- a/interface/web/monitor/lib/lang/nl.lng +++ b/interface/web/monitor/lib/lang/nl.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter is niet geïnstalleerd. Hierdoor is er geen informatie beschikbaar.'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'status'; $wb['monitor_serverstate_unknown_txt'] = 'onbekend'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/pl.lng b/interface/web/monitor/lib/lang/pl.lng index 4ce642fbd..77d05e056 100644 --- a/interface/web/monitor/lib/lang/pl.lng +++ b/interface/web/monitor/lib/lang/pl.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Log Clamav'; $wb['monitor_logs_ispc_txt'] = 'Log ISPConfig'; $wb['monitor_norkhunter_txt'] = 'RKHunter nie jest zainstalowany, więc nie ma Log-u'; $wb['monitor_serverstate_server_txt'] = 'Serwer'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Status'; $wb['monitor_serverstate_unknown_txt'] = 'nieznany'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/pt.lng b/interface/web/monitor/lib/lang/pt.lng index 6ad8038b9..2218ede89 100644 --- a/interface/web/monitor/lib/lang/pt.lng +++ b/interface/web/monitor/lib/lang/pt.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Log do Clamav '; $wb['monitor_logs_ispc_txt'] = 'Log do ISPConfig'; $wb['monitor_norkhunter_txt'] = 'RKHunter não está instalado, então não existem logs a exibir'; $wb['monitor_serverstate_server_txt'] = 'Servidor'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Estado'; $wb['monitor_serverstate_unknown_txt'] = 'desconhecido'; $wb['monitor_serverstate_info_txt'] = 'informações'; diff --git a/interface/web/monitor/lib/lang/ro.lng b/interface/web/monitor/lib/lang/ro.lng index 85063a047..7b06c4ba0 100644 --- a/interface/web/monitor/lib/lang/ro.lng +++ b/interface/web/monitor/lib/lang/ro.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'ClamAV - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'State'; $wb['monitor_serverstate_unknown_txt'] = 'unknown'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/ru.lng b/interface/web/monitor/lib/lang/ru.lng index cbabab99e..49e9d4604 100644 --- a/interface/web/monitor/lib/lang/ru.lng +++ b/interface/web/monitor/lib/lang/ru.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - журнал'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - журнал'; $wb['monitor_norkhunter_txt'] = 'RKHunter не установлен, поэтому нет логов'; $wb['monitor_serverstate_server_txt'] = 'Сервер'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Состояние'; $wb['monitor_serverstate_unknown_txt'] = 'неизвестных'; $wb['monitor_serverstate_info_txt'] = 'информации'; diff --git a/interface/web/monitor/lib/lang/se.lng b/interface/web/monitor/lib/lang/se.lng index 4d3e8d727..732805d2a 100644 --- a/interface/web/monitor/lib/lang/se.lng +++ b/interface/web/monitor/lib/lang/se.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - logg'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - logg'; $wb['monitor_norkhunter_txt'] = 'RKHunter är inte installerat så det finns ingen loggdata'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Status'; $wb['monitor_serverstate_unknown_txt'] = 'okänd'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/sk.lng b/interface/web/monitor/lib/lang/sk.lng index c74508a1f..769724238 100644 --- a/interface/web/monitor/lib/lang/sk.lng +++ b/interface/web/monitor/lib/lang/sk.lng @@ -64,6 +64,7 @@ $wb['monitor_logs_clamav_txt'] = 'Clamav - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; $wb['monitor_norkhunter_txt'] = 'RKHunter is not installed, so there is no log data'; $wb['monitor_serverstate_server_txt'] = 'Server'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'State'; $wb['monitor_serverstate_unknown_txt'] = 'unknown'; $wb['monitor_serverstate_info_txt'] = 'info'; diff --git a/interface/web/monitor/lib/lang/tr.lng b/interface/web/monitor/lib/lang/tr.lng index 091b95900..00beedb1d 100644 --- a/interface/web/monitor/lib/lang/tr.lng +++ b/interface/web/monitor/lib/lang/tr.lng @@ -68,6 +68,7 @@ $wb['monitor_logs_ispc_txt'] = 'ISPConfig Günlüğü'; $wb['monitor_nosupportedraid1_txt'] = 'Şimdilik RAID durumunu izlemek için mdadm ya da mpt-status destekleniyor.
Bunlardan biri sunucunuzda bulunamadı.

Bu nedenle RAID sürücünüz henüz desteklenemiyor.'; $wb['monitor_norkhunter_txt'] = 'RKHunter yüklü olmadığından herhangi bir günlük verisi yok'; $wb['monitor_serverstate_server_txt'] = 'Sunucu'; +$wb['monitor_serverstate_kernel_txt'] = 'Kernel'; $wb['monitor_serverstate_state_txt'] = 'Durum'; $wb['monitor_serverstate_unknown_txt'] = 'bilinmiyor'; $wb['monitor_serverstate_info_txt'] = 'bilgi'; -- GitLab From 43e1d025cf60e25577647827c9c26ed609999638 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 16 Jul 2018 14:24:20 +0200 Subject: [PATCH 055/310] Extended IDS whitelist. Fixed connection issue in mail account import tool. --- interface/web/tools/import_ispconfig.php | 14 +++++++++++++- security/ids.whitelist | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/interface/web/tools/import_ispconfig.php b/interface/web/tools/import_ispconfig.php index 0e7763dd9..4012802bc 100644 --- a/interface/web/tools/import_ispconfig.php +++ b/interface/web/tools/import_ispconfig.php @@ -109,10 +109,22 @@ if(isset($_POST['connected'])) { try { + //* Allow connections to self signed SSL certs + $context = stream_context_create( + array( + 'ssl' => array ( + 'verify_peer' => false, + 'verify_peer_name' => false, + 'allow_self_signed' => true + ) + ) + ); + $client = new SoapClient(null, array('location' => $_POST['remote_server'], 'uri' => $_POST['remote_server'].'/index.php', 'trace' => 1, - 'exceptions' => 1)); + 'exceptions' => 1, + 'stream_context' => $context)); if(!isset($remote_session_id)) $remote_session_id = $_POST['remote_session_id']; diff --git a/security/ids.whitelist b/security/ids.whitelist index 42c0559ec..a9b045e15 100644 --- a/security/ids.whitelist +++ b/security/ids.whitelist @@ -41,6 +41,7 @@ admin:/capp.php:SESSION.s.module.nav.1.items.0.title admin:/sites/web_vhost_subdomain_edit.php:POST.php_open_basedir admin:/sites/web_domain_edit.php:POST.php_open_basedir admin:/sites/web_domain_edit.php:POST.apache_directives +admin:/sites/web_vhost_domain_edit.php:POST.nginx_directives user:/sites/shell_user_edit.php:POST.ssh_rsa user:/sites/cron_edit.php:POST.command admin:/admin/server_config_edit.php:POST.jailkit_chroot_app_programs -- GitLab From 67d81d3f6d367b8ce011b5bf85c566fdb815c6ce Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 16 Jul 2018 17:31:29 +0200 Subject: [PATCH 056/310] Fixed nginx socket path in apps vhost for Ubuntu 18.04. --- install/lib/installer_base.lib.php | 6 +++--- server/plugins-available/apps_vhost_plugin.inc.php | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 8a1dcd465..10cfbaf96 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2135,9 +2135,9 @@ class installer_base { $content = str_replace('{ssl_comment}', '#', $content); // Fix socket path on PHP 7 systems - if(file_exists('/var/run/php/php7.0-fpm.sock')) { - $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content); - } + if(file_exists('/var/run/php/php7.0-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content); + if(file_exists('/var/run/php/php7.1-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.1-fpm.sock', $content); + if(file_exists('/var/run/php/php7.2-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.2-fpm.sock', $content); wf($vhost_conf_dir.'/apps.vhost', $content); diff --git a/server/plugins-available/apps_vhost_plugin.inc.php b/server/plugins-available/apps_vhost_plugin.inc.php index 88b5aa290..b843e3c8a 100644 --- a/server/plugins-available/apps_vhost_plugin.inc.php +++ b/server/plugins-available/apps_vhost_plugin.inc.php @@ -183,6 +183,11 @@ class apps_vhost_plugin { } $content = str_replace('{use_tcp}', $use_tcp, $content); $content = str_replace('{use_socket}', $use_socket, $content); + + // Fix socket path on PHP 7 systems + if(file_exists('/var/run/php/php7.0-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content); + if(file_exists('/var/run/php/php7.1-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.1-fpm.sock', $content); + if(file_exists('/var/run/php/php7.2-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.2-fpm.sock', $content); // PHP-FPM // Dont just copy over the php-fpm pool template but add some custom settings -- GitLab From b1cfd5bb00082502f2543728faae19700ded73ca Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 16 Jul 2018 18:12:06 +0200 Subject: [PATCH 057/310] Improved code to set server_name under system config. --- interface/web/admin/server_config_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index b4868e8fd..e446bf3ad 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -75,7 +75,7 @@ class page_action extends tform_actions { function onShowEnd() { global $app; - $app->tpl->setVar('server_name', $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ? AND ((SELECT COUNT(*) FROM server) > 1)", $this->id)['server_name']); + $app->tpl->setVar('server_name', $app->functions->htmlentities($app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ? AND ((SELECT COUNT(*) FROM server) > 1)", $this->id)['server_name'])); parent::onShowEnd(); } -- GitLab From 7032859085464215cf19e5660c883f6dfd64cf54 Mon Sep 17 00:00:00 2001 From: Davide Piccagnoni Date: Tue, 17 Jul 2018 16:12:58 +0200 Subject: [PATCH 058/310] Update it_mail_user_autoresponder.lng --- .../lib/lang/it_mail_user_autoresponder.lng | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/interface/web/mailuser/lib/lang/it_mail_user_autoresponder.lng b/interface/web/mailuser/lib/lang/it_mail_user_autoresponder.lng index caaac2e7c..c4a98624d 100644 --- a/interface/web/mailuser/lib/lang/it_mail_user_autoresponder.lng +++ b/interface/web/mailuser/lib/lang/it_mail_user_autoresponder.lng @@ -1,13 +1,13 @@ -- GitLab From a6c39cdd859aa32451bc09e360827a6fcae4f17b Mon Sep 17 00:00:00 2001 From: Davide Piccagnoni Date: Tue, 17 Jul 2018 17:24:45 +0200 Subject: [PATCH 059/310] Updated mailuser Italian language --- interface/web/mailuser/lib/lang/it_mail_user_cc.lng | 12 ++++++------ .../web/mailuser/lib/lang/it_mail_user_password.lng | 12 ++++++------ .../mailuser/lib/lang/it_mail_user_spamfilter.lng | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/interface/web/mailuser/lib/lang/it_mail_user_cc.lng b/interface/web/mailuser/lib/lang/it_mail_user_cc.lng index 01f22f5fc..555d04143 100644 --- a/interface/web/mailuser/lib/lang/it_mail_user_cc.lng +++ b/interface/web/mailuser/lib/lang/it_mail_user_cc.lng @@ -1,9 +1,9 @@ diff --git a/interface/web/mailuser/lib/lang/it_mail_user_password.lng b/interface/web/mailuser/lib/lang/it_mail_user_password.lng index b5c3af195..ef05d5640 100644 --- a/interface/web/mailuser/lib/lang/it_mail_user_password.lng +++ b/interface/web/mailuser/lib/lang/it_mail_user_password.lng @@ -1,11 +1,11 @@ diff --git a/interface/web/mailuser/lib/lang/it_mail_user_spamfilter.lng b/interface/web/mailuser/lib/lang/it_mail_user_spamfilter.lng index 9d4c5496e..a0f889d86 100644 --- a/interface/web/mailuser/lib/lang/it_mail_user_spamfilter.lng +++ b/interface/web/mailuser/lib/lang/it_mail_user_spamfilter.lng @@ -1,7 +1,7 @@ -- GitLab From 4ff0d1a07a70a8f081bf0b3fbc1b2bf30d30d705 Mon Sep 17 00:00:00 2001 From: Vojtech Myslivec Date: Wed, 18 Jul 2018 00:05:21 +0200 Subject: [PATCH 060/310] Remove some duplicities in en translations --- interface/web/client/lib/lang/en.lng | 3 +-- interface/web/mail/lib/lang/en.lng | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/interface/web/client/lib/lang/en.lng b/interface/web/client/lib/lang/en.lng index 743516c96..40154b03a 100644 --- a/interface/web/client/lib/lang/en.lng +++ b/interface/web/client/lib/lang/en.lng @@ -24,7 +24,6 @@ $wb['error_domain_in dnsslaveuse'] = 'This domain cannot be deleted, because it $wb['error_domain_in mailuse'] = 'This domain cannot be deleted, because it is in use as mail-domain'; $wb['error_domain_in webuse'] = 'This domain cannot be deleted, because it is in use as web-domain'; $wb['error_client_can_not_add_domain'] = 'You cannot add a new domain'; -$wb['domain_txt'] = 'Domain'; $wb['error_client_group_id_empty'] = 'You have to select a customer
'; $wb['Email-Templates'] = 'Email-Templates'; -?> \ No newline at end of file +?> diff --git a/interface/web/mail/lib/lang/en.lng b/interface/web/mail/lib/lang/en.lng index e5f9e678c..e320511bb 100644 --- a/interface/web/mail/lib/lang/en.lng +++ b/interface/web/mail/lib/lang/en.lng @@ -20,7 +20,6 @@ $wb['Email filter'] = 'Email filter'; $wb['Email Whitelist'] = 'Email Whitelist'; $wb['Whitelist'] = 'Whitelist'; $wb['Spamfilter blacklist'] = 'Spamfilter blacklist'; -$wb['Blacklist'] = 'Blacklist'; $wb['Spamfilter Config'] = 'Spamfilter Config'; $wb['Server'] = 'Server'; $wb['Spamfilter policy'] = 'Spamfilter policy'; @@ -31,13 +30,11 @@ $wb['Other'] = 'Other'; $wb['Spamfilter users'] = 'Spamfilter users'; $wb['Users'] = 'Users'; $wb['Spamfilter Whitelist'] = 'Spamfilter Whitelist'; -$wb['Whitelist'] = 'Whitelist'; $wb['Email'] = 'Email'; $wb['Email Mailbox'] = 'Email Mailbox'; $wb['Email Accounts'] = 'Email Accounts'; $wb['User / Domain'] = 'User / Domain'; $wb['Server Settings'] = 'Server Settings'; -$wb['Spamfilter'] = 'Spamfilter'; $wb['Fetchmail'] = 'Fetchmail'; $wb['Mailbox traffic'] = 'Mailbox traffic'; $wb['Statistics'] = 'Statistics'; @@ -48,4 +45,4 @@ $wb['Global Filters'] = 'Global Filters'; $wb['Domain Alias'] = 'Domain Alias'; $wb["Relay Recipients"] = 'Relay Recipients'; $wb['Mailbox quota'] = 'Mailbox quota'; -?> \ No newline at end of file +?> -- GitLab From 7d848629f094c13f379eb624749007180280da9c Mon Sep 17 00:00:00 2001 From: Vojtech Myslivec Date: Tue, 17 Jul 2018 23:07:24 +0200 Subject: [PATCH 061/310] Unify main cz translations Reorder the lines to match en original translation and to achieve easier machine comparison --- interface/lib/lang/cz.lng | 26 ++++++++--------- interface/web/admin/lib/lang/cz.lng | 42 +++++++++++++++++---------- interface/web/client/lib/lang/cz.lng | 4 +-- interface/web/help/lib/lang/cz.lng | 2 +- interface/web/login/lib/lang/cz.lng | 14 ++++----- interface/web/mail/lib/lang/cz.lng | 2 +- interface/web/monitor/lib/lang/cz.lng | 38 ++++++++++++------------ interface/web/sites/lib/lang/cz.lng | 4 +-- interface/web/tools/lib/lang/cz.lng | 4 +-- 9 files changed, 74 insertions(+), 62 deletions(-) diff --git a/interface/lib/lang/cz.lng b/interface/lib/lang/cz.lng index b1518d96b..28ee941a8 100644 --- a/interface/lib/lang/cz.lng +++ b/interface/lib/lang/cz.lng @@ -1,5 +1,6 @@ diff --git a/interface/web/admin/lib/lang/cz.lng b/interface/web/admin/lib/lang/cz.lng index 957ddffeb..a54f348b3 100644 --- a/interface/web/admin/lib/lang/cz.lng +++ b/interface/web/admin/lib/lang/cz.lng @@ -1,52 +1,64 @@ diff --git a/interface/web/client/lib/lang/cz.lng b/interface/web/client/lib/lang/cz.lng index 447810f94..147d1fd9d 100644 --- a/interface/web/client/lib/lang/cz.lng +++ b/interface/web/client/lib/lang/cz.lng @@ -19,11 +19,11 @@ $wb['Edit Client Circle'] = 'Upravit skupinu klientů'; $wb['Domains'] = 'Domény'; $wb['domain_txt'] = 'Doména'; $wb['client_txt'] = 'Klient'; +$wb['error_domain_in dnsuse'] = 'This domain cannot be deleted, because it is in use as dns zone'; +$wb['error_domain_in dnsslaveuse'] = 'This domain cannot be deleted, because it is in use as secondary dns zone'; $wb['error_domain_in mailuse'] = 'Tato doména nelze odstranit, protože je v používána jako poštovní doména'; $wb['error_domain_in webuse'] = 'Tato doména nelze odstranit, protože je v používána jako webová doména'; $wb['error_client_can_not_add_domain'] = 'Nemůžete přidat novou doménu'; $wb['error_client_group_id_empty'] = 'Musíte vybrat zákazníka
'; -$wb['error_domain_in dnsuse'] = 'This domain cannot be deleted, because it is in use as dns zone'; -$wb['error_domain_in dnsslaveuse'] = 'This domain cannot be deleted, because it is in use as secondary dns zone'; $wb['Email-Templates'] = 'E-mailové šablony'; ?> diff --git a/interface/web/help/lib/lang/cz.lng b/interface/web/help/lib/lang/cz.lng index 55279c6a6..1288ef0fd 100644 --- a/interface/web/help/lib/lang/cz.lng +++ b/interface/web/help/lib/lang/cz.lng @@ -9,6 +9,6 @@ $wb['Version'] = 'Verze'; $wb['Frequently Asked Questions'] = 'Často kladené dotazy'; $wb['FAQ Sections'] = 'Sekce FAQ - Často kladené dotazy'; $wb['Manage Sections'] = 'Spravovat sekce'; -$wb['Manage Questions'] = 'Spravovat dotazy'; $wb['Add a Question & Answer Pair'] = 'Vytvořit otázku a odpověď'; +$wb['Manage Questions'] = 'Spravovat dotazy'; ?> diff --git a/interface/web/login/lib/lang/cz.lng b/interface/web/login/lib/lang/cz.lng index 065f6fc86..7e864ecfb 100644 --- a/interface/web/login/lib/lang/cz.lng +++ b/interface/web/login/lib/lang/cz.lng @@ -5,29 +5,29 @@ $wb['error_user_blocked'] = 'Uživatel je blokován.'; $wb['error_user_too_many_logins'] = 'Příliš mnoho nesprávných přihlášení, zkuste to za 15 minut znovu'; $wb['pass_reset_txt'] = 'Bude Vám vygenerováno a zasláno nové heslo na e-mail, pokud Vaše adresa zadaná níže odpovídá adrese ve Vašem klientském nastavení.'; $wb['pw_reset'] = 'Heslo bylo resetováno a zasláno na Váš e-mail.'; +$wb['pw_reset_act'] = 'You have been sent an activation link. Please visit the link to confirm your password request.'; $wb['pw_error'] = 'Uživatelské jméno nebo e-mail nesouhlasí.'; $wb['pw_error_noinput'] = 'Prosím zadejte uživatelské jméno a e-mail.'; $wb['pw_reset_mail_msg'] = 'Vaše heslo do ISPConfigu bylo resetováno. Nové heslo je: '; $wb['pw_reset_mail_title'] = 'Heslo do ISPConfigu bylo resetováno.'; +$wb['pw_reset_act_mail_title'] = 'Confirm ISPConfig 3 Control panel password reset'; +$wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPConfig 3 control panel account password by visiting the following activation link: '; $wb['user_regex_error'] = 'Uživatelské jméno obsahuje nepovolené znaky nebo je delší než 64 znaků.'; $wb['pw_error_length'] = 'Heslo je delší než 64 znaků.'; +$wb['email_error'] = 'E-mail obsahuje nepovolené znaky nebo má neplatný formát.'; +$wb['login_txt'] = 'Přihlášení'; $wb['username_txt'] = 'Uživatelské jméno'; $wb['password_txt'] = 'Heslo'; $wb['login_button_txt'] = 'Přihlásit se'; $wb['pw_lost_txt'] = 'Obnovit zapomenuté heslo'; -$wb['error_maintenance_mode'] = 'V současné době probíhá údržba systému ISPConfig. Přihlášení zkuste prosím později. Děkujeme Vám za trpělivost.'; -$wb['login_txt'] = 'Přihlášení'; $wb['pw_reset_txt'] = 'Resetování (obnova) hesla'; $wb['pw_button_txt'] = 'Znovu odeslat heslo'; $wb['email_txt'] = 'E-mail'; -$wb['theme_not_compatible'] = 'Zvolené téma není kompatibilní s aktuální verzí ISPConfig. Zkontrolujte prosím, zda není nová verze tématu.
Výchozí motiv byl aktivován automaticky.'; $wb['back_txt'] = 'Zpět'; -$wb['email_error'] = 'E-mail obsahuje nepovolené znaky nebo má neplatný formát.'; +$wb['error_maintenance_mode'] = 'V současné době probíhá údržba systému ISPConfig. Přihlášení zkuste prosím později. Děkujeme Vám za trpělivost.'; +$wb['theme_not_compatible'] = 'Zvolené téma není kompatibilní s aktuální verzí ISPConfig. Zkontrolujte prosím, zda není nová verze tématu.
Výchozí motiv byl aktivován automaticky.'; $wb['stay_logged_in_txt'] = 'Zapamatovat si přihlášení'; $wb['lost_password_function_disabled_txt'] = 'The lost password function is not available for this user.'; -$wb['pw_reset_act'] = 'You have been sent an activation link. Please visit the link to confirm your password request.'; -$wb['pw_reset_act_mail_title'] = 'Confirm ISPConfig 3 Control panel password reset'; -$wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPConfig 3 control panel account password by visiting the following activation link: '; $wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; $wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; $wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; diff --git a/interface/web/mail/lib/lang/cz.lng b/interface/web/mail/lib/lang/cz.lng index d0f6157cb..6b9deb3a9 100644 --- a/interface/web/mail/lib/lang/cz.lng +++ b/interface/web/mail/lib/lang/cz.lng @@ -37,12 +37,12 @@ $wb['User / Domain'] = 'Uživatel / Doména'; $wb['Server Settings'] = 'Nastavení serveru'; $wb['Fetchmail'] = 'Externí získávání e-mailů'; $wb['Mailbox traffic'] = 'Přenesená data'; +$wb['Statistics'] = 'Statistiky'; $wb['Postfix Whitelist'] = 'Postfix bílá listina'; $wb['Postfix Blacklist'] = 'Postfix černá listina'; $wb['Content Filter'] = 'Obsahový filtr'; $wb['Global Filters'] = 'Globální filtry'; $wb['Domain Alias'] = 'Přezdívky e-mailových domén'; $wb['Relay Recipients'] = 'Relay adresáti'; -$wb['Statistics'] = 'Statistiky'; $wb['Mailbox quota'] = 'Kvóty pro e-mailové schránky'; ?> diff --git a/interface/web/monitor/lib/lang/cz.lng b/interface/web/monitor/lib/lang/cz.lng index dc3e3cb34..45faa6af2 100644 --- a/interface/web/monitor/lib/lang/cz.lng +++ b/interface/web/monitor/lib/lang/cz.lng @@ -10,6 +10,7 @@ $wb['Memory usage'] = 'Využití paměti'; $wb['no_data_serverload_txt'] = 'Nejsou k dispozici žádná data o zatížení serveru. Prosím zkuste to později znova.'; $wb['no_data_memusage_txt'] = 'Nejsou k dispozici žádná data o využití paměti. Prosím zkuste to později znova.'; $wb['no_data_diskusage_txt'] = 'Nejsou k dispozici žádná data o využití disku. Prosím zkuste to později znova.'; +$wb['no_data_database_size_txt'] = 'Nejsou k dispozici žádná data o využití databáze. Prosím zkuste to později znova'; $wb['no_data_cpuinfo_txt'] = 'Nejsou k dispozici žádná data o CPU. Prosím zkuste to později znova.'; $wb['no_data_services_txt'] = 'Nejsou k dispozici žádná data o službách. Prosím zkuste to později znova.'; $wb['no_data_updates_txt'] = 'Nejsou k dispozici žádná data o aktualizacích. Prosím zkuste to později znova.'; @@ -45,6 +46,10 @@ $wb['Show Clamav-Log'] = 'Zobrazit Clamav log'; $wb['Show ISPConfig-Log'] = 'Zobrazit ISPConfig log'; $wb['Show RKHunter-Log'] = 'Zobrazit RKHunter log'; $wb['Show Jobqueue'] = 'Zobrazit frontu úloh'; +$wb['Show fail2ban-Log'] = 'Zobrazit Fail2Ban Log'; +$wb['Show MongoDB-Log'] = 'Show MongoDB-Log'; +$wb['Show IPTables'] = 'Zobrazit IPTables pravidla'; +$wb['Show OpenVz VE BeanCounter'] = 'Zobrazit OpenVz VE BeanCounter'; $wb['monitor_general_serverstate_txt'] = 'Stav serveru'; $wb['monitor_general_systemstate_txt'] = 'Stav systému'; $wb['monitor_diskusage_filesystem_txt'] = 'Souborový systém'; @@ -54,6 +59,10 @@ $wb['monitor_diskusage_used_txt'] = 'Užito'; $wb['monitor_diskusage_available_txt'] = 'Volné'; $wb['monitor_diskusage_usage_txt'] = 'Užití%'; $wb['monitor_diskusage_mounted_txt'] = 'Připojeno na'; +$wb['monitor_database_name_txt'] = 'Databáze'; +$wb['monitor_database_size_txt'] = 'Velikost'; +$wb['monitor_database_client_txt'] = 'Klient'; +$wb['monitor_database_domain_txt'] = 'Doména'; $wb['monitor_logs_mail_txt'] = 'E-mail - Log'; $wb['monitor_logs_mailwarn_txt'] = 'E-mail - Varování - Log'; $wb['monitor_logs_mailerr_txt'] = 'E-mail - Chyby - Log'; @@ -62,6 +71,7 @@ $wb['monitor_logs_ispccron_txt'] = 'ISPConfig cron - Log'; $wb['monitor_logs_freshclam_txt'] = 'Freshclam - Log'; $wb['monitor_logs_clamav_txt'] = 'ClamAV - Log'; $wb['monitor_logs_ispc_txt'] = 'ISPConfig - Log'; +$wb['monitor_nosupportedraid1_txt'] = 'V současné době, podporujeme nástroje mdadm nebo MPT-stav pro sledování sofwarových RAID polí.
Nemůžeme najít žádné z nich na serveru.

To znamená, že nemůžeme monitorovat váš RAID.'; $wb['monitor_norkhunter_txt'] = 'RKHunter není nainstalován, proto zde nejsou žádna data'; $wb['monitor_serverstate_server_txt'] = 'Server'; $wb['monitor_serverstate_kernel_txt'] = 'Kernel'; @@ -115,6 +125,11 @@ $wb['monitor_serverstate_syslogunknown_txt'] = 'Systémový log: ???'; $wb['monitor_serverstate_updatesok_txt'] = 'Systém je aktuální.'; $wb['monitor_serverstate_updatesneeded_txt'] = 'Jedna nebo více komponent potřebují zaktualizovat'; $wb['monitor_serverstate_updatesunknown_txt'] = 'Systémová aktualizace: ???'; +$wb['monitor_serverstate_beancounterok_txt'] = 'Soubor čítačů (limitů) je v pořádku'; +$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are vew failure in the beancounter'; +$wb['monitor_serverstate_beancounterwarning_txt'] = 'Některé čítače (limity) vykazují selhání.'; +$wb['monitor_serverstate_beancountercritical_txt'] = 'Existuje mnoho selhání čítačů (limitů)'; +$wb['monitor_serverstate_beancountererror_txt'] = 'Existuje příliš mnoho selhání čítačů (limitů)'; $wb['monitor_services_online_txt'] = 'Běží'; $wb['monitor_services_offline_txt'] = 'Neběží'; $wb['monitor_services_web_txt'] = 'Web-Server:'; @@ -123,6 +138,7 @@ $wb['monitor_services_smtp_txt'] = 'SMTP-Server:'; $wb['monitor_services_pop_txt'] = 'POP3-Server:'; $wb['monitor_services_imap_txt'] = 'IMAP-Server:'; $wb['monitor_services_mydns_txt'] = 'DNS-Server:'; +$wb['monitor_services_mongodb_txt'] = 'MongoDB-Server:'; $wb['monitor_services_mysql_txt'] = 'mySQL-Server:'; $wb['monitor_settings_datafromdate_txt'] = 'Data z: '; $wb['monitor_settings_datetimeformat_txt'] = 'Y-d-m H:i'; @@ -134,31 +150,15 @@ $wb['monitor_title_mailq_txt'] = 'E-mailová fronta'; $wb['monitor_title_raidstate_txt'] = 'Stav pole RAID'; $wb['monitor_title_rkhunterlog_txt'] = 'RKHunter log'; $wb['monitor_title_fail2ban_txt'] = 'Fail2Ban log'; -$wb['monitor_updates_nosupport_txt'] = 'Vaše distribuce nepodporuje toto monitorování'; -$wb['monitor_nosupportedraid1_txt'] = 'V současné době, podporujeme nástroje mdadm nebo MPT-stav pro sledování sofwarových RAID polí.
Nemůžeme najít žádné z nich na serveru.

To znamená, že nemůžeme monitorovat váš RAID.'; -$wb['monitor_serverstate_beancounterok_txt'] = 'Soubor čítačů (limitů) je v pořádku'; -$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are vew failure in the beancounter'; -$wb['monitor_serverstate_beancounterwarning_txt'] = 'Některé čítače (limity) vykazují selhání.'; -$wb['monitor_serverstate_beancountercritical_txt'] = 'Existuje mnoho selhání čítačů (limitů)'; -$wb['monitor_serverstate_beancountererror_txt'] = 'Existuje příliš mnoho selhání čítačů (limitů)'; +$wb['monitor_title_mongodb_txt'] = 'MongoDB Log'; +$wb['monitor_title_iptables_txt'] = 'IPTables Pravidla'; $wb['monitor_title_beancounter_txt'] = 'OpenVz VE čítače (limity)'; +$wb['monitor_updates_nosupport_txt'] = 'Vaše distribuce nepodporuje toto monitorování'; $wb['monitor_beancounter_nosupport_txt'] = 'Tento server nemá nainstalován VE OpenVZ a proto nemá beancounter informace'; -$wb['monitor_title_iptables_txt'] = 'IPTables Pravidla'; -$wb['Show fail2ban-Log'] = 'Zobrazit Fail2Ban Log'; -$wb['Show IPTables'] = 'Zobrazit IPTables pravidla'; -$wb['Show OpenVz VE BeanCounter'] = 'Zobrazit OpenVz VE BeanCounter'; $wb['Show Monit'] = 'Zobrazit Monit'; $wb['no_monit_url_defined_txt'] = 'Monit URL adresa není nastavena.'; $wb['no_permissions_to_view_monit_txt'] = 'You are not allowed to access Monit.'; $wb['Show Munin'] = 'Zobrazit Munin'; $wb['no_munin_url_defined_txt'] = 'Munin URL adresa není nastavena.'; $wb['no_permissions_to_view_munin_txt'] = 'You are not allowed to access Munin.'; -$wb['no_data_database_size_txt'] = 'No data about the database usage available at the moment. Please check again later.'; -$wb['Show MongoDB-Log'] = 'Show MongoDB-Log'; -$wb['monitor_database_name_txt'] = 'Databáze'; -$wb['monitor_database_size_txt'] = 'Velikost'; -$wb['monitor_database_client_txt'] = 'Klient'; -$wb['monitor_database_domain_txt'] = 'Doména'; -$wb['monitor_services_mongodb_txt'] = 'MongoDB-Server:'; -$wb['monitor_title_mongodb_txt'] = 'MongoDB Log'; ?> diff --git a/interface/web/sites/lib/lang/cz.lng b/interface/web/sites/lib/lang/cz.lng index 4c16438e3..3a05d956d 100644 --- a/interface/web/sites/lib/lang/cz.lng +++ b/interface/web/sites/lib/lang/cz.lng @@ -4,6 +4,7 @@ $wb['Website'] = 'Webové stránky'; $wb['Subdomain'] = 'Subdomény pro webové stránky'; $wb['Aliasdomain'] = 'Přezdívky domén webové stránky'; $wb['Database'] = 'Databáze'; +$wb['Database User'] = 'Uživatelé databáze'; $wb['Web Access'] = 'Webové přístupy'; $wb['FTP-User'] = 'FTP uživatelé'; $wb['Webdav-User'] = 'WebDAV uživatelé'; @@ -25,11 +26,10 @@ $wb['Domain'] = 'Doména'; $wb['Redirect'] = 'Přesměrování'; $wb['SSL'] = 'SSL'; $wb['Sites'] = 'Stránky'; -$wb['Database User'] = 'Uživatelé databáze'; $wb['APS Installer'] = 'APS instalátor'; $wb['Available packages'] = 'Dostupné balíčky'; $wb['Installed packages'] = 'Nainstalované balíčky'; $wb['Update Packagelist'] = 'Aktualizace seznamu balíčků'; $wb['Subdomain (Vhost)'] = 'Subdoména (Vhost)'; -$wb['error_proxy_requires_url'] = 'Redirect Type \\"proxy\\" requires a URL as the redirect path.'; +$wb['error_proxy_requires_url'] = 'Redirect Type "proxy" requires a URL as the redirect path.'; ?> diff --git a/interface/web/tools/lib/lang/cz.lng b/interface/web/tools/lib/lang/cz.lng index 66bcaf49a..9e790f35e 100644 --- a/interface/web/tools/lib/lang/cz.lng +++ b/interface/web/tools/lib/lang/cz.lng @@ -2,12 +2,12 @@ $wb['User Settings'] = 'Uživatelská nastavení'; $wb['Settings'] = 'Nastavení'; $wb['ISPConfig Tools'] = 'ISPConfig nástroje'; +$wb['Interface'] = 'Rozhraní'; $wb['Password and Language'] = 'Heslo a jazyk'; $wb['ispconfig_tools_note'] = 'Tento modul umožňuje změnit heslo a jazyk pro zahájení resynchronizace DNS záznamů.'; -$wb['Resync'] = 'Resynchronizace'; $wb['Sync Tools'] = 'Synchronizační nástroje'; +$wb['Resync'] = 'Resynchronizace'; $wb['Import'] = 'Importovat'; $wb['ISPConfig 3 mail'] = 'ISPConfig 3 vzdalený e-mail server'; $wb['PDNS Tupa'] = 'PowerDNS Tupa'; -$wb['Interface'] = 'Rozhraní'; ?> -- GitLab From e661a603d8696abf4e0d18a8027a6a78d141cb28 Mon Sep 17 00:00:00 2001 From: Vojtech Myslivec Date: Tue, 17 Jul 2018 23:41:18 +0200 Subject: [PATCH 062/310] Add missing cz translations --- interface/lib/lang/cz.lng | 15 +++++++++------ interface/web/client/lib/lang/cz.lng | 4 ++-- interface/web/dashboard/lib/lang/cz.lng | 2 +- interface/web/login/lib/lang/cz.lng | 16 ++++++++-------- interface/web/monitor/lib/lang/cz.lng | 10 +++++++--- interface/web/monitor/lib/lang/en.lng | 2 +- interface/web/sites/lib/lang/cz.lng | 2 +- interface/web/vm/lib/lang/cz.lng | 2 +- 8 files changed, 30 insertions(+), 23 deletions(-) diff --git a/interface/lib/lang/cz.lng b/interface/lib/lang/cz.lng index 28ee941a8..edd7a720a 100644 --- a/interface/lib/lang/cz.lng +++ b/interface/lib/lang/cz.lng @@ -30,7 +30,7 @@ $wb['btn_cancel_txt'] = 'Zrušit'; $wb['top_menu_system'] = 'Systém'; $wb['top_menu_client'] = 'Klienti'; $wb['top_menu_email'] = 'E-mail'; -$wb['top_menu_monitor'] = 'Monitor'; +$wb['top_menu_monitor'] = 'Monitoring'; $wb['top_menu_sites'] = 'Stránky'; $wb['top_menu_dns'] = 'DNS'; $wb['top_menu_tools'] = 'Nástroje'; @@ -122,6 +122,9 @@ $wb['datalog_status_d_mail_get'] = 'Odstranění účtu pro získávání extern $wb['datalog_status_i_mail_mailinglist'] = 'Vytvoření e-mailové konference (mailinglist)'; $wb['datalog_status_u_mail_mailinglist'] = 'Aktualizace nastavení e-mailové konference (mailinglist)'; $wb['datalog_status_d_mail_mailinglist'] = 'Odstranění e-mailové konference (mailinglist)'; +$wb['datalog_status_i_mail_ml_membership'] = 'Vytvoření člena konference'; +$wb['datalog_status_u_mail_ml_membership'] = 'Aktualizace člena konference'; +$wb['datalog_status_d_mail_ml_membership'] = 'Odstranění člena konference'; $wb['datalog_status_i_shell_user'] = 'Vytvoření shell uživatele'; $wb['datalog_status_u_shell_user'] = 'Aktualizace nastavení shell uživatele'; $wb['datalog_status_d_shell_user'] = 'Odstranění shell uživatele'; @@ -137,7 +140,7 @@ $wb['datalog_status_d_xmpp_domain'] = 'Smazat XMPP doménu'; $wb['datalog_status_i_xmpp_user'] = 'Vytvořit XMPP uživatele'; $wb['datalog_status_u_xmpp_user'] = 'Aktualizovat XMPP uživatele'; $wb['datalog_status_d_xmpp_user'] = 'Smazat XMPP uživatele'; -$wb['err_csrf_attempt_blocked'] = 'CSRF attempt blocked.'; +$wb['err_csrf_attempt_blocked'] = 'Pokus o CSRF zablokován.'; $wb['login_as_txt'] = 'Přihlašte se jako'; $wb['no_domain_perm'] = 'Nemáte oprávnění pro tuto doménu.'; $wb['no_destination_perm'] = 'Nemáte oprávnění pro tuto destinaci.'; @@ -155,9 +158,9 @@ $wb['strength_4'] = 'Silná'; $wb['strength_5'] = 'Velmi silná'; $wb['weak_password_txt'] = 'Zvolené heslo neodpovídá požadavkům zásad pro tvorbu hesel. Heslo musí být alespoň {chars} znaků dlouhé a mající sílu \\"{strength}\\".'; $wb['weak_password_length_txt'] = 'Zvolené heslo neodpovídá požadavkům zásad pro tvorbu hesel. Heslo musí být alespoň {chars} znaků dlouhé.'; -$wb['security_check1_txt'] = 'Check for security permission:'; -$wb['security_check2_txt'] = 'failed.'; +$wb['security_check1_txt'] = 'Ověření bezpečnostních oprávnění:'; +$wb['security_check2_txt'] = 'selhalo.'; $wb['select_directive_snippet_txt'] = 'Šablony částí prog. kódu'; -$wb['select_master_directive_snippet_txt'] = 'Master Directive Snippets'; -$wb['datalog_changes_close_txt'] = 'Close'; +$wb['select_master_directive_snippet_txt'] = 'Hlavní části prog. kódu'; +$wb['datalog_changes_close_txt'] = 'Zavřít'; ?> diff --git a/interface/web/client/lib/lang/cz.lng b/interface/web/client/lib/lang/cz.lng index 147d1fd9d..dabaf58eb 100644 --- a/interface/web/client/lib/lang/cz.lng +++ b/interface/web/client/lib/lang/cz.lng @@ -19,8 +19,8 @@ $wb['Edit Client Circle'] = 'Upravit skupinu klientů'; $wb['Domains'] = 'Domény'; $wb['domain_txt'] = 'Doména'; $wb['client_txt'] = 'Klient'; -$wb['error_domain_in dnsuse'] = 'This domain cannot be deleted, because it is in use as dns zone'; -$wb['error_domain_in dnsslaveuse'] = 'This domain cannot be deleted, because it is in use as secondary dns zone'; +$wb['error_domain_in dnsuse'] = 'Tato doména nemůže být odstraněna, jelikož je použitá jako DNS zóna'; +$wb['error_domain_in dnsslaveuse'] = 'Tato doména nemůže být odstraněna, jelikož je použitá jako sekundární DNS zóna'; $wb['error_domain_in mailuse'] = 'Tato doména nelze odstranit, protože je v používána jako poštovní doména'; $wb['error_domain_in webuse'] = 'Tato doména nelze odstranit, protože je v používána jako webová doména'; $wb['error_client_can_not_add_domain'] = 'Nemůžete přidat novou doménu'; diff --git a/interface/web/dashboard/lib/lang/cz.lng b/interface/web/dashboard/lib/lang/cz.lng index 16ed927c3..5a894381d 100644 --- a/interface/web/dashboard/lib/lang/cz.lng +++ b/interface/web/dashboard/lib/lang/cz.lng @@ -1,5 +1,5 @@ diff --git a/interface/web/login/lib/lang/cz.lng b/interface/web/login/lib/lang/cz.lng index 7e864ecfb..aa6c9ad1c 100644 --- a/interface/web/login/lib/lang/cz.lng +++ b/interface/web/login/lib/lang/cz.lng @@ -5,13 +5,13 @@ $wb['error_user_blocked'] = 'Uživatel je blokován.'; $wb['error_user_too_many_logins'] = 'Příliš mnoho nesprávných přihlášení, zkuste to za 15 minut znovu'; $wb['pass_reset_txt'] = 'Bude Vám vygenerováno a zasláno nové heslo na e-mail, pokud Vaše adresa zadaná níže odpovídá adrese ve Vašem klientském nastavení.'; $wb['pw_reset'] = 'Heslo bylo resetováno a zasláno na Váš e-mail.'; -$wb['pw_reset_act'] = 'You have been sent an activation link. Please visit the link to confirm your password request.'; +$wb['pw_reset_act'] = 'Byl vám zaslán aktivační odkaz. Nádledujte, prosím, odkaz pro dokončení resetování hesla.'; $wb['pw_error'] = 'Uživatelské jméno nebo e-mail nesouhlasí.'; $wb['pw_error_noinput'] = 'Prosím zadejte uživatelské jméno a e-mail.'; $wb['pw_reset_mail_msg'] = 'Vaše heslo do ISPConfigu bylo resetováno. Nové heslo je: '; -$wb['pw_reset_mail_title'] = 'Heslo do ISPConfigu bylo resetováno.'; -$wb['pw_reset_act_mail_title'] = 'Confirm ISPConfig 3 Control panel password reset'; -$wb['pw_reset_act_mail_msg'] = 'Please confirm that your want to reset your ISPConfig 3 control panel account password by visiting the following activation link: '; +$wb['pw_reset_mail_title'] = 'Heslo do ISPConfigu bylo resetováno'; +$wb['pw_reset_act_mail_title'] = 'Potvrďte resetování ISPConfig hesla'; +$wb['pw_reset_act_mail_msg'] = 'Potvrďte, prosím, žádost o resetování ISPConfig hesla kliknutím na následující aktivační odkaz: '; $wb['user_regex_error'] = 'Uživatelské jméno obsahuje nepovolené znaky nebo je delší než 64 znaků.'; $wb['pw_error_length'] = 'Heslo je delší než 64 znaků.'; $wb['email_error'] = 'E-mail obsahuje nepovolené znaky nebo má neplatný formát.'; @@ -27,8 +27,8 @@ $wb['back_txt'] = 'Zpět'; $wb['error_maintenance_mode'] = 'V současné době probíhá údržba systému ISPConfig. Přihlášení zkuste prosím později. Děkujeme Vám za trpělivost.'; $wb['theme_not_compatible'] = 'Zvolené téma není kompatibilní s aktuální verzí ISPConfig. Zkontrolujte prosím, zda není nová verze tématu.
Výchozí motiv byl aktivován automaticky.'; $wb['stay_logged_in_txt'] = 'Zapamatovat si přihlášení'; -$wb['lost_password_function_disabled_txt'] = 'The lost password function is not available for this user.'; -$wb['lost_password_function_wait_txt'] = 'You cannot request a new password, yet. Please wait a few minutes.'; -$wb['lost_password_function_expired_txt'] = 'This activation link has expired. Please request a new one.'; -$wb['lost_password_function_denied_txt'] = 'This activation link is not valid.'; +$wb['lost_password_function_disabled_txt'] = 'Resetování hesla není pro tento účet možné.'; +$wb['lost_password_function_wait_txt'] = 'Nyní nemůžete požádat o resetování hesla. Prosím, vyčkejte několik minut.'; +$wb['lost_password_function_expired_txt'] = 'Tento aktivační odkaz již vypršel. Zažádejte, prosím o nový.'; +$wb['lost_password_function_denied_txt'] = 'Tento aktivační odkaz není platný.'; ?> diff --git a/interface/web/monitor/lib/lang/cz.lng b/interface/web/monitor/lib/lang/cz.lng index 45faa6af2..19a924b6f 100644 --- a/interface/web/monitor/lib/lang/cz.lng +++ b/interface/web/monitor/lib/lang/cz.lng @@ -126,7 +126,7 @@ $wb['monitor_serverstate_updatesok_txt'] = 'Systém je aktuální.'; $wb['monitor_serverstate_updatesneeded_txt'] = 'Jedna nebo více komponent potřebují zaktualizovat'; $wb['monitor_serverstate_updatesunknown_txt'] = 'Systémová aktualizace: ???'; $wb['monitor_serverstate_beancounterok_txt'] = 'Soubor čítačů (limitů) je v pořádku'; -$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are vew failure in the beancounter'; +$wb['monitor_serverstate_beancounterinfo_txt'] = 'Existuje několik málo selhání čítačů (limitů)'; $wb['monitor_serverstate_beancounterwarning_txt'] = 'Některé čítače (limity) vykazují selhání.'; $wb['monitor_serverstate_beancountercritical_txt'] = 'Existuje mnoho selhání čítačů (limitů)'; $wb['monitor_serverstate_beancountererror_txt'] = 'Existuje příliš mnoho selhání čítačů (limitů)'; @@ -157,8 +157,12 @@ $wb['monitor_updates_nosupport_txt'] = 'Vaše distribuce nepodporuje toto monito $wb['monitor_beancounter_nosupport_txt'] = 'Tento server nemá nainstalován VE OpenVZ a proto nemá beancounter informace'; $wb['Show Monit'] = 'Zobrazit Monit'; $wb['no_monit_url_defined_txt'] = 'Monit URL adresa není nastavena.'; -$wb['no_permissions_to_view_monit_txt'] = 'You are not allowed to access Monit.'; +$wb['no_permissions_to_view_monit_txt'] = 'Nemáte oprávnění přistoupit k Monit.'; $wb['Show Munin'] = 'Zobrazit Munin'; $wb['no_munin_url_defined_txt'] = 'Munin URL adresa není nastavena.'; -$wb['no_permissions_to_view_munin_txt'] = 'You are not allowed to access Munin.'; +$wb['no_permissions_to_view_munin_txt'] = 'Nemáte oprávnění přistoupit k Munin.'; +$wb['Show Nagios/Check_MK'] = 'Zobrazit Nagios'; +$wb['no_nagios_url_defined_txt'] = 'Nejsou definovány žádné Nagios URL.'; +$wb['no_permissions_to_view_nagios_txt'] = 'Nejste oprávnění přistoupit k Nagios/Check_MK.'; +$wb['go_to_nagios_txt'] = 'Otevřít nové okno s tímto pohledem'; ?> diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index 38a8c0734..3721f692e 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -126,7 +126,7 @@ $wb['monitor_serverstate_updatesok_txt'] = 'Your system is up to date.'; $wb['monitor_serverstate_updatesneeded_txt'] = 'One or more components needs an update'; $wb['monitor_serverstate_updatesunknown_txt'] = 'System Update: ???'; $wb['monitor_serverstate_beancounterok_txt'] = 'The beancounter is ok'; -$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are vew failure in the beancounter'; +$wb['monitor_serverstate_beancounterinfo_txt'] = 'There are few failure in the beancounter'; $wb['monitor_serverstate_beancounterwarning_txt'] = 'There are some failure in the beancounter'; $wb['monitor_serverstate_beancountercritical_txt'] = 'There are many failure in the beancounter'; $wb['monitor_serverstate_beancountererror_txt'] = 'There are too much failure in the beancounter'; diff --git a/interface/web/sites/lib/lang/cz.lng b/interface/web/sites/lib/lang/cz.lng index 3a05d956d..9cf64fca7 100644 --- a/interface/web/sites/lib/lang/cz.lng +++ b/interface/web/sites/lib/lang/cz.lng @@ -31,5 +31,5 @@ $wb['Available packages'] = 'Dostupné balíčky'; $wb['Installed packages'] = 'Nainstalované balíčky'; $wb['Update Packagelist'] = 'Aktualizace seznamu balíčků'; $wb['Subdomain (Vhost)'] = 'Subdoména (Vhost)'; -$wb['error_proxy_requires_url'] = 'Redirect Type "proxy" requires a URL as the redirect path.'; +$wb['error_proxy_requires_url'] = 'Přesměrování typu "proxy" potřebuje v cestě přesměrování URL.'; ?> diff --git a/interface/web/vm/lib/lang/cz.lng b/interface/web/vm/lib/lang/cz.lng index 556a59356..37034b56f 100644 --- a/interface/web/vm/lib/lang/cz.lng +++ b/interface/web/vm/lib/lang/cz.lng @@ -1,5 +1,5 @@ Date: Wed, 25 Jul 2018 15:21:49 +0200 Subject: [PATCH 063/310] Add option to "name" default php-version for websites per server (#5089) --- install/tpl/server.ini.master | 1 + interface/web/admin/form/server_config.tform.php | 10 ++++++++++ interface/web/admin/lib/lang/ar_server_config.lng | 2 ++ interface/web/admin/lib/lang/bg_server_config.lng | 2 ++ interface/web/admin/lib/lang/br_server_config.lng | 1 + interface/web/admin/lib/lang/ca_server_config.lng | 2 ++ interface/web/admin/lib/lang/cz_server_config.lng | 2 ++ interface/web/admin/lib/lang/de_server_config.lng | 2 ++ interface/web/admin/lib/lang/dk_server_config.lng | 2 ++ interface/web/admin/lib/lang/el_server_config.lng | 2 ++ interface/web/admin/lib/lang/en_server_config.lng | 2 ++ interface/web/admin/lib/lang/es_server_config.lng | 2 ++ interface/web/admin/lib/lang/fi_server_config.lng | 2 ++ interface/web/admin/lib/lang/fr_server_config.lng | 2 ++ interface/web/admin/lib/lang/hr_server_config.lng | 2 ++ interface/web/admin/lib/lang/hu_server_config.lng | 2 ++ interface/web/admin/lib/lang/id_server_config.lng | 2 ++ interface/web/admin/lib/lang/it_server_config.lng | 2 ++ interface/web/admin/lib/lang/ja_server_config.lng | 2 ++ interface/web/admin/lib/lang/nl_server_config.lng | 2 ++ interface/web/admin/lib/lang/pl_server_config.lng | 2 ++ interface/web/admin/lib/lang/pt_server_config.lng | 2 ++ interface/web/admin/lib/lang/ro_server_config.lng | 2 ++ interface/web/admin/lib/lang/ru_server_config.lng | 2 ++ interface/web/admin/lib/lang/se_server_config.lng | 2 ++ interface/web/admin/lib/lang/sk_server_config.lng | 2 ++ interface/web/admin/lib/lang/tr_server_config.lng | 2 ++ .../web/admin/templates/server_config_web_edit.htm | 5 ++++- interface/web/sites/ajax_get_json.php | 7 +++++++ .../web/sites/templates/web_vhost_domain_edit.htm | 6 +++--- interface/web/sites/web_vhost_domain_edit.php | 9 +++++---- 31 files changed, 79 insertions(+), 8 deletions(-) diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 39c24bc70..079d63448 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -102,6 +102,7 @@ php_fpm_ini_path=/etc/php5/fpm/php.ini php_fpm_pool_dir=/etc/php5/fpm/pool.d php_fpm_start_port=9010 php_fpm_socket_dir=/var/lib/php5-fpm +php_default_name=Default set_folder_permissions_on_update=n add_web_users_to_sshusers_group=y connect_userid_to_webid=n diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index f939c97b3..a39cc3b99 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1094,6 +1094,16 @@ $form["tabs"]['web'] = array( 'width' => '40', 'maxlength' => '255' ), + 'php_default_name' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => 'Default', + 'validators' => array( 0 => array('type' => 'NOTEMPTY', + 'errmsg' => 'php_default_name_error_empty'), + ), + 'width' => '40', + 'maxlength' => '255' + ), 'php_fpm_init_script' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng index 683efce31..55d4c4ffc 100644 --- a/interface/web/admin/lib/lang/ar_server_config.lng +++ b/interface/web/admin/lib/lang/ar_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng index 277cee8b9..74e0405cd 100644 --- a/interface/web/admin/lib/lang/bg_server_config.lng +++ b/interface/web/admin/lib/lang/bg_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng index a46db9f1c..70512ea93 100644 --- a/interface/web/admin/lib/lang/br_server_config.lng +++ b/interface/web/admin/lib/lang/br_server_config.lng @@ -291,4 +291,5 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; ?> diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng index 3d8491cf9..fbd3e1ea0 100644 --- a/interface/web/admin/lib/lang/ca_server_config.lng +++ b/interface/web/admin/lib/lang/ca_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng index 204828d7a..54acda96f 100644 --- a/interface/web/admin/lib/lang/cz_server_config.lng +++ b/interface/web/admin/lib/lang/cz_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index 6ef8c90c8..f81bb279b 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Beschreibung Standard PHP'; +$wb['php_default_name_error_empty'] = 'Beschreibung Standard PHP ist leer.'; ?> diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng index fcf4d2007..61139aa54 100644 --- a/interface/web/admin/lib/lang/dk_server_config.lng +++ b/interface/web/admin/lib/lang/dk_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng index f7c475c57..38600769c 100644 --- a/interface/web/admin/lib/lang/el_server_config.lng +++ b/interface/web/admin/lib/lang/el_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index 5d087356e..bcbf4ceea 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -292,4 +292,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng index aaee15ec0..cb0fbf121 100755 --- a/interface/web/admin/lib/lang/es_server_config.lng +++ b/interface/web/admin/lib/lang/es_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng index 99c1524dc..6e08e9841 100755 --- a/interface/web/admin/lib/lang/fi_server_config.lng +++ b/interface/web/admin/lib/lang/fi_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng index 43e67450e..2045dbb8b 100644 --- a/interface/web/admin/lib/lang/fr_server_config.lng +++ b/interface/web/admin/lib/lang/fr_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng index 797f0eb71..99d69fec0 100644 --- a/interface/web/admin/lib/lang/hr_server_config.lng +++ b/interface/web/admin/lib/lang/hr_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng index 04370d1b4..24d2fcb05 100644 --- a/interface/web/admin/lib/lang/hu_server_config.lng +++ b/interface/web/admin/lib/lang/hu_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng index 2993c5c59..8abd5d6be 100644 --- a/interface/web/admin/lib/lang/id_server_config.lng +++ b/interface/web/admin/lib/lang/id_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng index cce33cf7e..a87f3129d 100644 --- a/interface/web/admin/lib/lang/it_server_config.lng +++ b/interface/web/admin/lib/lang/it_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng index 353aaa809..f915e8607 100644 --- a/interface/web/admin/lib/lang/ja_server_config.lng +++ b/interface/web/admin/lib/lang/ja_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng index b1320fc9a..c8b320b8c 100644 --- a/interface/web/admin/lib/lang/nl_server_config.lng +++ b/interface/web/admin/lib/lang/nl_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng index e2288f905..6f00d524e 100644 --- a/interface/web/admin/lib/lang/pl_server_config.lng +++ b/interface/web/admin/lib/lang/pl_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng index 9d7fa04cd..62a8a3401 100644 --- a/interface/web/admin/lib/lang/pt_server_config.lng +++ b/interface/web/admin/lib/lang/pt_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng index e7787e186..f7c4c5703 100644 --- a/interface/web/admin/lib/lang/ro_server_config.lng +++ b/interface/web/admin/lib/lang/ro_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng index eb004bcfc..a95d6e70c 100644 --- a/interface/web/admin/lib/lang/ru_server_config.lng +++ b/interface/web/admin/lib/lang/ru_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng index a38c3e6d1..97d3c9f80 100644 --- a/interface/web/admin/lib/lang/se_server_config.lng +++ b/interface/web/admin/lib/lang/se_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng index f20c681e2..cfc0b3ab7 100644 --- a/interface/web/admin/lib/lang/sk_server_config.lng +++ b/interface/web/admin/lib/lang/sk_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng index 59a11a28c..ccf1ed5b9 100644 --- a/interface/web/admin/lib/lang/tr_server_config.lng +++ b/interface/web/admin/lib/lang/tr_server_config.lng @@ -291,4 +291,6 @@ $wb['logging_txt'] = 'Store website access and error logs'; $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites. For Apache, access and error log can be anonymized. For nginx, only the access log is anonymized, the error log will contain IP addresses.'; $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; +$wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; ?> diff --git a/interface/web/admin/templates/server_config_web_edit.htm b/interface/web/admin/templates/server_config_web_edit.htm index c0f148271..bb61d866c 100644 --- a/interface/web/admin/templates/server_config_web_edit.htm +++ b/interface/web/admin/templates/server_config_web_edit.htm @@ -256,7 +256,10 @@
-
+
+ +
+
diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php index d79eba239..9e530514c 100644 --- a/interface/web/sites/ajax_get_json.php +++ b/interface/web/sites/ajax_get_json.php @@ -97,6 +97,8 @@ if($type == 'getphpfastcgi'){ } elseif($php_type == 'fast-cgi'){ $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND active = 'y'".$sql_where, $server_id); } + $php_records[]=array('name' => $web_config['php_default_name']); + uasort($php_records, 'sort_php'); $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { @@ -243,4 +245,9 @@ if($type == 'getclientssldata'){ header('Content-type: application/json'); echo $json; + +function sort_php($a, $b) { + return strcmp($a['name'], $b['name']); +} + ?> diff --git a/interface/web/sites/templates/web_vhost_domain_edit.htm b/interface/web/sites/templates/web_vhost_domain_edit.htm index 86fd3b294..149d43088 100644 --- a/interface/web/sites/templates/web_vhost_domain_edit.htm +++ b/interface/web/sites/templates/web_vhost_domain_edit.htm @@ -444,8 +444,8 @@ function reloadFastcgiPHPVersions(noFormChange) { jQuery.getJSON('sites/ajax_get_json.php'+ '?' + Math.round(new Date().getTime()), {server_id : serverId, php_type : jQuery('#php').val(), type : "getphpfastcgi", client_group_id : clientGroupId}, function(data) { - var options = ''; - //var options = ''; + //var options = ''; + var options = ''; var phpfastcgiselected = ''; $.each(data, function(key, val) { @@ -468,7 +468,7 @@ phpfastcgiselected = ''; - options += ''; + //options += ''; $('#fastcgi_php_version').html(options).change(); if(noFormChange) ISPConfig.resetFormChanged(); }); diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 1fa9a6a5a..4f2206c67 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -239,6 +239,7 @@ class page_action extends tform_actions { //PHP Version Selection (FastCGI) $server_type = 'apache'; +//print_r($web_config[$server_id]);exit; if(!empty($web_config[$server_id]['server_type'])) $server_type = $web_config[$server_id]['server_type']; if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; @@ -257,7 +258,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?) AND active = 'y'", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ @@ -404,7 +405,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?) AND active = 'y'", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ @@ -624,7 +625,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND active = 'y'", $parent_domain['server_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ @@ -952,7 +953,7 @@ class page_action extends tform_actions { function onSubmit() { global $app, $conf; - +//print_r($this->dataRecord);exit; // Set a few fixed values $this->dataRecord["vhost_type"] = 'name'; if($this->_vhostdomain_type == 'domain') { -- GitLab From ff16ebc265c0c59e6966f5323e216dd257543d92 Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 15:25:12 +0200 Subject: [PATCH 064/310] clean-up code --- interface/web/sites/web_vhost_domain_edit.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 4f2206c67..029df1cbe 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -239,7 +239,6 @@ class page_action extends tform_actions { //PHP Version Selection (FastCGI) $server_type = 'apache'; -//print_r($web_config[$server_id]);exit; if(!empty($web_config[$server_id]['server_type'])) $server_type = $web_config[$server_id]['server_type']; if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; @@ -953,7 +952,6 @@ class page_action extends tform_actions { function onSubmit() { global $app, $conf; -//print_r($this->dataRecord);exit; // Set a few fixed values $this->dataRecord["vhost_type"] = 'name'; if($this->_vhostdomain_type == 'domain') { -- GitLab From 840f3954b51c9c494b6dea661b2d20ad92460e89 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 25 Jul 2018 15:32:28 +0200 Subject: [PATCH 065/310] - fixed module button display on dashlet if multiple modules have same order setting --- interface/web/dashboard/dashlets/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/dashboard/dashlets/modules.php b/interface/web/dashboard/dashlets/modules.php index da1eb0be7..5c1f15149 100644 --- a/interface/web/dashboard/dashlets/modules.php +++ b/interface/web/dashboard/dashlets/modules.php @@ -47,7 +47,7 @@ class dashlet_modules { } else { if(strlen($module_title) > 8) $module_title = substr($module_title, 0, 7).'..'; } - $mod[$module['order']] = array( 'modules_title' => $module_title, + $mod[$module['order'].'-'.$module['name']] = array( 'modules_title' => $module_title, 'modules_startpage' => $module['startpage'], 'modules_name' => $module['name']); } -- GitLab From c97bed4466ec457c9b9bb80f50b73fb3765aafea Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 16:59:12 +0200 Subject: [PATCH 066/310] show active for additional php-versions (#5090) --- install/dist/lib/fedora.lib.php | 21 +++++++++++++++++++ install/dist/lib/gentoo.lib.php | 21 +++++++++++++++++++ install/dist/lib/opensuse.lib.php | 21 +++++++++++++++++++ install/tpl/debian_postfix.conf.master | 6 ++++++ install/tpl/fedora_postfix.conf.master | 6 ++++++ install/tpl/gentoo_postfix.conf.master | 6 ++++++ install/tpl/opensuse_postfix.conf.master | 6 ++++++ install/tpl/server.ini.master | 2 +- .../web/admin/lib/lang/de_server_php_list.lng | 1 + .../web/admin/lib/lang/en_server_php_list.lng | 1 + interface/web/admin/list/server_php.list.php | 9 ++++++++ .../web/admin/templates/server_php_list.htm | 5 ++++- 12 files changed, 103 insertions(+), 2 deletions(-) diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index f1d57f9c8..8cf13ff19 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -53,6 +53,14 @@ class installer_dist extends installer_base { $cf = $conf['postfix']; $config_dir = $cf['config_dir']; + exec('postconf mail_version', $ret); + $postfix_version=str_replace('mail_version = ', '', $ret[0]); + unset($ret); + exec('openssl version', $ret); + $openssl_version=$ret[0]; + unset($ret); + $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; + if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -163,6 +171,19 @@ class installer_dist extends installer_base { '{greylisting}' => $greylisting, '{reject_slm}' => $reject_sender_login_mismatch, ); + + //* If PFS is possible, configure it + if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); + if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); + if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', + '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); + } else { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => '', + '{smtpd_tls_dh1024_param_file}' => '')); + } $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/fedora_postfix.conf.master', 'tpl/fedora_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index af692b168..17c1797eb 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -54,6 +54,14 @@ class installer extends installer_base $cf = $conf['postfix']; $config_dir = $cf['config_dir']; + exec('postconf mail_version', $ret); + $postfix_version=str_replace('mail_version = ', '', $ret[0]); + unset($ret); + exec('openssl version', $ret); + $openssl_version=$ret[0]; + unset($ret); + $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; + if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -116,6 +124,19 @@ class installer extends installer_base '{reject_slm}' => $reject_sender_login_mismatch, ); + //* If PFS is possible, configure it + if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); + if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); + if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', + '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); + } else { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => '', + '{smtpd_tls_dh1024_param_file}' => '')); + } + $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_postfix.conf.master', 'tpl/gentoo_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); $postconf_commands = array_filter(explode("\n", $postconf_tpl)); // read and remove empty lines diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index b83b24dcf..99da9742e 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -53,6 +53,14 @@ class installer_dist extends installer_base { $cf = $conf['postfix']; $config_dir = $cf['config_dir']; + exec('postconf mail_version', $ret); + $postfix_version=str_replace('mail_version = ', '', $ret[0]); + unset($ret); + exec('openssl version', $ret); + $openssl_version=$ret[0]; + unset($ret); + $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; + if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -174,6 +182,19 @@ class installer_dist extends installer_base { '{greylisting}' => $greylisting, '{reject_slm}' => $reject_sender_login_mismatch, ); + + //* If PFS is possible, configure it + if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); + if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); + if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', + '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); + } else { + $postconf_placeholders = array_merge($postconf_placeholders, array( + '{smtpd_tls_dh512_param_file}' => '', + '{smtpd_tls_dh1024_param_file}' => '')); + } $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/opensuse_postfix.conf.master', 'tpl/opensuse_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index b7dbea630..82cd9a154 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -44,3 +44,9 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL +smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} +smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} +smtpd_tls_eecdh_grade = strong +tls_preempt_cipherlist = yes +smtp_tls_loglevel = 1 +smtpd_tls_loglevel = 1 diff --git a/install/tpl/fedora_postfix.conf.master b/install/tpl/fedora_postfix.conf.master index f06af8228..28a38994a 100644 --- a/install/tpl/fedora_postfix.conf.master +++ b/install/tpl/fedora_postfix.conf.master @@ -40,3 +40,9 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL +smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} +smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} +smtpd_tls_eecdh_grade = strong +tls_preempt_cipherlist = yes +smtp_tls_loglevel = 1 +smtpd_tls_loglevel = 1 diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index dc20e02c1..3c7015e50 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -39,3 +39,9 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL +smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} +smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} +smtpd_tls_eecdh_grade = strong +tls_preempt_cipherlist = yes +smtp_tls_loglevel = 1 +smtpd_tls_loglevel = 1 diff --git a/install/tpl/opensuse_postfix.conf.master b/install/tpl/opensuse_postfix.conf.master index 4192f988b..fb2e911b5 100644 --- a/install/tpl/opensuse_postfix.conf.master +++ b/install/tpl/opensuse_postfix.conf.master @@ -42,3 +42,9 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL +smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} +smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} +smtpd_tls_eecdh_grade = strong +tls_preempt_cipherlist = yes +smtp_tls_loglevel = 1 +smtpd_tls_loglevel = 1 diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 079d63448..f5dff7940 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -102,7 +102,7 @@ php_fpm_ini_path=/etc/php5/fpm/php.ini php_fpm_pool_dir=/etc/php5/fpm/pool.d php_fpm_start_port=9010 php_fpm_socket_dir=/var/lib/php5-fpm -php_default_name=Default +php_default_name=default set_folder_permissions_on_update=n add_web_users_to_sshusers_group=y connect_userid_to_webid=n diff --git a/interface/web/admin/lib/lang/de_server_php_list.lng b/interface/web/admin/lib/lang/de_server_php_list.lng index d775fc6c0..fe9a72ea1 100644 --- a/interface/web/admin/lib/lang/de_server_php_list.lng +++ b/interface/web/admin/lib/lang/de_server_php_list.lng @@ -4,4 +4,5 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Neue PHP Version hinzufügen'; $wb['client_id_txt'] = 'Kunde'; $wb['name_txt'] = 'PHP Name'; +$wb['active_txt'] = 'Aktiv'; ?> diff --git a/interface/web/admin/lib/lang/en_server_php_list.lng b/interface/web/admin/lib/lang/en_server_php_list.lng index b402fd1ed..62cbe6168 100644 --- a/interface/web/admin/lib/lang/en_server_php_list.lng +++ b/interface/web/admin/lib/lang/en_server_php_list.lng @@ -4,4 +4,5 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Add new PHP version'; $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; +$wb['active_txt'] = 'Active'; ?> diff --git a/interface/web/admin/list/server_php.list.php b/interface/web/admin/list/server_php.list.php index ee4ad1ab9..a4a38901a 100644 --- a/interface/web/admin/list/server_php.list.php +++ b/interface/web/admin/list/server_php.list.php @@ -44,6 +44,15 @@ $liste['auth'] = 'no'; * Suchfelder *****************************************************/ +$liste['item'][] = array( 'field' => 'active', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'width' => '', + 'value' => array('y' => $app->lng('yes_txt'), 'n' => $app->lng('no_txt'))); + $liste['item'][] = array( 'field' => 'server_id', 'datatype' => 'INTEGER', 'formtype' => 'SELECT', diff --git a/interface/web/admin/templates/server_php_list.htm b/interface/web/admin/templates/server_php_list.htm index 0fb98965b..5a6392eea 100644 --- a/interface/web/admin/templates/server_php_list.htm +++ b/interface/web/admin/templates/server_php_list.htm @@ -15,12 +15,14 @@ + + @@ -32,6 +34,7 @@ + @@ -54,4 +57,4 @@
{tmpl_var name='search_limit'}
{tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="client_id"} {tmpl_var name="name"}
- \ No newline at end of file + -- GitLab From 0933e16927f36ed30b64716228e6589c0d39beaf Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 17:00:51 +0200 Subject: [PATCH 067/310] Revert "clean-up code" This reverts commit ff16ebc265c0c59e6966f5323e216dd257543d92. --- interface/web/sites/web_vhost_domain_edit.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 029df1cbe..4f2206c67 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -239,6 +239,7 @@ class page_action extends tform_actions { //PHP Version Selection (FastCGI) $server_type = 'apache'; +//print_r($web_config[$server_id]);exit; if(!empty($web_config[$server_id]['server_type'])) $server_type = $web_config[$server_id]['server_type']; if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; @@ -952,6 +953,7 @@ class page_action extends tform_actions { function onSubmit() { global $app, $conf; +//print_r($this->dataRecord);exit; // Set a few fixed values $this->dataRecord["vhost_type"] = 'name'; if($this->_vhostdomain_type == 'domain') { -- GitLab From ef5c6457cce0f4d3b034b606bc804c8ef8c23f0e Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 17:01:33 +0200 Subject: [PATCH 068/310] Revert "Revert "clean-up code"" This reverts commit 0933e16927f36ed30b64716228e6589c0d39beaf. --- interface/web/sites/web_vhost_domain_edit.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 4f2206c67..029df1cbe 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -239,7 +239,6 @@ class page_action extends tform_actions { //PHP Version Selection (FastCGI) $server_type = 'apache'; -//print_r($web_config[$server_id]);exit; if(!empty($web_config[$server_id]['server_type'])) $server_type = $web_config[$server_id]['server_type']; if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; @@ -953,7 +952,6 @@ class page_action extends tform_actions { function onSubmit() { global $app, $conf; -//print_r($this->dataRecord);exit; // Set a few fixed values $this->dataRecord["vhost_type"] = 'name'; if($this->_vhostdomain_type == 'domain') { -- GitLab From f055f5e9bf002bf5a35a2f0f397cdf43ee86a254 Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 17:01:57 +0200 Subject: [PATCH 069/310] Revert "show active for additional php-versions (#5090)" This reverts commit c97bed4466ec457c9b9bb80f50b73fb3765aafea. --- install/dist/lib/fedora.lib.php | 21 ------------------- install/dist/lib/gentoo.lib.php | 21 ------------------- install/dist/lib/opensuse.lib.php | 21 ------------------- install/tpl/debian_postfix.conf.master | 6 ------ install/tpl/fedora_postfix.conf.master | 6 ------ install/tpl/gentoo_postfix.conf.master | 6 ------ install/tpl/opensuse_postfix.conf.master | 6 ------ install/tpl/server.ini.master | 2 +- .../web/admin/lib/lang/de_server_php_list.lng | 1 - .../web/admin/lib/lang/en_server_php_list.lng | 1 - interface/web/admin/list/server_php.list.php | 9 -------- .../web/admin/templates/server_php_list.htm | 5 +---- 12 files changed, 2 insertions(+), 103 deletions(-) diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 8cf13ff19..f1d57f9c8 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -53,14 +53,6 @@ class installer_dist extends installer_base { $cf = $conf['postfix']; $config_dir = $cf['config_dir']; - exec('postconf mail_version', $ret); - $postfix_version=str_replace('mail_version = ', '', $ret[0]); - unset($ret); - exec('openssl version', $ret); - $openssl_version=$ret[0]; - unset($ret); - $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; - if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -171,19 +163,6 @@ class installer_dist extends installer_base { '{greylisting}' => $greylisting, '{reject_slm}' => $reject_sender_login_mismatch, ); - - //* If PFS is possible, configure it - if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); - if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); - if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', - '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); - } else { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => '', - '{smtpd_tls_dh1024_param_file}' => '')); - } $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/fedora_postfix.conf.master', 'tpl/fedora_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index 17c1797eb..af692b168 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -54,14 +54,6 @@ class installer extends installer_base $cf = $conf['postfix']; $config_dir = $cf['config_dir']; - exec('postconf mail_version', $ret); - $postfix_version=str_replace('mail_version = ', '', $ret[0]); - unset($ret); - exec('openssl version', $ret); - $openssl_version=$ret[0]; - unset($ret); - $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; - if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -124,19 +116,6 @@ class installer extends installer_base '{reject_slm}' => $reject_sender_login_mismatch, ); - //* If PFS is possible, configure it - if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); - if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); - if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', - '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); - } else { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => '', - '{smtpd_tls_dh1024_param_file}' => '')); - } - $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/gentoo_postfix.conf.master', 'tpl/gentoo_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); $postconf_commands = array_filter(explode("\n", $postconf_tpl)); // read and remove empty lines diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index 99da9742e..b83b24dcf 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -53,14 +53,6 @@ class installer_dist extends installer_base { $cf = $conf['postfix']; $config_dir = $cf['config_dir']; - exec('postconf mail_version', $ret); - $postfix_version=str_replace('mail_version = ', '', $ret[0]); - unset($ret); - exec('openssl version', $ret); - $openssl_version=$ret[0]; - unset($ret); - $use_pfs=@(version_compare($openssl_version, 'OpenSSL 0.9', '>=') && version_compare($postfix_version, '2.6', '>='))?true:false; - if(!is_dir($config_dir)){ $this->error("The postfix configuration directory '$config_dir' does not exist."); } @@ -182,19 +174,6 @@ class installer_dist extends installer_base { '{greylisting}' => $greylisting, '{reject_slm}' => $reject_sender_login_mismatch, ); - - //* If PFS is possible, configure it - if($use_pfs && !file_exists($config_dir.'/dh_512.pem')) exec('openssl gendh -out '.$config_dir.'/dh_512.pem -2 512'); - if($use_pfs && !file_exists($config_dir.'/dh_2048.pem')) exec('openssl gendh -out '.$config_dir.'/dh_2048.pem -2 2048'); - if($use_pfs && file_exists($config_dir.'/dh_512.pem') && file_exists($config_dir.'/dh_2048.pem')) { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => $config_dir.'/dh_512.pem', - '{smtpd_tls_dh1024_param_file}' => $config_dir.'/dh_2048.pem' )); - } else { - $postconf_placeholders = array_merge($postconf_placeholders, array( - '{smtpd_tls_dh512_param_file}' => '', - '{smtpd_tls_dh1024_param_file}' => '')); - } $postconf_tpl = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/opensuse_postfix.conf.master', 'tpl/opensuse_postfix.conf.master'); $postconf_tpl = strtr($postconf_tpl, $postconf_placeholders); diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index 82cd9a154..b7dbea630 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -44,9 +44,3 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL -smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} -smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} -smtpd_tls_eecdh_grade = strong -tls_preempt_cipherlist = yes -smtp_tls_loglevel = 1 -smtpd_tls_loglevel = 1 diff --git a/install/tpl/fedora_postfix.conf.master b/install/tpl/fedora_postfix.conf.master index 28a38994a..f06af8228 100644 --- a/install/tpl/fedora_postfix.conf.master +++ b/install/tpl/fedora_postfix.conf.master @@ -40,9 +40,3 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL -smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} -smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} -smtpd_tls_eecdh_grade = strong -tls_preempt_cipherlist = yes -smtp_tls_loglevel = 1 -smtpd_tls_loglevel = 1 diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index 3c7015e50..dc20e02c1 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -39,9 +39,3 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL -smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} -smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} -smtpd_tls_eecdh_grade = strong -tls_preempt_cipherlist = yes -smtp_tls_loglevel = 1 -smtpd_tls_loglevel = 1 diff --git a/install/tpl/opensuse_postfix.conf.master b/install/tpl/opensuse_postfix.conf.master index fb2e911b5..4192f988b 100644 --- a/install/tpl/opensuse_postfix.conf.master +++ b/install/tpl/opensuse_postfix.conf.master @@ -42,9 +42,3 @@ smtpd_tls_protocols = !SSLv2,!SSLv3 smtp_tls_protocols = !SSLv2,!SSLv3 smtpd_tls_exclude_ciphers = RC4, aNULL smtp_tls_exclude_ciphers = RC4, aNULL -smtpd_tls_dh512_param_file = {smtpd_tls_dh512_param_file} -smtpd_tls_dh1024_param_file = {smtpd_tls_dh1024_param_file} -smtpd_tls_eecdh_grade = strong -tls_preempt_cipherlist = yes -smtp_tls_loglevel = 1 -smtpd_tls_loglevel = 1 diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index f5dff7940..079d63448 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -102,7 +102,7 @@ php_fpm_ini_path=/etc/php5/fpm/php.ini php_fpm_pool_dir=/etc/php5/fpm/pool.d php_fpm_start_port=9010 php_fpm_socket_dir=/var/lib/php5-fpm -php_default_name=default +php_default_name=Default set_folder_permissions_on_update=n add_web_users_to_sshusers_group=y connect_userid_to_webid=n diff --git a/interface/web/admin/lib/lang/de_server_php_list.lng b/interface/web/admin/lib/lang/de_server_php_list.lng index fe9a72ea1..d775fc6c0 100644 --- a/interface/web/admin/lib/lang/de_server_php_list.lng +++ b/interface/web/admin/lib/lang/de_server_php_list.lng @@ -4,5 +4,4 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Neue PHP Version hinzufügen'; $wb['client_id_txt'] = 'Kunde'; $wb['name_txt'] = 'PHP Name'; -$wb['active_txt'] = 'Aktiv'; ?> diff --git a/interface/web/admin/lib/lang/en_server_php_list.lng b/interface/web/admin/lib/lang/en_server_php_list.lng index 62cbe6168..b402fd1ed 100644 --- a/interface/web/admin/lib/lang/en_server_php_list.lng +++ b/interface/web/admin/lib/lang/en_server_php_list.lng @@ -4,5 +4,4 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Add new PHP version'; $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; -$wb['active_txt'] = 'Active'; ?> diff --git a/interface/web/admin/list/server_php.list.php b/interface/web/admin/list/server_php.list.php index a4a38901a..ee4ad1ab9 100644 --- a/interface/web/admin/list/server_php.list.php +++ b/interface/web/admin/list/server_php.list.php @@ -44,15 +44,6 @@ $liste['auth'] = 'no'; * Suchfelder *****************************************************/ -$liste['item'][] = array( 'field' => 'active', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => '=', - 'prefix' => '', - 'suffix' => '', - 'width' => '', - 'value' => array('y' => $app->lng('yes_txt'), 'n' => $app->lng('no_txt'))); - $liste['item'][] = array( 'field' => 'server_id', 'datatype' => 'INTEGER', 'formtype' => 'SELECT', diff --git a/interface/web/admin/templates/server_php_list.htm b/interface/web/admin/templates/server_php_list.htm index 5a6392eea..0fb98965b 100644 --- a/interface/web/admin/templates/server_php_list.htm +++ b/interface/web/admin/templates/server_php_list.htm @@ -15,14 +15,12 @@ - - @@ -34,7 +32,6 @@ - @@ -57,4 +54,4 @@
{tmpl_var name='search_limit'}
{tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="client_id"} {tmpl_var name="name"}
- + \ No newline at end of file -- GitLab From 081f738e6aee674e3cb20cb17bc9d0dda7518574 Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 17:04:55 +0200 Subject: [PATCH 070/310] show active for additional php-versions (#5090) --- interface/web/admin/lib/lang/de_server_php_list.lng | 1 + interface/web/admin/lib/lang/en_server_php_list.lng | 1 + interface/web/admin/list/server_php.list.php | 9 +++++++++ interface/web/admin/templates/server_php_list.htm | 5 ++++- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/interface/web/admin/lib/lang/de_server_php_list.lng b/interface/web/admin/lib/lang/de_server_php_list.lng index d775fc6c0..fe9a72ea1 100644 --- a/interface/web/admin/lib/lang/de_server_php_list.lng +++ b/interface/web/admin/lib/lang/de_server_php_list.lng @@ -4,4 +4,5 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Neue PHP Version hinzufügen'; $wb['client_id_txt'] = 'Kunde'; $wb['name_txt'] = 'PHP Name'; +$wb['active_txt'] = 'Aktiv'; ?> diff --git a/interface/web/admin/lib/lang/en_server_php_list.lng b/interface/web/admin/lib/lang/en_server_php_list.lng index b402fd1ed..62cbe6168 100644 --- a/interface/web/admin/lib/lang/en_server_php_list.lng +++ b/interface/web/admin/lib/lang/en_server_php_list.lng @@ -4,4 +4,5 @@ $wb['server_id_txt'] = 'Server'; $wb['add_new_record_txt'] = 'Add new PHP version'; $wb['client_id_txt'] = 'Client'; $wb['name_txt'] = 'PHP Name'; +$wb['active_txt'] = 'Active'; ?> diff --git a/interface/web/admin/list/server_php.list.php b/interface/web/admin/list/server_php.list.php index ee4ad1ab9..a4a38901a 100644 --- a/interface/web/admin/list/server_php.list.php +++ b/interface/web/admin/list/server_php.list.php @@ -44,6 +44,15 @@ $liste['auth'] = 'no'; * Suchfelder *****************************************************/ +$liste['item'][] = array( 'field' => 'active', + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'width' => '', + 'value' => array('y' => $app->lng('yes_txt'), 'n' => $app->lng('no_txt'))); + $liste['item'][] = array( 'field' => 'server_id', 'datatype' => 'INTEGER', 'formtype' => 'SELECT', diff --git a/interface/web/admin/templates/server_php_list.htm b/interface/web/admin/templates/server_php_list.htm index 0fb98965b..5a6392eea 100644 --- a/interface/web/admin/templates/server_php_list.htm +++ b/interface/web/admin/templates/server_php_list.htm @@ -15,12 +15,14 @@ + + @@ -32,6 +34,7 @@ + @@ -54,4 +57,4 @@
{tmpl_var name='search_limit'}
{tmpl_var name="active"} {tmpl_var name="server_id"} {tmpl_var name="client_id"} {tmpl_var name="name"}
- \ No newline at end of file + -- GitLab From f114eb1ac6e667d05d6eb0d0333f309a8197eb81 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 25 Jul 2018 11:42:03 -0600 Subject: [PATCH 071/310] copy MySQL client flags support from master --- interface/lib/classes/db_mysql.inc.php | 15 ++++++--------- server/lib/app.inc.php | 2 +- server/lib/classes/db_mysql.inc.php | 19 ++++++++----------- 3 files changed, 15 insertions(+), 21 deletions(-) mode change 100755 => 100644 server/lib/app.inc.php diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index ee6e534b2..e3bf695df 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -74,18 +74,15 @@ class db { $this->dbCharset = $conf[$prefix.'db_charset']; $this->dbNewLink = $conf[$prefix.'db_new_link']; $this->dbClientFlags = $conf[$prefix.'db_client_flags']; - $this->_iConnId = mysqli_init(); - $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); - $try = 0; - while($this->_iConnId->connect_error && $try < 5) { - if($try > 0) sleep(1); - $try++; - $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); + mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); + for($try=0;(!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5;++$try) { + sleep($try); + mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); } - if($this->_iConnId->connect_error) { + if(!is_object($this->_iConnId) || mysqli_connect_error()) { $this->_iConnId = null; $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!'); return false; @@ -244,7 +241,7 @@ class db { $try++; $ok = mysqli_ping($this->_iConnId); if(!$ok) { - if(!mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort)) { + if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { if($try > 4) { $this->_sqlerror('DB::query -> reconnect'); return false; diff --git a/server/lib/app.inc.php b/server/lib/app.inc.php old mode 100755 new mode 100644 index 5016bbc9e..ce2a5484f --- a/server/lib/app.inc.php +++ b/server/lib/app.inc.php @@ -51,7 +51,7 @@ class app { */ if($conf['dbmaster_host'] != '' && ($conf['dbmaster_host'] != $conf['db_host'] || ($conf['dbmaster_host'] == $conf['db_host'] && $conf['dbmaster_database'] != $conf['db_database']))) { - $this->dbmaster = new db($conf['dbmaster_host'], $conf['dbmaster_user'], $conf['dbmaster_password'], $conf['dbmaster_database'], $conf['dbmaster_port']); + $this->dbmaster = new db($conf['dbmaster_host'], $conf['dbmaster_user'], $conf['dbmaster_password'], $conf['dbmaster_database'], $conf['dbmaster_port'], $conf['dbmaster_client_flags']); } else { $this->dbmaster = $this->db; } diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 21e9dc9aa..4eb691ce4 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -64,7 +64,7 @@ class db */ // constructor - public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL) { + public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL) { global $app, $conf; $this->dbHost = $host ? $host : $conf['db_host']; @@ -74,19 +74,16 @@ class db $this->dbPass = $pass ? $pass : $conf['db_password']; $this->dbCharset = $conf['db_charset']; $this->dbNewLink = $conf['db_new_link']; - $this->dbClientFlags = $conf['db_client_flags']; - + $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); - $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); - $try = 0; - while($this->_iConnId->connect_error && $try < 5) { - if($try > 0) sleep(1); - $try++; - $this->_iConnId->real_connect($this->dbHost, $this->dbUser, $this->dbPass, null, (int)$this->dbPort, null, $this->dbClientFlags); + mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); + for($try=0;(!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5;++$try) { + sleep($try); + mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); } - if($this->_iConnId->connect_error) { + if(!is_object($this->_iConnId) || mysqli_connect_error()) { $this->_iConnId = null; $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); return false; @@ -198,7 +195,7 @@ class db $try++; $ok = mysqli_ping($this->_iConnId); if(!$ok) { - if(!mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort)) { + if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { if($this->errorNumber == '111') { // server is not available if($try > 9) { -- GitLab From 7630f59c73ce29d0058e125bd7297ac34d138a26 Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 25 Jul 2018 20:11:14 +0200 Subject: [PATCH 072/310] show reseller in client template list --- .../client/lib/lang/de_client_template_list.lng | 1 + .../client/lib/lang/en_client_template_list.lng | 1 + .../web/client/list/client_template.list.php | 16 ++++++++++++++++ .../client/templates/client_template_list.htm | 9 ++++++--- 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/interface/web/client/lib/lang/de_client_template_list.lng b/interface/web/client/lib/lang/de_client_template_list.lng index 552035fd7..cd5f339ee 100644 --- a/interface/web/client/lib/lang/de_client_template_list.lng +++ b/interface/web/client/lib/lang/de_client_template_list.lng @@ -3,4 +3,5 @@ $wb['list_head_txt'] = 'Kundenvorlagen'; $wb['template_type_txt'] = 'Typ'; $wb['template_name_txt'] = 'Vorlagenname'; $wb['template_id_txt'] = 'Template ID'; +$wb['sys_groupid_txt'] = 'Reseller'; ?> diff --git a/interface/web/client/lib/lang/en_client_template_list.lng b/interface/web/client/lib/lang/en_client_template_list.lng index 1906cefc4..a0442c835 100644 --- a/interface/web/client/lib/lang/en_client_template_list.lng +++ b/interface/web/client/lib/lang/en_client_template_list.lng @@ -3,4 +3,5 @@ $wb["list_head_txt"] = 'Client and Reseller Templates'; $wb["template_type_txt"] = 'Type'; $wb["template_name_txt"] = 'Template name'; $wb['template_id_txt'] = 'Template ID'; +$wb['sys_groupid_txt'] = 'Reseller'; ?> diff --git a/interface/web/client/list/client_template.list.php b/interface/web/client/list/client_template.list.php index cb37eb3f2..a63776ff8 100644 --- a/interface/web/client/list/client_template.list.php +++ b/interface/web/client/list/client_template.list.php @@ -44,6 +44,22 @@ $liste["auth"] = "yes"; /***************************************************** * Suchfelder *****************************************************/ +if($_SESSION['s']['user']['typ'] == 'admin') { + $liste["item"][] = array( 'field' => 'sys_groupid', + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => "SELECT sys_group.groupid,CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), IF(client.contact_firstname != '', CONCAT(client.contact_firstname, ' '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as name FROM sys_group, client WHERE sys_group.groupid != 1 AND sys_group.client_id = client.client_id ORDER BY client.company_name, client.contact_name", + 'keyfield'=> 'groupid', + 'valuefield'=> 'name' + ), + 'width' => '', + 'value' => '' + ); +} $liste["item"][] = array( 'field' => "template_id", 'datatype' => "INTEGER", diff --git a/interface/web/client/templates/client_template_list.htm b/interface/web/client/templates/client_template_list.htm index 16176b131..37564f719 100644 --- a/interface/web/client/templates/client_template_list.htm +++ b/interface/web/client/templates/client_template_list.htm @@ -17,12 +17,14 @@ + {tmpl_var name='search_limit'} + {tmpl_var name='search_template_type'} @@ -34,6 +36,7 @@ {tmpl_var name="template_id"} + {tmpl_var name="sys_groupid"} {tmpl_var name="template_type"} {tmpl_var name="template_name"} @@ -43,16 +46,16 @@ - {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - +
- \ No newline at end of file + -- GitLab From 78a06887591532d6391ce01bf37f0cf06235553e Mon Sep 17 00:00:00 2001 From: florian030 Date: Mon, 30 Jul 2018 10:52:45 +0200 Subject: [PATCH 073/310] fixed "named php-default " --- interface/web/sites/ajax_get_json.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php index 9e530514c..e638e2c46 100644 --- a/interface/web/sites/ajax_get_json.php +++ b/interface/web/sites/ajax_get_json.php @@ -107,7 +107,11 @@ if($type == 'getphpfastcgi'){ } else { $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; } - $json .= '"'.$php_version.'": "'.$php_record['name'].'",'; + if($php_record['name'] != $web_config['php_default_name']) { + $json .= '"'.$php_version.'": "'.$php_record['name'].'",'; + } else { + $json .= '"": "'.$php_record['name'].'",'; + } } } unset($php_records); -- GitLab From dc6e082d0a3050e99488b5f39810ea6fda3a7f1a Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 31 Jul 2018 13:13:01 +0200 Subject: [PATCH 074/310] Fixes #5095 update serial when DNS records are deleted with remote api. --- interface/lib/classes/remote.d/dns.inc.php | 28 +++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/interface/lib/classes/remote.d/dns.inc.php b/interface/lib/classes/remote.d/dns.inc.php index 9938d7543..363af8f48 100644 --- a/interface/lib/classes/remote.d/dns.inc.php +++ b/interface/lib/classes/remote.d/dns.inc.php @@ -331,7 +331,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_aaaa.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -382,7 +382,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_a.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -433,7 +433,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_alias.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -484,7 +484,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_cname.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -535,7 +535,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_hinfo.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -586,7 +586,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_mx.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -637,7 +637,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_ns.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -688,7 +688,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_ptr.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -739,7 +739,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_rp.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -790,7 +790,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_srv.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -841,7 +841,7 @@ class remoting_dns extends remoting { return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_txt.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); return $affected_rows; } @@ -916,6 +916,12 @@ class remoting_dns extends remoting { } private function increase_serial($session_id, $client_id, $params) { + global $app; + if(!isset($params['zone']) && isset($params['dns_rr_id'])) { + $tmp = $app->db->queryOneRecord('SELECT zone FROM dns_rr WHERE id = ?',$params['dns_rr_id']); + $params['zone'] = $tmp['zone']; + unset($tmp); + } $soa = $this->dns_zone_get($session_id, $params['zone']); $serial=$soa['serial']; $serial_date = intval(substr($serial, 0, 8)); -- GitLab From 6f2f1ec25dc81d49c730017f9e31dcaf0ada186a Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 31 Jul 2018 13:13:30 +0200 Subject: [PATCH 075/310] Improve the readOnly check of form tabs. --- interface/lib/classes/tform.inc.php | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/interface/lib/classes/tform.inc.php b/interface/lib/classes/tform.inc.php index b28e50322..920541cac 100644 --- a/interface/lib/classes/tform.inc.php +++ b/interface/lib/classes/tform.inc.php @@ -132,20 +132,25 @@ class tform extends tform_base { function isReadonlyTab($tab, $primary_id) { global $app, $conf; + + if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true) { - // Add backticks for incomplete table names. - if(stristr($this->formDef['db_table'], '.')) { - $escape = ''; - } else { - $escape = '`'; - } + // Add backticks for incomplete table names. + if(stristr($this->formDef['db_table'], '.')) { + $escape = ''; + } else { + $escape = '`'; + } - $sql = "SELECT sys_userid FROM ?? WHERE ?? = ?"; - $record = $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id); + $sql = "SELECT sys_userid FROM ?? WHERE ?? = ?"; + $record = $app->db->queryOneRecord($sql, $this->formDef['db_table'], $this->formDef['db_table_idx'], $primary_id); - // return true if the readonly flag of the form is set and the current loggedin user is not the owner of the record. - if(isset($this->formDef['tabs'][$tab]['readonly']) && $this->formDef['tabs'][$tab]['readonly'] == true && $record['sys_userid'] != $_SESSION["s"]["user"]["userid"]) { - return true; + // return true if the readonly flag of the form is set and the current loggedin user is not the owner of the record. + if($record['sys_userid'] != $_SESSION["s"]["user"]["userid"]) { + return true; + } else { + return false; + } } else { return false; } -- GitLab From 33854f2917356c250b5ebead3aebf8f315da1465 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 31 Jul 2018 14:09:43 +0200 Subject: [PATCH 076/310] Show {DOCROOT_CLIENT} placeholder on options tab of the website. --- interface/web/sites/templates/web_vhost_domain_advanced.htm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/web/sites/templates/web_vhost_domain_advanced.htm b/interface/web/sites/templates/web_vhost_domain_advanced.htm index 7ca4710f4..1def0ecb6 100644 --- a/interface/web/sites/templates/web_vhost_domain_advanced.htm +++ b/interface/web/sites/templates/web_vhost_domain_advanced.htm @@ -98,13 +98,13 @@
- {tmpl_var name="available_apache_directive_snippets_txt"}

 {tmpl_var name="apache_directive_snippets_txt"}
----
 {tmpl_var name='variables_txt'}: {DOCROOT} + {tmpl_var name="available_apache_directive_snippets_txt"}

 {tmpl_var name="apache_directive_snippets_txt"}
----
 {tmpl_var name='variables_txt'}: {DOCROOT}, {DOCROOT_CLIENT}
- {tmpl_var name="available_nginx_directive_snippets_txt"}

 {tmpl_var name="nginx_directive_snippets_txt"}
----
 {tmpl_var name='variables_txt'}: {DOCROOT}, {FASTCGIPASS}, {PHPFALLBACKFASTCGIPASS} + {tmpl_var name="available_nginx_directive_snippets_txt"}

 {tmpl_var name="nginx_directive_snippets_txt"}
----
 {tmpl_var name='variables_txt'}: {DOCROOT}, {DOCROOT_CLIENT}, {FASTCGIPASS}, {PHPFALLBACKFASTCGIPASS}
-- GitLab From f5bb35537f64cde4f243c10909b86c90843bbc21 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Wed, 1 Aug 2018 10:57:55 +0200 Subject: [PATCH 077/310] Improved vhost path filter. --- interface/web/sites/form/web_vhost_domain.tform.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/web/sites/form/web_vhost_domain.tform.php b/interface/web/sites/form/web_vhost_domain.tform.php index fc3859ebf..be06d3463 100644 --- a/interface/web/sites/form/web_vhost_domain.tform.php +++ b/interface/web/sites/form/web_vhost_domain.tform.php @@ -349,6 +349,9 @@ if($vhostdomain_type == 'domain') { 'regex' => '@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', 'errmsg'=> 'web_folder_error_regex'), ), + 'filters' => array( 0 => array( 'event' => 'SAVE', + 'type' => 'TRIM'), + ), 'formtype' => 'TEXT', 'default' => '', 'value' => '', @@ -368,6 +371,9 @@ if($vhostdomain_type == 'domain') { 'regex' => '@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', 'errmsg'=> 'web_folder_error_regex'), ), + 'filters' => array( 0 => array( 'event' => 'SAVE', + 'type' => 'TRIM'), + ), 'formtype' => 'TEXT', 'default' => '', 'value' => '', -- GitLab From 0e6d0529d5f9b1d139ff66d0f70312fdfa21d4c0 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 6 Aug 2018 15:36:02 +0200 Subject: [PATCH 078/310] Some improvements for Commit a39f3677 --- interface/web/admin/form/server_config.tform.php | 8 ++++++++ interface/web/sites/web_vhost_domain_edit.php | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index a39cc3b99..a12743049 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1101,6 +1101,14 @@ $form["tabs"]['web'] = array( 'validators' => array( 0 => array('type' => 'NOTEMPTY', 'errmsg' => 'php_default_name_error_empty'), ), + 'filters' => array( + 0 => array( 'event' => 'SAVE', + 'type' => 'TRIM'), + 1 => array( 'event' => 'SAVE', + 'type' => 'STRIPTAGS'), + 2 => array( 'event' => 'SAVE', + 'type' => 'STRIPNL') + ), 'width' => '40', 'maxlength' => '255' ), diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 029df1cbe..19e4c4c23 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -257,7 +257,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?) AND active = 'y'", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ @@ -404,7 +404,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?) AND active = 'y'", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ @@ -624,7 +624,7 @@ class page_action extends tform_actions { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND active = 'y'", $parent_domain['server_id']); } } - $php_select = ""; + $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ -- GitLab From 70e865b3d770b0f9c7584b1bc21ab9e035cac832 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 6 Aug 2018 17:01:24 +0200 Subject: [PATCH 079/310] Missed one file in last commit. --- interface/web/sites/ajax_get_json.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php index e638e2c46..494f274f1 100644 --- a/interface/web/sites/ajax_get_json.php +++ b/interface/web/sites/ajax_get_json.php @@ -97,7 +97,7 @@ if($type == 'getphpfastcgi'){ } elseif($php_type == 'fast-cgi'){ $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND active = 'y'".$sql_where, $server_id); } - $php_records[]=array('name' => $web_config['php_default_name']); + $php_records[]=array('name' => $app->functions->htmlentities($web_config['php_default_name'])); uasort($php_records, 'sort_php'); $php_select = ""; if(is_array($php_records) && !empty($php_records)) { -- GitLab From b1210f0af422e7f870010dfacccdb477645be47b Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Tue, 7 Aug 2018 19:11:40 -0600 Subject: [PATCH 080/310] fix mysqli connection errors and db::getDatabaseSize() --- server/lib/classes/db_mysql.inc.php | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 4eb691ce4..172655707 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -78,12 +78,15 @@ class db $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); - for($try=0;(!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5;++$try) { + for($try=0;(!is_object($this->_iConnId) || mysqli_connect_errno()) && $try < 5;++$try) { sleep($try); + if(!is_object($this->_iConnId)) { + $this->_iConnId = mysqli_init(); + } mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); } - if(!is_object($this->_iConnId) || mysqli_connect_error()) { + if(!is_object($this->_iConnId) || mysqli_connect_errno()) { $this->_iConnId = null; $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); return false; @@ -193,7 +196,7 @@ class db $try = 0; do { $try++; - $ok = mysqli_ping($this->_iConnId); + $ok = (is_object($this->_iConnId)) ? mysqli_ping($this->_iConnId) : false; if(!$ok) { if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { if($this->errorNumber == '111') { @@ -550,28 +553,18 @@ class db * @param string $database_name * @return int - database-size in bytes */ - - public function getDatabaseSize($database_name) { global $app; - include 'lib/mysql_clientdb.conf'; - - /* Connect to the database */ - $link = mysqli_connect($clientdb_host, $clientdb_user, $clientdb_password); - if (!$link) { - $app->log('Unable to connect to the database'.mysqli_connect_error(), LOGLEVEL_DEBUG); - return; - } + require_once 'lib/mysql_clientdb.conf'; - /* Get database-size from information_schema */ - $result = mysqli_query($link, "SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".mysqli_real_escape_string($link, $database_name)."'"); + $result = $this->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$this->escape($database_name)."'"); if(!$result) { - $app->log('Unable to get the database-size for ' . $database_name . ': '.mysqli_error($link), LOGLEVEL_DEBUG); + $this->_sqlerror('Unable to get the database-size for ' . $database_name); return; } - $database_size = mysqli_fetch_row($result); - mysqli_close($link); + $database_size = $result->getAsRow(); + $result->free(); return $database_size[0]; } -- GitLab From 2c915aec1d67f5890d7fc6bb1ade1956c912c7f6 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 8 Aug 2018 17:01:28 -0600 Subject: [PATCH 081/310] add config variable name prefix --- server/lib/classes/db_mysql.inc.php | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 172655707..f79f87fc8 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -35,6 +35,8 @@ class db private $_iQueryId; private $_iConnId; + private $_Prefix = ''; // config variable name prefix + private $dbHost = ''; // hostname of the MySQL server private $dbPort = ''; // port of the MySQL server private $dbName = ''; // logical database name on that server @@ -64,17 +66,18 @@ class db */ // constructor - public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL) { + public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL, $confPrefix = '') { global $app, $conf; - $this->dbHost = $host ? $host : $conf['db_host']; - $this->dbPort = $port ? $port : $conf['db_port']; - $this->dbName = $database ? $database : $conf['db_database']; - $this->dbUser = $user ? $user : $conf['db_user']; - $this->dbPass = $pass ? $pass : $conf['db_password']; - $this->dbCharset = $conf['db_charset']; - $this->dbNewLink = $conf['db_new_link']; - $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; + if($confPrefix != '') $this->_Prefix = $confPrefix . '_'; + $this->dbHost = $host ? $host : $conf[$this->_Prefix.'db_host']; + $this->dbPort = $port ? $port : $conf[$this->_Prefix.'db_port']; + $this->dbName = $database ? $database : $conf[$this->_Prefix.'db_database']; + $this->dbUser = $user ? $user : $conf[$this->_Prefix.'db_user']; + $this->dbPass = $pass ? $pass : $conf[$this->_Prefix.'db_password']; + $this->dbCharset = $conf[$this->_Prefix.'db_charset']; + $this->dbNewLink = $conf[$this->_Prefix.'db_new_link']; + $this->dbClientFlags = $flags ? $flags : $conf[$this->_Prefix.'db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); @@ -187,7 +190,6 @@ class db private function _query($sQuery = '') { global $app; - //if($this->isConnected == false) return false; if ($sQuery == '') { $this->_sqlerror('Keine Anfrage angegeben / No query given'); return false; @@ -211,7 +213,7 @@ class db } if($try > 9) { - $this->_sqlerror('DB::query -> reconnect', '', true); + $this->_sqlerror('DB::_query -> reconnect', '', true); return false; } else { sleep(($try > 7 ? 5 : 1)); @@ -474,7 +476,7 @@ class db //$sAddMsg .= getDebugBacktrace(); - if($this->show_error_messages && $conf['demo_mode'] === false) { + if($this->show_error_messages && $conf[$this->_Prefix.'demo_mode'] === false) { echo $sErrormsg . $sAddMsg; } elseif(is_object($app) && method_exists($app, 'log') && $bNoLog == false) { $app->log($sErrormsg . $sAddMsg . ' -> ' . $mysql_errno . ' (' . $mysql_error . ')', LOGLEVEL_WARN, false); @@ -570,7 +572,7 @@ class db //** Function to fill the datalog with a full differential record. public function datalogSave($db_table, $action, $primary_field, $primary_id, $record_old, $record_new, $force_update = false) { - global $app, $conf; + global $app; // Insert backticks only for incomplete table names. if(stristr($db_table, '.')) { -- GitLab From 629a8ddfe022ed519631bd6dfd6645a6f1374bbd Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 8 Aug 2018 17:02:19 -0600 Subject: [PATCH 082/310] add db::securityScan() --- server/lib/classes/db_mysql.inc.php | 54 ++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index f79f87fc8..1c1cfc5ad 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -187,6 +187,58 @@ class db mysqli_query($this->_iConnId, "SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'"); } + private function securityScan($string) { + global $app, $conf; + + // get security config + if(isset($app)) { + $app->uses('getconf'); + $ids_config = $app->getconf->get_security_config('ids'); + + if($ids_config['sql_scan_enabled'] == 'yes') { + + // Remove whitespace + $string = trim($string); + if(substr($string,-1) == ';') $string = substr($string,0,-1); + + // Save original string + $string_orig = $string; + + //echo $string; + $chars = array(';', '#', '/*', '*/', '--', '\\\'', '\\"'); + + $string = str_replace('\\\\', '', $string); + $string = preg_replace('/(^|[^\\\])([\'"])\\2/is', '$1', $string); + $string = preg_replace('/(^|[^\\\])([\'"])(.*?[^\\\])\\2/is', '$1', $string); + $ok = true; + + if(substr_count($string, "`") % 2 != 0 || substr_count($string, "'") % 2 != 0 || substr_count($string, '"') % 2 != 0) { + $app->log("SQL injection warning (" . $string_orig . ")",2); + $ok = false; + } else { + foreach($chars as $char) { + if(strpos($string, $char) !== false) { + $ok = false; + $app->log("SQL injection warning (" . $string_orig . ")",2); + break; + } + } + } + if($ok == true) { + return true; + } else { + if($ids_config['sql_scan_action'] == 'warn') { + // we return false in warning level. + return false; + } else { + // if sql action = 'block' or anything else then stop here. + $app->error('Possible SQL injection. All actions have been logged.'); + } + } + } + } + } + private function _query($sQuery = '') { global $app; @@ -227,7 +279,7 @@ class db $aArgs = func_get_args(); $sQuery = call_user_func_array(array(&$this, '_build_query_string'), $aArgs); - + $this->securityScan($sQuery); $this->_iQueryId = mysqli_query($this->_iConnId, $sQuery); if (!$this->_iQueryId) { $this->_sqlerror('Falsche Anfrage / Wrong Query', 'SQL-Query = ' . $sQuery); -- GitLab From e8f8b1f197bb3cd5ad6864763e9541d900901694 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 8 Aug 2018 17:19:05 -0600 Subject: [PATCH 083/310] add db::insertFromArray() --- server/lib/classes/db_mysql.inc.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 1c1cfc5ad..2a7f206b2 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -567,6 +567,26 @@ class db return $out; } + public function insertFromArray($tablename, $data) { + if(!is_array($data)) return false; + + $k_query = ''; + $v_query = ''; + + $params = array($tablename); + $v_params = array(); + + foreach($data as $key => $value) { + $k_query .= ($k_query != '' ? ', ' : '') . '??'; + $v_query .= ($v_query != '' ? ', ' : '') . '?'; + $params[] = $key; + $v_params[] = $value; + } + + $query = 'INSERT INTO ?? (' . $k_query . ') VALUES (' . $v_query . ')'; + return $this->query($query, true, array_merge($params, $v_params)); + } + public function diffrec($record_old, $record_new) { $diffrec_full = array(); $diff_num = 0; -- GitLab From e4f5781ef92cafabee19c5d3e81470e4d1b8f264 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 8 Aug 2018 18:01:48 -0600 Subject: [PATCH 084/310] fix db quota messages --- server/lib/classes/cron.d/100-monitor_database_size.inc.php | 4 ++-- server/lib/classes/db_mysql.inc.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/lib/classes/cron.d/100-monitor_database_size.inc.php b/server/lib/classes/cron.d/100-monitor_database_size.inc.php index d2981dd31..02d90a404 100644 --- a/server/lib/classes/cron.d/100-monitor_database_size.inc.php +++ b/server/lib/classes/cron.d/100-monitor_database_size.inc.php @@ -95,12 +95,12 @@ class cronjob_monitor_database_size extends cronjob { if(!is_numeric($quota)) continue; if($quota < 1 || $quota > $data[$i]['size']) { - print $rec['database_name'] . ' does not exceed quota qize: ' . $quota . ' > ' . $data[$i]['size'] . "\n"; + print 'database ' . $rec['database_name'] . ' size does not exceed quota: ' . $quota . ' (quota) > ' . $data[$i]['size'] . " (used)\n"; if($rec['quota_exceeded'] == 'y') { $app->dbmaster->datalogUpdate('web_database', array('quota_exceeded' => 'n'), 'database_id', $rec['database_id']); } } elseif($rec['quota_exceeded'] == 'n') { - print $rec['database_name'] . ' exceeds quota qize: ' . $quota . ' < ' . $data[$i]['size'] . "\n"; + print 'database ' . $rec['database_name'] . ' size exceeds quota: ' . $quota . ' (quota) < ' . $data[$i]['size'] . " (used)\n"; $app->dbmaster->datalogUpdate('web_database', array('quota_exceeded' => 'y'), 'database_id', $rec['database_id']); } } diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 2a7f206b2..279e12a77 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -634,12 +634,12 @@ class db $result = $this->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$this->escape($database_name)."'"); if(!$result) { - $this->_sqlerror('Unable to get the database-size for ' . $database_name); + $this->_sqlerror('Unable to determine the size of database ' . $database_name); return; } $database_size = $result->getAsRow(); $result->free(); - return $database_size[0]; + return $database_size[0] ? $database_size[0] : 0; } //** Function to fill the datalog with a full differential record. -- GitLab From b94c90305cadfa5c31a6f73beff4a5cc9c46671c Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Thu, 9 Aug 2018 10:45:24 -0600 Subject: [PATCH 085/310] suppress warnings for missing log file --- .../classes/cron.d/200-ftplogfiles.inc.php | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/server/lib/classes/cron.d/200-ftplogfiles.inc.php b/server/lib/classes/cron.d/200-ftplogfiles.inc.php index e47196755..36b433524 100644 --- a/server/lib/classes/cron.d/200-ftplogfiles.inc.php +++ b/server/lib/classes/cron.d/200-ftplogfiles.inc.php @@ -71,24 +71,26 @@ class cronjob_ftplogfiles extends cronjob { } } - $fp = fopen('/var/log/pure-ftpd/transfer.log.1', 'r'); + $fp = @fopen('/var/log/pure-ftpd/transfer.log.1', 'r'); $ftp_traffic = array(); - // cumule des stats journalière dans un tableau - while($line = fgets($fp)) - { - $parsed_line = parse_ftp_log($line); - - $sql = "SELECT wd.domain FROM ftp_user AS fu INNER JOIN web_domain AS wd ON fu.parent_domain_id = wd.domain_id WHERE fu.username = ? "; - $temp = $app->db->queryOneRecord($sql, $parsed_line['username'] ); - - $parsed_line['domain'] = $temp['domain']; - - add_ftp_traffic($ftp_traffic, $parsed_line); + if ($fp) { + // cumule des stats journalière dans un tableau + while($line = fgets($fp)) + { + $parsed_line = parse_ftp_log($line); + + $sql = "SELECT wd.domain FROM ftp_user AS fu INNER JOIN web_domain AS wd ON fu.parent_domain_id = wd.domain_id WHERE fu.username = ? "; + $temp = $app->db->queryOneRecord($sql, $parsed_line['username'] ); + + $parsed_line['domain'] = $temp['domain']; + + add_ftp_traffic($ftp_traffic, $parsed_line); + } + + fclose($fp); } - - fclose($fp); - + // Save du tableau en BD foreach($ftp_traffic as $traffic_date => $all_traffic) { @@ -123,4 +125,4 @@ class cronjob_ftplogfiles extends cronjob { } } -?> \ No newline at end of file +?> -- GitLab From c0069d7aa813b2b460cf6ab548367e87e90e50cc Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Thu, 9 Aug 2018 15:05:39 -0600 Subject: [PATCH 086/310] fix unlimited db quota message --- server/lib/classes/cron.d/100-monitor_database_size.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/classes/cron.d/100-monitor_database_size.inc.php b/server/lib/classes/cron.d/100-monitor_database_size.inc.php index 02d90a404..97f122537 100644 --- a/server/lib/classes/cron.d/100-monitor_database_size.inc.php +++ b/server/lib/classes/cron.d/100-monitor_database_size.inc.php @@ -95,7 +95,7 @@ class cronjob_monitor_database_size extends cronjob { if(!is_numeric($quota)) continue; if($quota < 1 || $quota > $data[$i]['size']) { - print 'database ' . $rec['database_name'] . ' size does not exceed quota: ' . $quota . ' (quota) > ' . $data[$i]['size'] . " (used)\n"; + print 'database ' . $rec['database_name'] . ' size does not exceed quota: ' . ($quota < 1 ? 'unlimited' : $quota) . ' (quota) > ' . $data[$i]['size'] . " (used)\n"; if($rec['quota_exceeded'] == 'y') { $app->dbmaster->datalogUpdate('web_database', array('quota_exceeded' => 'n'), 'database_id', $rec['database_id']); } -- GitLab From b1b26f0e58a5b565cadbbfede8089cf298df0d7a Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Thu, 9 Aug 2018 18:08:26 -0600 Subject: [PATCH 087/310] merging differences between 'server' and 'interface' --- server/lib/classes/db_mysql.inc.php | 58 +++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 279e12a77..6e9d7b835 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -1,4 +1,12 @@ escape($sValue); + $sTxt = str_replace('`', '', $sTxt); if(strpos($sTxt, '.') !== false) { $sTxt = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $sTxt); $sTxt = str_replace('.`*`', '.*', $sTxt); @@ -180,11 +189,11 @@ class db /**#@+ - * @access private - */ + * @access private + */ private function _setCharset() { - mysqli_query($this->_iConnId, 'SET NAMES '.$this->dbCharset); - mysqli_query($this->_iConnId, "SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'"); + $this->query('SET NAMES '.$this->dbCharset); + $this->query("SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'"); } private function securityScan($string) { @@ -693,6 +702,10 @@ class db public function datalogInsert($tablename, $insert_data, $index_field) { global $app; + // Check fields + if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); + if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); + if(is_array($insert_data)) { $key_str = ''; $val_str = ''; @@ -728,6 +741,10 @@ class db public function datalogUpdate($tablename, $update_data, $index_field, $index_value, $force_update = false) { global $app; + // Check fields + if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); + if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); + $old_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); if(is_array($update_data)) { @@ -759,6 +776,10 @@ class db public function datalogDelete($tablename, $index_field, $index_value) { global $app; + // Check fields + if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); + if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); + $old_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $this->query("DELETE FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $new_rec = array(); @@ -776,6 +797,26 @@ class db return true; } + //* get the current datalog status for the specified login (or currently logged in user) + public function datalogStatus($login = '') { + global $app; + + $return = array('count' => 0, 'entries' => array()); + + if($login == '' && isset($_SESSION['s']['user'])) { + $login = $_SESSION['s']['user']['username']; + } + + $result = $this->queryAllRecords("SELECT COUNT( * ) AS cnt, sys_datalog.action, sys_datalog.dbtable FROM sys_datalog, server WHERE server.server_id = sys_datalog.server_id AND sys_datalog.user = ? AND sys_datalog.datalog_id > server.updated GROUP BY sys_datalog.dbtable, sys_datalog.action", $login); + foreach($result as $row) { + if(!$row['dbtable'] || in_array($row['dbtable'], array('aps_instances', 'aps_instances_settings', 'mail_access', 'mail_content_filter'))) continue; // ignore some entries, maybe more to come + $return['entries'][] = array('table' => $row['dbtable'], 'action' => $row['action'], 'count' => $row['cnt'], 'text' => $app->lng('datalog_status_' . $row['action'] . '_' . $row['dbtable'])); $return['count'] += $row['cnt']; + } + unset($result); + + return $return; + } + public function freeResult($query) { @@ -906,10 +947,10 @@ class db function tableInfo($table_name) { - global $go_api, $go_info; + global $go_api, $go_info, $app; // Tabellenfelder einlesen - if($rows = $go_api->db->queryAllRecords('SHOW FIELDS FROM ??', $table_name)){ + if($rows = $app->db->queryAllRecords('SHOW FIELDS FROM ??', $table_name)){ foreach($rows as $row) { $name = $row['Field']; $default = $row['Default']; @@ -1011,7 +1052,7 @@ class db return 'char'; break; case 'varchar': - if($typeValue < 1) die('Database failure: Lenght required for these data types.'); + if($typeValue < 1) die('Database failure: Length required for these data types.'); return 'varchar('.$typeValue.')'; break; case 'text': @@ -1020,6 +1061,9 @@ class db case 'blob': return 'blob'; break; + case 'date': + return 'date'; + break; } } -- GitLab From 04f35dfc213cf18e7088555421b6b16253f8bf59 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Thu, 9 Aug 2018 18:11:35 -0600 Subject: [PATCH 088/310] copy db_mysql.inc.php from 'server' to 'interface' --- interface/lib/classes/db_mysql.inc.php | 216 ++++++++++++++++--------- 1 file changed, 140 insertions(+), 76 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index e3bf695df..6e9d7b835 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -1,4 +1,12 @@ dbHost = $conf[$prefix.'db_host']; - $this->dbPort = $conf[$prefix.'db_port']; - $this->dbName = $conf[$prefix.'db_database']; - $this->dbUser = $conf[$prefix.'db_user']; - $this->dbPass = $conf[$prefix.'db_password']; - $this->dbCharset = $conf[$prefix.'db_charset']; - $this->dbNewLink = $conf[$prefix.'db_new_link']; - $this->dbClientFlags = $conf[$prefix.'db_client_flags']; + public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL, $confPrefix = '') { + global $app, $conf; + + if($confPrefix != '') $this->_Prefix = $confPrefix . '_'; + $this->dbHost = $host ? $host : $conf[$this->_Prefix.'db_host']; + $this->dbPort = $port ? $port : $conf[$this->_Prefix.'db_port']; + $this->dbName = $database ? $database : $conf[$this->_Prefix.'db_database']; + $this->dbUser = $user ? $user : $conf[$this->_Prefix.'db_user']; + $this->dbPass = $pass ? $pass : $conf[$this->_Prefix.'db_password']; + $this->dbCharset = $conf[$this->_Prefix.'db_charset']; + $this->dbNewLink = $conf[$this->_Prefix.'db_new_link']; + $this->dbClientFlags = $flags ? $flags : $conf[$this->_Prefix.'db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); - for($try=0;(!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5;++$try) { + for($try=0;(!is_object($this->_iConnId) || mysqli_connect_errno()) && $try < 5;++$try) { sleep($try); + if(!is_object($this->_iConnId)) { + $this->_iConnId = mysqli_init(); + } mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); } - if(!is_object($this->_iConnId) || mysqli_connect_error()) { + if(!is_object($this->_iConnId) || mysqli_connect_errno()) { $this->_iConnId = null; - $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!'); + $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); return false; } if(!((bool)mysqli_query( $this->_iConnId, 'USE `' . $this->dbName . '`'))) { $this->close(); - $this->_sqlerror('Datenbank nicht gefunden / Database not found'); + $this->_sqlerror('Datenbank nicht gefunden / Database not found', '', true); return false; } @@ -105,6 +120,11 @@ class db { $this->_iConnId = null; } + /* This allows our private variables to be "read" out side of the class */ + public function __get($var) { + return isset($this->$var) ? $this->$var : NULL; + } + public function _build_query_string($sQuery = '') { $iArgs = func_num_args(); if($iArgs > 1) { @@ -127,7 +147,7 @@ class db { if($iPos2 !== false && ($iPos === false || $iPos2 <= $iPos)) { $sTxt = $this->escape($sValue); - + $sTxt = str_replace('`', '', $sTxt); if(strpos($sTxt, '.') !== false) { $sTxt = preg_replace('/^(.+)\.(.+)$/', '`$1`.`$2`', $sTxt); @@ -169,33 +189,33 @@ class db { /**#@+ - * @access private - */ + * @access private + */ private function _setCharset() { - mysqli_query($this->_iConnId, 'SET NAMES '.$this->dbCharset); - mysqli_query($this->_iConnId, "SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'"); + $this->query('SET NAMES '.$this->dbCharset); + $this->query("SET character_set_results = '".$this->dbCharset."', character_set_client = '".$this->dbCharset."', character_set_connection = '".$this->dbCharset."', character_set_database = '".$this->dbCharset."', character_set_server = '".$this->dbCharset."'"); } - + private function securityScan($string) { global $app, $conf; - + // get security config if(isset($app)) { $app->uses('getconf'); $ids_config = $app->getconf->get_security_config('ids'); - + if($ids_config['sql_scan_enabled'] == 'yes') { - + // Remove whitespace $string = trim($string); if(substr($string,-1) == ';') $string = substr($string,0,-1); - + // Save original string $string_orig = $string; - + //echo $string; $chars = array(';', '#', '/*', '*/', '--', '\\\'', '\\"'); - + $string = str_replace('\\\\', '', $string); $string = preg_replace('/(^|[^\\\])([\'"])\\2/is', '$1', $string); $string = preg_replace('/(^|[^\\\])([\'"])(.*?[^\\\])\\2/is', '$1', $string); @@ -239,14 +259,25 @@ class db { $try = 0; do { $try++; - $ok = mysqli_ping($this->_iConnId); + $ok = (is_object($this->_iConnId)) ? mysqli_ping($this->_iConnId) : false; if(!$ok) { if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { - if($try > 4) { - $this->_sqlerror('DB::query -> reconnect'); + if($this->errorNumber == '111') { + // server is not available + if($try > 9) { + if(isset($app) && isset($app->forceErrorExit)) { + $app->forceErrorExit('Database connection failure!'); + } + // if we reach this, the app object is missing or has no exit method, so we continue as normal + } + sleep(30); // additional seconds, please! + } + + if($try > 9) { + $this->_sqlerror('DB::_query -> reconnect', '', true); return false; } else { - sleep(1); + sleep(($try > 7 ? 5 : 1)); } } else { $this->_setCharset(); @@ -258,7 +289,7 @@ class db { $aArgs = func_get_args(); $sQuery = call_user_func_array(array(&$this, '_build_query_string'), $aArgs); $this->securityScan($sQuery); - $this->_iQueryId = @mysqli_query($this->_iConnId, $sQuery); + $this->_iQueryId = mysqli_query($this->_iConnId, $sQuery); if (!$this->_iQueryId) { $this->_sqlerror('Falsche Anfrage / Wrong Query', 'SQL-Query = ' . $sQuery); return false; @@ -390,7 +421,7 @@ class db { } public function query_all_array($sQuery = '') { - return $this->queryAllArray($sQuery); + return call_user_func_array(array(&$this, 'queryAllArray'), func_get_args()); } @@ -431,6 +462,7 @@ class db { } + /** * check if a utf8 string is valid * @@ -470,7 +502,7 @@ class db { public function escape($sString) { global $app; if(!is_string($sString) && !is_numeric($sString)) { - $app->log('NON-String given in escape function! (' . gettype($sString) . ')', LOGLEVEL_DEBUG); + $app->log('NON-String given in escape function! (' . gettype($sString) . ')', LOGLEVEL_INFO); //$sAddMsg = getDebugBacktrace(); $app->log($sAddMsg, LOGLEVEL_DEBUG); $sString = ''; @@ -479,7 +511,7 @@ class db { $cur_encoding = mb_detect_encoding($sString); if($cur_encoding != "UTF-8") { if($cur_encoding != 'ASCII') { - if(is_object($app) && method_exists($app, 'log')) $app->log('String ' . substr($sString, 0, 25) . '... is ' . $cur_encoding . '.', LOGLEVEL_DEBUG); + if(is_object($app) && method_exists($app, 'log')) $app->log('String ' . substr($sString, 0, 25) . '... is ' . $cur_encoding . '.', LOGLEVEL_INFO); if($cur_encoding) $sString = mb_convert_encoding($sString, 'UTF-8', $cur_encoding); else $sString = mb_convert_encoding($sString, 'UTF-8'); } @@ -496,7 +528,7 @@ class db { * * @access private */ - private function _sqlerror($sErrormsg = 'Unbekannter Fehler', $sAddMsg = '') { + private function _sqlerror($sErrormsg = 'Unbekannter Fehler', $sAddMsg = '', $bNoLog = false) { global $app, $conf; $mysql_error = (is_object($this->_iConnId) ? mysqli_error($this->_iConnId) : mysqli_connect_error()); @@ -505,11 +537,13 @@ class db { //$sAddMsg .= getDebugBacktrace(); - if($this->show_error_messages && $conf['demo_mode'] === false) { + if($this->show_error_messages && $conf[$this->_Prefix.'demo_mode'] === false) { echo $sErrormsg . $sAddMsg; - } else if(is_object($app) && method_exists($app, 'log')) { - $app->log($sErrormsg . $sAddMsg . ' -> ' . $mysql_errno . ' (' . $mysql_error . ')', LOGLEVEL_WARN); - } + } elseif(is_object($app) && method_exists($app, 'log') && $bNoLog == false) { + $app->log($sErrormsg . $sAddMsg . ' -> ' . $mysql_errno . ' (' . $mysql_error . ')', LOGLEVEL_WARN, false); + } elseif(php_sapi_name() == 'cli') { + echo $sErrormsg . $sAddMsg; + } } public function affectedRows() { @@ -541,27 +575,27 @@ class db { } return $out; } - + public function insertFromArray($tablename, $data) { if(!is_array($data)) return false; - + $k_query = ''; $v_query = ''; - + $params = array($tablename); $v_params = array(); - + foreach($data as $key => $value) { $k_query .= ($k_query != '' ? ', ' : '') . '??'; $v_query .= ($v_query != '' ? ', ' : '') . '?'; $params[] = $key; $v_params[] = $value; } - + $query = 'INSERT INTO ?? (' . $k_query . ') VALUES (' . $v_query . ')'; return $this->query($query, true, array_merge($params, $v_params)); } - + public function diffrec($record_old, $record_new) { $diffrec_full = array(); $diff_num = 0; @@ -597,15 +631,36 @@ class db { } + /** + * Function to get the database-size + * @param string $database_name + * @return int - database-size in bytes + */ + public function getDatabaseSize($database_name) { + global $app; + + require_once 'lib/mysql_clientdb.conf'; + + $result = $this->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$this->escape($database_name)."'"); + if(!$result) { + $this->_sqlerror('Unable to determine the size of database ' . $database_name); + return; + } + $database_size = $result->getAsRow(); + $result->free(); + return $database_size[0] ? $database_size[0] : 0; + } + //** Function to fill the datalog with a full differential record. public function datalogSave($db_table, $action, $primary_field, $primary_id, $record_old, $record_new, $force_update = false) { - global $app, $conf; + global $app; - // Check fields - if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$db_table)) $app->error('Invalid table name '.$db_table); - if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$primary_field)) $app->error('Invalid primary field '.$primary_field.' in table '.$db_table); - - $primary_id = intval($primary_id); + // Insert backticks only for incomplete table names. + if(stristr($db_table, '.')) { + $escape = ''; + } else { + $escape = '`'; + } if($force_update == true) { //* We force a update even if no record has changed @@ -625,12 +680,13 @@ class db { if($diff_num > 0) { - //print_r($diff_num); - //print_r($diffrec_full); $diffstr = serialize($diffrec_full); - $username = $_SESSION['s']['user']['username']; + if(isset($_SESSION)) { + $username = $_SESSION['s']['user']['username']; + } else { + $username = 'admin'; + } $dbidx = $primary_field.':'.$primary_id; - if(trim($username) == '') $username = 'none'; if($action == 'INSERT') $action = 'i'; if($action == 'UPDATE') $action = 'u'; @@ -645,11 +701,11 @@ class db { //** Inserts a record and saves the changes into the datalog public function datalogInsert($tablename, $insert_data, $index_field) { global $app; - + // Check fields if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); - + if(is_array($insert_data)) { $key_str = ''; $val_str = ''; @@ -688,7 +744,7 @@ class db { // Check fields if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); - + $old_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); if(is_array($update_data)) { @@ -723,7 +779,7 @@ class db { // Check fields if(!preg_match('/^[a-zA-Z0-9\-\_\.]{1,64}$/',$tablename)) $app->error('Invalid table name '.$tablename); if(!preg_match('/^[a-zA-Z0-9\-\_]{1,64}$/',$index_field)) $app->error('Invalid index field '.$index_field.' in table '.$tablename); - + $old_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $this->query("DELETE FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $new_rec = array(); @@ -732,13 +788,20 @@ class db { return true; } + //** Deletes a record and saves the changes into the datalog + public function datalogError($errormsg) { + global $app; + + if(isset($app->modules->current_datalog_id) && $app->modules->current_datalog_id > 0) $this->query("UPDATE sys_datalog set error = ? WHERE datalog_id = ?", $errormsg, $app->modules->current_datalog_id); + + return true; + } + //* get the current datalog status for the specified login (or currently logged in user) public function datalogStatus($login = '') { global $app; $return = array('count' => 0, 'entries' => array()); - //if($_SESSION['s']['user']['typ'] == 'admin') return $return; // these information should not be displayed to admin users - // removed in favor of new non intrusive datalogstatus notification header if($login == '' && isset($_SESSION['s']['user'])) { $login = $_SESSION['s']['user']['username']; @@ -747,14 +810,24 @@ class db { $result = $this->queryAllRecords("SELECT COUNT( * ) AS cnt, sys_datalog.action, sys_datalog.dbtable FROM sys_datalog, server WHERE server.server_id = sys_datalog.server_id AND sys_datalog.user = ? AND sys_datalog.datalog_id > server.updated GROUP BY sys_datalog.dbtable, sys_datalog.action", $login); foreach($result as $row) { if(!$row['dbtable'] || in_array($row['dbtable'], array('aps_instances', 'aps_instances_settings', 'mail_access', 'mail_content_filter'))) continue; // ignore some entries, maybe more to come - $return['entries'][] = array('table' => $row['dbtable'], 'action' => $row['action'], 'count' => $row['cnt'], 'text' => $app->lng('datalog_status_' . $row['action'] . '_' . $row['dbtable'])); - $return['count'] += $row['cnt']; + $return['entries'][] = array('table' => $row['dbtable'], 'action' => $row['action'], 'count' => $row['cnt'], 'text' => $app->lng('datalog_status_' . $row['action'] . '_' . $row['dbtable'])); $return['count'] += $row['cnt']; } unset($result); return $return; } + + public function freeResult($query) + { + if(is_object($query) && (get_class($query) == "mysqli_result")) { + $query->free(); + return true; + } else { + return false; + } + } + /* $columns = array(action => add | alter | drop name => Spaltenname @@ -879,15 +952,6 @@ class db { if($rows = $app->db->queryAllRecords('SHOW FIELDS FROM ??', $table_name)){ foreach($rows as $row) { - /* - $name = $row[0]; - $default = $row[4]; - $key = $row[3]; - $extra = $row[5]; - $isnull = $row[2]; - $type = $row[1]; - */ - $name = $row['Field']; $default = $row['Default']; $key = $row['Key']; @@ -988,7 +1052,7 @@ class db { return 'char'; break; case 'varchar': - if($typeValue < 1) die('Database failure: Lenght required for these data types.'); + if($typeValue < 1) die('Database failure: Length required for these data types.'); return 'varchar('.$typeValue.')'; break; case 'text': -- GitLab From 94babc398a34d58b2f47ec99361456be47a54ae1 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Tue, 14 Aug 2018 15:12:20 -0600 Subject: [PATCH 089/310] update db class use to support client flags (ssl) --- interface/lib/app.inc.php | 6 ++- interface/lib/classes/db_mysql.inc.php | 30 ++++++++----- interface/lib/classes/session.inc.php | 6 ++- .../default/assets/stylesheets/ispconfig.css | 3 ++ .../default/assets/stylesheets/ispconfig.sass | 5 ++- interface/web/tools/dns_import_tupa.php | 42 ++++++------------- interface/web/tools/import_vpopmail.php | 26 ++++++------ .../web/tools/templates/dns_import_tupa.htm | 17 +++++--- .../web/tools/templates/import_vpopmail.htm | 17 +++++--- server/lib/app.inc.php | 12 +++++- server/lib/classes/db_mysql.inc.php | 30 ++++++++----- 11 files changed, 113 insertions(+), 81 deletions(-) diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php index 12b7e9e92..ab7d90334 100755 --- a/interface/lib/app.inc.php +++ b/interface/lib/app.inc.php @@ -62,7 +62,11 @@ class app { $this->_conf = $conf; if($this->_conf['start_db'] == true) { $this->load('db_'.$this->_conf['db_type']); - $this->db = new db; + try { + $this->db = new db; + } catch (Exception $e) { + $this->db = false; + } } //* Start the session diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 6e9d7b835..9e8169fbf 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -64,8 +64,8 @@ class db private $record = array(); // last record fetched private $autoCommit = 1; // Autocommit Transactions private $currentRow; // current row number - public $errorNumber = 0; // last error number */ + public $errorNumber = 0; // last error number public $errorMessage = ''; // last error message /* private $errorLocation = '';// last error location @@ -94,18 +94,20 @@ class db if(!is_object($this->_iConnId)) { $this->_iConnId = mysqli_init(); } - mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); + if(!mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags)) { + $this->_sqlerror('Database connection failed'); + } } if(!is_object($this->_iConnId) || mysqli_connect_errno()) { $this->_iConnId = null; - $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); - return false; + $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); // sets errorMessage + throw new Exception($this->errorMessage); } if(!((bool)mysqli_query( $this->_iConnId, 'USE `' . $this->dbName . '`'))) { $this->close(); - $this->_sqlerror('Datenbank nicht gefunden / Database not found', '', true); - return false; + $this->_sqlerror('Datenbank nicht gefunden / Database not found', '', true); // sets errorMessage + throw new Exception($this->errorMessage); } $this->_setCharset(); @@ -261,8 +263,11 @@ class db $try++; $ok = (is_object($this->_iConnId)) ? mysqli_ping($this->_iConnId) : false; if(!$ok) { - if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { - if($this->errorNumber == '111') { + if(!is_object($this->_iConnId)) { + $this->_iConnId = mysqli_init(); + } + if(!mysqli_real_connect($this->_isConnId, $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { + if(mysqli_connect_errno() == '111') { // server is not available if($try > 9) { if(isset($app) && isset($app->forceErrorExit)) { @@ -531,8 +536,13 @@ class db private function _sqlerror($sErrormsg = 'Unbekannter Fehler', $sAddMsg = '', $bNoLog = false) { global $app, $conf; - $mysql_error = (is_object($this->_iConnId) ? mysqli_error($this->_iConnId) : mysqli_connect_error()); - $mysql_errno = (is_object($this->_iConnId) ? mysqli_errno($this->_iConnId) : mysqli_connect_errno()); + $mysql_errno = mysqli_connect_errno(); + $mysql_error = mysqli_connect_error(); + if ($mysql_errno === 0 && is_object($this->_iConnId)) { + $mysql_errno = mysqli_errno($this->_iConnId); + $mysql_error = mysqli_error($this->_iConnId); + } + $this->errorNumber = $mysql_error; $this->errorMessage = $mysql_error; //$sAddMsg .= getDebugBacktrace(); diff --git a/interface/lib/classes/session.inc.php b/interface/lib/classes/session.inc.php index f4a90beda..3e93cd431 100644 --- a/interface/lib/classes/session.inc.php +++ b/interface/lib/classes/session.inc.php @@ -36,7 +36,11 @@ class session { private $permanent = false; function __construct($session_timeout = 0) { - $this->db = new db; + try { + $this->db = new db; + } catch (Exception $e) { + $this->db = false; + } $this->timeout = $session_timeout; } diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css index d432c7c59..5cd1bd141 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.css +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css @@ -25,6 +25,9 @@ body { .form-group input[type='checkbox'] { margin-top: 10px; } +.form-group .checkbox-inline input[type='checkbox'] { + margin-top: 4px; } + .control-label { font-weight: normal; } .control-label:after { diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.sass b/interface/web/themes/default/assets/stylesheets/ispconfig.sass index 9855d07dc..3ea081053 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.sass +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.sass @@ -25,6 +25,9 @@ body .form-group input[type='checkbox'] margin-top: 10px +.form-group .checkbox-inline input[type='checkbox'] + margin-top: 4px + .control-label font-weight: normal @@ -311,4 +314,4 @@ thead.dark .input-group-field:last-child border-top-left-radius: 0 - border-bottom-left-radius: 0 \ No newline at end of file + border-bottom-left-radius: 0 diff --git a/interface/web/tools/dns_import_tupa.php b/interface/web/tools/dns_import_tupa.php index 12bd03529..d1b4e1af3 100644 --- a/interface/web/tools/dns_import_tupa.php +++ b/interface/web/tools/dns_import_tupa.php @@ -49,32 +49,27 @@ if(isset($_POST['start']) && $_POST['start'] == 1) { //* CSRF Check $app->auth->csrf_token_check(); - //* Set variable sin template + //* Set variables in template $app->tpl->setVar('dbhost', $_POST['dbhost'], true); $app->tpl->setVar('dbname', $_POST['dbname'], true); $app->tpl->setVar('dbuser', $_POST['dbuser'], true); $app->tpl->setVar('dbpassword', $_POST['dbpassword'], true); + $app->tpl->setVar('dbssl', 'true', true); //* Establish connection to external database $msg .= 'Connecting to external database...
'; - //* Backup DB login details - /*$conf_bak['db_host'] = $conf['db_host']; - $conf_bak['db_database'] = $conf['db_database']; - $conf_bak['db_user'] = $conf['db_user']; - $conf_bak['db_password'] = $conf['db_password'];*/ + //* Set external db client flags + $db_client_flags = 0; + if(isset($_POST['dbssl']) && $_POST['dbssl'] == 1) $db_client_flags |= MYSQLI_CLIENT_SSL; - //* Set external Login details - $conf['imp_db_host'] = $_POST['dbhost']; - $conf['imp_db_database'] = $_POST['dbname']; - $conf['imp_db_user'] = $_POST['dbuser']; - $conf['imp_db_password'] = $_POST['dbpassword']; - $conf['imp_db_charset'] = $conf['db_charset']; - $conf['imp_db_new_link'] = $conf['db_new_link']; - $conf['imp_db_client_flags'] = $conf['db_client_flags']; - - //* create new db object - $exdb = new db('imp'); + //* create new db object with external login details + try { + $exdb = new db($_POST['dbhost'], $_POST['dbuser'], $_POST['dbpassword'], $_POST['dbname'], 3306, $db_client_flags); + } catch (Exception $e) { + $error .= "Error connecting to Tupa database" . ($e->getMessage() ? ": " . $e->getMessage() : '.') . "
\n"; + $exdb = false; + } $server_id = 1; $sys_userid = 1; @@ -159,26 +154,13 @@ if(isset($_POST['start']) && $_POST['start'] == 1) { ); $dns_rr_id = $app->db->datalogInsert('dns_rr', $insert_data, 'id'); //$msg .= $insert_data.'
'; - } } } - } } - - - - } else { - $error .= $exdb->errorMessage; } - //* restore db login details - /*$conf['db_host'] = $conf_bak['db_host']; - $conf['db_database'] = $conf_bak['db_database']; - $conf['db_user'] = $conf_bak['db_user']; - $conf['db_password'] = $conf_bak['db_password'];*/ - } $app->tpl->setVar('msg', $msg); diff --git a/interface/web/tools/import_vpopmail.php b/interface/web/tools/import_vpopmail.php index 3ef87710e..a7ec457fb 100644 --- a/interface/web/tools/import_vpopmail.php +++ b/interface/web/tools/import_vpopmail.php @@ -52,17 +52,17 @@ $app->tpl->setVar($wb); if(isset($_POST['db_hostname']) && $_POST['db_hostname'] != '') { - //* Set external Login details - $conf['imp_db_host'] = $_POST['db_hostname']; - $conf['imp_db_database'] = $_POST['db_name']; - $conf['imp_db_user'] = $_POST['db_user']; - $conf['imp_db_password'] = $_POST['db_password']; - $conf['imp_db_charset'] = 'utf8'; - $conf['imp_db_new_link'] = false; - $conf['imp_db_client_flags'] = 0; - - //* create new db object - $exdb = new db('imp'); + //* Set external db client flags + $db_client_flags = 0; + if(isset($_POST['db_ssl']) && $_POST['db_ssl'] == 1) $db_client_flags |= MYSQLI_CLIENT_SSL; + + //* create new db object with external login details + try { + $exdb = new db($_POST['db_hostname'], $_POST['db_user'], $_POST['db_password'], $_POST['db_name'], 3306, $db_client_flags); + } catch (Exception $e) { + $error .= "Error connecting to database" . ($e->getMessage() ? ": " . $e->getMessage() : '.') . "
\n"; + $exdb = false; + } if($exdb !== false) { $msg .= 'Databse connection succeeded
'; @@ -75,9 +75,6 @@ if(isset($_POST['db_hostname']) && $_POST['db_hostname'] != '') { } else { $msg .= 'The server with the ID $local_server_id is not a mail server.
'; } - - } else { - $msg .= 'Database connection failed
'; } } else { @@ -88,6 +85,7 @@ $app->tpl->setVar('db_hostname', $_POST['db_hostname'], true); $app->tpl->setVar('db_user', $_POST['db_user'], true); $app->tpl->setVar('db_password', $_POST['db_password'], true); $app->tpl->setVar('db_name', $_POST['db_name'], true); +$app->tpl->setVar('db_ssl', 'true', true); $app->tpl->setVar('local_server_id', $_POST['local_server_id'], true); $app->tpl->setVar('msg', $msg); $app->tpl->setVar('error', $error); diff --git a/interface/web/tools/templates/dns_import_tupa.htm b/interface/web/tools/templates/dns_import_tupa.htm index 2d37a6a04..cd47f431e 100644 --- a/interface/web/tools/templates/dns_import_tupa.htm +++ b/interface/web/tools/templates/dns_import_tupa.htm @@ -4,22 +4,27 @@ PowerDNS Tupa import
- +
- +
- +
- +
- +
+ +
+ +
+

@@ -34,4 +39,4 @@
-
\ No newline at end of file +
diff --git a/interface/web/tools/templates/import_vpopmail.htm b/interface/web/tools/templates/import_vpopmail.htm index 749ce74a4..7876875b9 100644 --- a/interface/web/tools/templates/import_vpopmail.htm +++ b/interface/web/tools/templates/import_vpopmail.htm @@ -8,26 +8,31 @@
{tmpl_var name="legend_txt"}
- +
- +
- +
- +
+
+
+ +
+ +
- +
-
diff --git a/server/lib/app.inc.php b/server/lib/app.inc.php index ce2a5484f..86df2a86f 100644 --- a/server/lib/app.inc.php +++ b/server/lib/app.inc.php @@ -43,7 +43,11 @@ class app { if($conf['start_db'] == true) { $this->load('db_'.$conf['db_type']); - $this->db = new db; + try { + $this->db = new db; + } catch (Exception $e) { + $this->db = false; + } /* Initialize the connection to the master DB, @@ -51,7 +55,11 @@ class app { */ if($conf['dbmaster_host'] != '' && ($conf['dbmaster_host'] != $conf['db_host'] || ($conf['dbmaster_host'] == $conf['db_host'] && $conf['dbmaster_database'] != $conf['db_database']))) { - $this->dbmaster = new db($conf['dbmaster_host'], $conf['dbmaster_user'], $conf['dbmaster_password'], $conf['dbmaster_database'], $conf['dbmaster_port'], $conf['dbmaster_client_flags']); + try { + $this->dbmaster = new db($conf['dbmaster_host'], $conf['dbmaster_user'], $conf['dbmaster_password'], $conf['dbmaster_database'], $conf['dbmaster_port'], $conf['dbmaster_client_flags']); + } catch (Exception $e) { + $this->dbmaster = false; + } } else { $this->dbmaster = $this->db; } diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 6e9d7b835..9e8169fbf 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -64,8 +64,8 @@ class db private $record = array(); // last record fetched private $autoCommit = 1; // Autocommit Transactions private $currentRow; // current row number - public $errorNumber = 0; // last error number */ + public $errorNumber = 0; // last error number public $errorMessage = ''; // last error message /* private $errorLocation = '';// last error location @@ -94,18 +94,20 @@ class db if(!is_object($this->_iConnId)) { $this->_iConnId = mysqli_init(); } - mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); + if(!mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags)) { + $this->_sqlerror('Database connection failed'); + } } if(!is_object($this->_iConnId) || mysqli_connect_errno()) { $this->_iConnId = null; - $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); - return false; + $this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!', '', true); // sets errorMessage + throw new Exception($this->errorMessage); } if(!((bool)mysqli_query( $this->_iConnId, 'USE `' . $this->dbName . '`'))) { $this->close(); - $this->_sqlerror('Datenbank nicht gefunden / Database not found', '', true); - return false; + $this->_sqlerror('Datenbank nicht gefunden / Database not found', '', true); // sets errorMessage + throw new Exception($this->errorMessage); } $this->_setCharset(); @@ -261,8 +263,11 @@ class db $try++; $ok = (is_object($this->_iConnId)) ? mysqli_ping($this->_iConnId) : false; if(!$ok) { - if(!mysqli_real_connect(mysqli_init(), $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { - if($this->errorNumber == '111') { + if(!is_object($this->_iConnId)) { + $this->_iConnId = mysqli_init(); + } + if(!mysqli_real_connect($this->_isConnId, $this->dbHost, $this->dbUser, $this->dbPass, $this->dbName, (int)$this->dbPort, NULL, $this->dbClientFlags)) { + if(mysqli_connect_errno() == '111') { // server is not available if($try > 9) { if(isset($app) && isset($app->forceErrorExit)) { @@ -531,8 +536,13 @@ class db private function _sqlerror($sErrormsg = 'Unbekannter Fehler', $sAddMsg = '', $bNoLog = false) { global $app, $conf; - $mysql_error = (is_object($this->_iConnId) ? mysqli_error($this->_iConnId) : mysqli_connect_error()); - $mysql_errno = (is_object($this->_iConnId) ? mysqli_errno($this->_iConnId) : mysqli_connect_errno()); + $mysql_errno = mysqli_connect_errno(); + $mysql_error = mysqli_connect_error(); + if ($mysql_errno === 0 && is_object($this->_iConnId)) { + $mysql_errno = mysqli_errno($this->_iConnId); + $mysql_error = mysqli_error($this->_iConnId); + } + $this->errorNumber = $mysql_error; $this->errorMessage = $mysql_error; //$sAddMsg .= getDebugBacktrace(); -- GitLab From a2ce9dc787cc016df9ff243dbe17ddbd608ca47e Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Tue, 14 Aug 2018 15:16:42 -0600 Subject: [PATCH 090/310] remove config variable name prefix --- interface/lib/classes/db_mysql.inc.php | 25 +++++++++++-------------- server/lib/classes/db_mysql.inc.php | 25 +++++++++++-------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 9e8169fbf..283695d7b 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -43,8 +43,6 @@ class db private $_iQueryId; private $_iConnId; - private $_Prefix = ''; // config variable name prefix - private $dbHost = ''; // hostname of the MySQL server private $dbPort = ''; // port of the MySQL server private $dbName = ''; // logical database name on that server @@ -74,18 +72,17 @@ class db */ // constructor - public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL, $confPrefix = '') { + public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL) { global $app, $conf; - if($confPrefix != '') $this->_Prefix = $confPrefix . '_'; - $this->dbHost = $host ? $host : $conf[$this->_Prefix.'db_host']; - $this->dbPort = $port ? $port : $conf[$this->_Prefix.'db_port']; - $this->dbName = $database ? $database : $conf[$this->_Prefix.'db_database']; - $this->dbUser = $user ? $user : $conf[$this->_Prefix.'db_user']; - $this->dbPass = $pass ? $pass : $conf[$this->_Prefix.'db_password']; - $this->dbCharset = $conf[$this->_Prefix.'db_charset']; - $this->dbNewLink = $conf[$this->_Prefix.'db_new_link']; - $this->dbClientFlags = $flags ? $flags : $conf[$this->_Prefix.'db_client_flags']; + $this->dbHost = $host ? $host : $conf['db_host']; + $this->dbPort = $port ? $port : $conf['db_port']; + $this->dbName = $database ? $database : $conf['db_database']; + $this->dbUser = $user ? $user : $conf['db_user']; + $this->dbPass = $pass ? $pass : $conf['db_password']; + $this->dbCharset = $conf['db_charset']; + $this->dbNewLink = $conf['db_new_link']; + $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); @@ -279,7 +276,7 @@ class db } if($try > 9) { - $this->_sqlerror('DB::_query -> reconnect', '', true); + $this->_sqlerror('db::_query -> reconnect', '', true); return false; } else { sleep(($try > 7 ? 5 : 1)); @@ -547,7 +544,7 @@ class db //$sAddMsg .= getDebugBacktrace(); - if($this->show_error_messages && $conf[$this->_Prefix.'demo_mode'] === false) { + if($this->show_error_messages && $conf['demo_mode'] === false) { echo $sErrormsg . $sAddMsg; } elseif(is_object($app) && method_exists($app, 'log') && $bNoLog == false) { $app->log($sErrormsg . $sAddMsg . ' -> ' . $mysql_errno . ' (' . $mysql_error . ')', LOGLEVEL_WARN, false); diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 9e8169fbf..283695d7b 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -43,8 +43,6 @@ class db private $_iQueryId; private $_iConnId; - private $_Prefix = ''; // config variable name prefix - private $dbHost = ''; // hostname of the MySQL server private $dbPort = ''; // port of the MySQL server private $dbName = ''; // logical database name on that server @@ -74,18 +72,17 @@ class db */ // constructor - public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL, $confPrefix = '') { + public function __construct($host = NULL , $user = NULL, $pass = NULL, $database = NULL, $port = NULL, $flags = NULL) { global $app, $conf; - if($confPrefix != '') $this->_Prefix = $confPrefix . '_'; - $this->dbHost = $host ? $host : $conf[$this->_Prefix.'db_host']; - $this->dbPort = $port ? $port : $conf[$this->_Prefix.'db_port']; - $this->dbName = $database ? $database : $conf[$this->_Prefix.'db_database']; - $this->dbUser = $user ? $user : $conf[$this->_Prefix.'db_user']; - $this->dbPass = $pass ? $pass : $conf[$this->_Prefix.'db_password']; - $this->dbCharset = $conf[$this->_Prefix.'db_charset']; - $this->dbNewLink = $conf[$this->_Prefix.'db_new_link']; - $this->dbClientFlags = $flags ? $flags : $conf[$this->_Prefix.'db_client_flags']; + $this->dbHost = $host ? $host : $conf['db_host']; + $this->dbPort = $port ? $port : $conf['db_port']; + $this->dbName = $database ? $database : $conf['db_database']; + $this->dbUser = $user ? $user : $conf['db_user']; + $this->dbPass = $pass ? $pass : $conf['db_password']; + $this->dbCharset = $conf['db_charset']; + $this->dbNewLink = $conf['db_new_link']; + $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); @@ -279,7 +276,7 @@ class db } if($try > 9) { - $this->_sqlerror('DB::_query -> reconnect', '', true); + $this->_sqlerror('db::_query -> reconnect', '', true); return false; } else { sleep(($try > 7 ? 5 : 1)); @@ -547,7 +544,7 @@ class db //$sAddMsg .= getDebugBacktrace(); - if($this->show_error_messages && $conf[$this->_Prefix.'demo_mode'] === false) { + if($this->show_error_messages && $conf['demo_mode'] === false) { echo $sErrormsg . $sAddMsg; } elseif(is_object($app) && method_exists($app, 'log') && $bNoLog == false) { $app->log($sErrormsg . $sAddMsg . ' -> ' . $mysql_errno . ' (' . $mysql_error . ')', LOGLEVEL_WARN, false); -- GitLab From 8b1b6ecc408bf6e5bdb897f66fe430253df1ae16 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Tue, 14 Aug 2018 15:19:00 -0600 Subject: [PATCH 091/310] remove old db_new_link option --- interface/lib/classes/db_mysql.inc.php | 2 -- server/lib/classes/db_mysql.inc.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 283695d7b..6384882ec 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -49,7 +49,6 @@ class db private $dbUser = ''; // database authorized user private $dbPass = ''; // user's password private $dbCharset = 'utf8';// Database charset - private $dbNewLink = false; // Return a new linkID when connect is called again private $dbClientFlags = 0; // MySQL Client falgs /**#@-*/ @@ -81,7 +80,6 @@ class db $this->dbUser = $user ? $user : $conf['db_user']; $this->dbPass = $pass ? $pass : $conf['db_password']; $this->dbCharset = $conf['db_charset']; - $this->dbNewLink = $conf['db_new_link']; $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 283695d7b..6384882ec 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -49,7 +49,6 @@ class db private $dbUser = ''; // database authorized user private $dbPass = ''; // user's password private $dbCharset = 'utf8';// Database charset - private $dbNewLink = false; // Return a new linkID when connect is called again private $dbClientFlags = 0; // MySQL Client falgs /**#@-*/ @@ -81,7 +80,6 @@ class db $this->dbUser = $user ? $user : $conf['db_user']; $this->dbPass = $pass ? $pass : $conf['db_password']; $this->dbCharset = $conf['db_charset']; - $this->dbNewLink = $conf['db_new_link']; $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); -- GitLab From 0e8a6d59611b719f85094a92b1f696ec93fda845 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 15 Aug 2018 17:17:53 -0600 Subject: [PATCH 092/310] fix db connection test for server.php --- interface/lib/classes/db_mysql.inc.php | 32 ++++++++++++++++++-------- server/lib/classes/db_mysql.inc.php | 32 ++++++++++++++++++-------- server/server.php | 6 ++--- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 6384882ec..b0ae61ef3 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -52,8 +52,7 @@ class db private $dbClientFlags = 0; // MySQL Client falgs /**#@-*/ - public $show_error_messages = false; // false in server, true in interface - + public $show_error_messages = false; // false in server, interface sets true when generating templates /* old things - unused now //// private $linkId = 0; // last result of mysqli_connect() @@ -80,7 +79,7 @@ class db $this->dbUser = $user ? $user : $conf['db_user']; $this->dbPass = $pass ? $pass : $conf['db_password']; $this->dbCharset = $conf['db_charset']; - $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; + $this->dbClientFlags = ($flags !== NULL) ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); @@ -117,6 +116,18 @@ class db $this->_iConnId = null; } + /* + * Test mysql connection. + * + * @return boolean returns true if db connection is good. + */ + public function testConnection() { + if(mysqli_connect_errno()) { + return false; + } + return (boolean)(is_object($this->_iConnId) && mysqli_ping($this->_iConnId)); + } + /* This allows our private variables to be "read" out side of the class */ public function __get($var) { return isset($this->$var) ? $this->$var : NULL; @@ -435,13 +446,14 @@ class db * @return int id of last inserted row or 0 if none */ public function insert_id() { - $iRes = mysqli_query($this->_iConnId, 'SELECT LAST_INSERT_ID() as `newid`'); - if(!is_object($iRes)) return false; - - $aReturn = mysqli_fetch_assoc($iRes); - mysqli_free_result($iRes); - - return $aReturn['newid']; + $oResult = $this->query('SELECT LAST_INSERT_ID() as `newid`'); + if(!$oResult) { + $this->_sqlerror('Unable to select last_insert_id()'); + return false; + } + $aReturn = $oResult->get(); + $oResult->free(); + return isset($aReturn['newid']) ? $aReturn['newid'] : 0; } diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index 6384882ec..b0ae61ef3 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -52,8 +52,7 @@ class db private $dbClientFlags = 0; // MySQL Client falgs /**#@-*/ - public $show_error_messages = false; // false in server, true in interface - + public $show_error_messages = false; // false in server, interface sets true when generating templates /* old things - unused now //// private $linkId = 0; // last result of mysqli_connect() @@ -80,7 +79,7 @@ class db $this->dbUser = $user ? $user : $conf['db_user']; $this->dbPass = $pass ? $pass : $conf['db_password']; $this->dbCharset = $conf['db_charset']; - $this->dbClientFlags = $flags ? $flags : $conf['db_client_flags']; + $this->dbClientFlags = ($flags !== NULL) ? $flags : $conf['db_client_flags']; $this->_iConnId = mysqli_init(); mysqli_real_connect($this->_iConnId, $this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort, NULL, $this->dbClientFlags); @@ -117,6 +116,18 @@ class db $this->_iConnId = null; } + /* + * Test mysql connection. + * + * @return boolean returns true if db connection is good. + */ + public function testConnection() { + if(mysqli_connect_errno()) { + return false; + } + return (boolean)(is_object($this->_iConnId) && mysqli_ping($this->_iConnId)); + } + /* This allows our private variables to be "read" out side of the class */ public function __get($var) { return isset($this->$var) ? $this->$var : NULL; @@ -435,13 +446,14 @@ class db * @return int id of last inserted row or 0 if none */ public function insert_id() { - $iRes = mysqli_query($this->_iConnId, 'SELECT LAST_INSERT_ID() as `newid`'); - if(!is_object($iRes)) return false; - - $aReturn = mysqli_fetch_assoc($iRes); - mysqli_free_result($iRes); - - return $aReturn['newid']; + $oResult = $this->query('SELECT LAST_INSERT_ID() as `newid`'); + if(!$oResult) { + $this->_sqlerror('Unable to select last_insert_id()'); + return false; + } + $aReturn = $oResult->get(); + $oResult->free(); + return isset($aReturn['newid']) ? $aReturn['newid'] : 0; } diff --git a/server/server.php b/server/server.php index 689cb1749..106d3edc6 100644 --- a/server/server.php +++ b/server/server.php @@ -61,7 +61,7 @@ $conf['server_id'] = intval($conf['server_id']); /* * Try to Load the server configuration from the master-db */ -if ($app->dbmaster->connect_error == NULL) { +if ($app->dbmaster->testConnection()) { $server_db_record = $app->dbmaster->queryOneRecord("SELECT * FROM server WHERE server_id = ?", $conf['server_id']); if(!is_array($server_db_record)) die('Unable to load the server configuration from database.'); @@ -152,7 +152,7 @@ $needStartCore = true; /* * Next we try to process the datalog */ -if ($app->db->connect_error == NULL && $app->dbmaster->connect_error == NULL) { +if ($app->db->testConnection() && $app->dbmaster->testConnection()) { // Check if there is anything to update if ($conf['mirror_server_id'] > 0) { @@ -187,7 +187,7 @@ if ($app->db->connect_error == NULL && $app->dbmaster->connect_error == NULL) { $needStartCore = false; } else { - if ($app->db->connect->connect_error == NULL) { + if (!$app->db->connect->testConnection()) { $app->log('Unable to connect to local server.' . $app->db->errorMessage, LOGLEVEL_WARN); } else { $app->log('Unable to connect to master server.' . $app->dbmaster->errorMessage, LOGLEVEL_WARN); -- GitLab From 27ba5e70ecd5d1ba1ee105bac1d6b9a9da48efdb Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 09:58:05 +0200 Subject: [PATCH 093/310] Fixed #5101 Issue with DKIM key generator --- interface/web/mail/ajax_get_json.php | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/web/mail/ajax_get_json.php b/interface/web/mail/ajax_get_json.php index f2ec3c3db..350c60938 100644 --- a/interface/web/mail/ajax_get_json.php +++ b/interface/web/mail/ajax_get_json.php @@ -74,6 +74,7 @@ if($type == 'create_dkim' && $domain_id != ''){ } else { $selector = 'invalid domain or selector'; } + } else { unset($dkim_public); exec('echo '.escapeshellarg($dkim_private).'|openssl rsa -pubout -outform PEM 2> /dev/null',$pubkey,$result); foreach($pubkey as $values) $dkim_public=$dkim_public.$values."\n"; -- GitLab From 71e4f82472f9f236b25c94c6f7eb3064ab741f88 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 10:06:52 +0200 Subject: [PATCH 094/310] Change of last commit. --- interface/web/mail/ajax_get_json.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/web/mail/ajax_get_json.php b/interface/web/mail/ajax_get_json.php index 350c60938..2a1a75616 100644 --- a/interface/web/mail/ajax_get_json.php +++ b/interface/web/mail/ajax_get_json.php @@ -74,6 +74,10 @@ if($type == 'create_dkim' && $domain_id != ''){ } else { $selector = 'invalid domain or selector'; } + unset($dkim_public); + exec('echo '.escapeshellarg($dkim_private).'|openssl rsa -pubout -outform PEM 2> /dev/null',$pubkey,$result); + foreach($pubkey as $values) $dkim_public=$dkim_public.$values."\n"; + $selector = $dkim_selector; } else { unset($dkim_public); exec('echo '.escapeshellarg($dkim_private).'|openssl rsa -pubout -outform PEM 2> /dev/null',$pubkey,$result); -- GitLab From 7a7ba27a4719304c45a27396e96c851ddbf95777 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 10:23:33 +0200 Subject: [PATCH 095/310] Fixed #5099 letsencrypt bug on multihost system --- server/plugins-available/apache2_plugin.inc.php | 2 +- server/plugins-available/nginx_plugin.inc.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 5b1441a4b..f9d3ae0a5 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -1220,7 +1220,7 @@ class apache2_plugin { /* Update the DB of the (local) Server */ $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); } } diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 20ba4e96f..4df2f8431 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -1298,7 +1298,7 @@ class nginx_plugin { $data['new']['ssl_letsencrypt'] = 'n'; if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); + $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); /* Update also the master-DB of the Server-Farm */ $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); } -- GitLab From beefb85b17488f874c5aa759002d6d86beb31854 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 10:45:58 +0200 Subject: [PATCH 096/310] Fixed #5065 Strict fcgi starter script permissions leads to a 500 server error on debian wheezy --- .../plugins-available/apache2_plugin.inc.php | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index f9d3ae0a5..bfa4526fc 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -1460,7 +1460,11 @@ class apache2_plugin { //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); - $app->system->chmod($fastcgi_starter_path, 0550); + if($web_config['security_level'] == 10) { + $app->system->chmod($fastcgi_starter_path, 0755); + } else { + $app->system->chmod($fastcgi_starter_path, 0550); + } $fcgi_tpl = new tpl(); $fcgi_tpl->newTemplate('php-fcgi-starter.master'); @@ -1503,7 +1507,11 @@ class apache2_plugin { $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); - $app->system->chmod($fcgi_starter_script, 0550); + if($web_config['security_level'] == 10) { + $app->system->chmod($fcgi_starter_script, 0755); + } else { + $app->system->chmod($fcgi_starter_script, 0550); + } $app->system->chown($fcgi_starter_script, $data['new']['system_user']); $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); @@ -1596,7 +1604,11 @@ class apache2_plugin { $app->system->mkdirpath($cgi_starter_path); $app->system->chown($cgi_starter_path, $data['new']['system_user']); $app->system->chgrp($cgi_starter_path, $data['new']['system_group']); - $app->system->chmod($cgi_starter_path, 0550); + if($web_config['security_level'] == 10) { + $app->system->chmod($cgi_starter_path, 0755); + } else { + $app->system->chmod($cgi_starter_path, 0550); + } $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG); } @@ -1629,7 +1641,11 @@ class apache2_plugin { $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG); - $app->system->chmod($cgi_starter_script, 0550); + if($web_config['security_level'] == 10) { + $app->system->chmod($cgi_starter_script, 0755); + } else { + $app->system->chmod($cgi_starter_script, 0550); + } $app->system->chown($cgi_starter_script, $data['new']['system_user']); $app->system->chgrp($cgi_starter_script, $data['new']['system_group']); -- GitLab From 202f04bcce11d3d8df536b8e0ebe9419e8d1d3f7 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 17 Aug 2018 10:55:01 +0200 Subject: [PATCH 097/310] - fixed vlogger error on non-numeric request size, fixes #5059 --- server/scripts/vlogger | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/server/scripts/vlogger b/server/scripts/vlogger index 8703df0d7..4e60254d0 100755 --- a/server/scripts/vlogger +++ b/server/scripts/vlogger @@ -510,11 +510,9 @@ else { $log_line =~ s/^\S*\s+//o; } - if ($reqsize ne "-") { - if ( $reqsize =~ m/\d|/ && $reqsize > 0 ) { - $tracker{$vhost} += $reqsize; - } - } + if ( $reqsize =~ m/^\d+$/ && $reqsize > 0 ) { + $tracker{$vhost} += $reqsize; + } print $vhost $log_line; -- GitLab From 7aecb1fc49dfd731a7598ae9411011948505d597 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 11:27:25 +0200 Subject: [PATCH 098/310] Fixed #5069 Ignore Ubuntu Livepatch /snap disk full alerts. --- server/lib/classes/cron.d/100-monitor_disk_usage.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/classes/cron.d/100-monitor_disk_usage.inc.php b/server/lib/classes/cron.d/100-monitor_disk_usage.inc.php index 1bae04cc5..1d03949a8 100644 --- a/server/lib/classes/cron.d/100-monitor_disk_usage.inc.php +++ b/server/lib/classes/cron.d/100-monitor_disk_usage.inc.php @@ -74,7 +74,7 @@ class cronjob_monitor_disk_usage extends cronjob { $app->uses('getconf'); $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $dfData = shell_exec('df -PhT -x simfs | awk \'!x[$1]++\' 2>/dev/null'); + $dfData = shell_exec('df -PhT -x simfs -x squashfs | awk \'!x[$1]++\' 2>/dev/null'); // split into array $df = explode("\n", $dfData); -- GitLab From 6e094613712e9aabca1fac62beff2b1f8ee0b33e Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 17:33:41 +0200 Subject: [PATCH 099/310] Fixed #5102 --- interface/lib/classes/functions.inc.php | 22 +++++++++++++++++++ interface/lib/classes/listform.inc.php | 2 +- .../lib/classes/listform_actions.inc.php | 2 +- .../classes/listform_tpl_generator.inc.php | 4 ++-- .../lib/classes/plugin_backuplist.inc.php | 2 +- .../classes/plugin_backuplist_mail.inc.php | 2 +- .../classes/plugin_directive_snippets.inc.php | 2 +- interface/lib/classes/plugin_listview.inc.php | 2 +- .../lib/classes/searchform_actions.inc.php | 4 ++-- interface/lib/classes/tform_base.inc.php | 4 ++-- .../lib/classes/tform_tpl_generator.inc.php | 2 +- interface/web/admin/language_add.php | 2 +- interface/web/admin/language_complete.php | 2 +- interface/web/admin/language_edit.php | 2 +- interface/web/admin/language_export.php | 2 +- interface/web/admin/language_import.php | 2 +- interface/web/admin/language_list.php | 2 +- .../web/admin/remote_action_ispcupdate.php | 2 +- .../web/admin/remote_action_osupdate.php | 2 +- interface/web/admin/software_package_list.php | 2 +- interface/web/admin/software_update_list.php | 2 +- interface/web/client/client_del.php | 2 +- interface/web/client/client_message.php | 2 +- interface/web/client/domain_del.php | 2 +- interface/web/client/domain_edit.php | 2 +- interface/web/dashboard/dashboard.php | 2 +- interface/web/dns/dns_import.php | 2 +- interface/web/dns/dns_wizard.php | 2 +- interface/web/js/scrigo.js.php | 1 + interface/web/login/index.php | 4 ++-- interface/web/login/login_as.php | 2 +- interface/web/login/logout.php | 2 +- interface/web/login/password_reset.php | 2 +- interface/web/mailuser/index.php | 2 +- interface/web/nav.php | 2 +- interface/web/sites/aps_install_package.php | 2 +- .../web/sites/aps_packagedetails_show.php | 2 +- .../web/sites/aps_update_packagelist.php | 2 +- interface/web/tools/import_ispconfig.php | 2 +- interface/web/tools/import_vpopmail.php | 2 +- interface/web/tools/index.php | 2 +- interface/web/tools/tpl_default.php | 2 +- interface/web/tools/user_settings.php | 10 ++++----- interface/web/vm/openvz_action.php | 2 +- 44 files changed, 72 insertions(+), 51 deletions(-) diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index 57e5fdc64..c94853461 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -477,6 +477,28 @@ class functions { return $out; } + + // Function to check paths before we use it as include. Use with absolute paths only. + public function check_include_path($path) { + if(strpos($path,'//')) die('Include path seems to be an URL: '.$this->htmlentities($path)); + if(strpos($path,'..')) die('Two dots are not allowed in include path: '.$this->htmlentities($path)); + if(!preg_match("/^[a-zA-Z0-9_\/\.\-]{1,}$/", $path)) die('Wrong chars in include path: '.$this->htmlentities($path)); + $path = realpath($path); + if($path == '') die('Include path does not exist.'); + if(substr($path,0,strlen(ISPC_ROOT_PATH)) != ISPC_ROOT_PATH) die('Path '.$this->htmlentities($path).' is outside of ISPConfig installation directory.'); + return $path; + } + + // Function to check language strings + public function check_language($language) { + global $app; + if(preg_match('/^[a-z]{2}$/',$language)) { + return $language; + } else { + die('Invalid language string: '.$this->htmlentities($language)); + } + } + } ?> diff --git a/interface/lib/classes/listform.inc.php b/interface/lib/classes/listform.inc.php index 15a1a53ad..4b92daa73 100644 --- a/interface/lib/classes/listform.inc.php +++ b/interface/lib/classes/listform.inc.php @@ -60,7 +60,7 @@ class listform { } //* Set local Language File - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_'.$this->listDef['name'].'_list.lng'; + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_'.$this->listDef['name'].'_list.lng'; if(!file_exists($lng_file)) $lng_file = 'lib/lang/en_'.$this->listDef['name'].'_list.lng'; include $lng_file; diff --git a/interface/lib/classes/listform_actions.inc.php b/interface/lib/classes/listform_actions.inc.php index b4366feaa..a13c3fdb7 100644 --- a/interface/lib/classes/listform_actions.inc.php +++ b/interface/lib/classes/listform_actions.inc.php @@ -249,7 +249,7 @@ class listform_actions { global $app; //* Set global Language File - $lng_file = ISPC_LIB_PATH.'/lang/'.$_SESSION['s']['language'].'.lng'; + $lng_file = ISPC_LIB_PATH.'/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; if(!file_exists($lng_file)) $lng_file = ISPC_LIB_PATH.'/lang/en.lng'; include $lng_file; diff --git a/interface/lib/classes/listform_tpl_generator.inc.php b/interface/lib/classes/listform_tpl_generator.inc.php index 0cb158bb3..031f7a1e5 100644 --- a/interface/lib/classes/listform_tpl_generator.inc.php +++ b/interface/lib/classes/listform_tpl_generator.inc.php @@ -153,10 +153,10 @@ class listform_tpl_generator { } function lng_add($lang, $listDef, $module = '') { - global $go_api, $go_info, $conf; + global $app, $conf; if($module == '') { - $lng_file = "lib/lang/".$conf["language"]."_".$listDef['name']."_list.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($conf["language"])."_".$listDef['name']."_list.lng"; } else { $lng_file = '../'.$module."/lib/lang/en_".$listDef['name']."_list.lng"; } diff --git a/interface/lib/classes/plugin_backuplist.inc.php b/interface/lib/classes/plugin_backuplist.inc.php index 8e62589f7..e96be012e 100644 --- a/interface/lib/classes/plugin_backuplist.inc.php +++ b/interface/lib/classes/plugin_backuplist.inc.php @@ -45,7 +45,7 @@ class plugin_backuplist extends plugin_base { $listTpl->newTemplate('templates/web_backup_list.htm'); //* Loading language file - $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_web_backup_list.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_web_backup_list.lng"; include $lng_file; $listTpl->setVar($wb); diff --git a/interface/lib/classes/plugin_backuplist_mail.inc.php b/interface/lib/classes/plugin_backuplist_mail.inc.php index 512fb8c9f..af1335560 100644 --- a/interface/lib/classes/plugin_backuplist_mail.inc.php +++ b/interface/lib/classes/plugin_backuplist_mail.inc.php @@ -46,7 +46,7 @@ class plugin_backuplist_mail extends plugin_base { $listTpl->newTemplate('templates/mail_user_backup_list.htm'); //* Loading language file - $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_mail_backup_list.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_mail_backup_list.lng"; include($lng_file); $listTpl->setVar($wb); diff --git a/interface/lib/classes/plugin_directive_snippets.inc.php b/interface/lib/classes/plugin_directive_snippets.inc.php index 41138bca1..555526444 100644 --- a/interface/lib/classes/plugin_directive_snippets.inc.php +++ b/interface/lib/classes/plugin_directive_snippets.inc.php @@ -18,7 +18,7 @@ class plugin_directive_snippets extends plugin_base $listTpl->newTemplate('templates/web_directive_snippets.htm'); //* Loading language file - $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_web_directive_snippets.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_web_directive_snippets.lng"; include $lng_file; $listTpl->setVar($wb); diff --git a/interface/lib/classes/plugin_listview.inc.php b/interface/lib/classes/plugin_listview.inc.php index c9d8340e0..bd0aa0e16 100644 --- a/interface/lib/classes/plugin_listview.inc.php +++ b/interface/lib/classes/plugin_listview.inc.php @@ -120,7 +120,7 @@ class plugin_listview extends plugin_base { } // Loading language field - $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$app->listform->listDef['name']."_list.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$app->listform->listDef['name']."_list.lng"; include $lng_file; $listTpl->setVar($wb); diff --git a/interface/lib/classes/searchform_actions.inc.php b/interface/lib/classes/searchform_actions.inc.php index e48eb8544..c4372982c 100644 --- a/interface/lib/classes/searchform_actions.inc.php +++ b/interface/lib/classes/searchform_actions.inc.php @@ -151,10 +151,10 @@ class searchform_actions { global $app; // Language File setzen - $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/'.$_SESSION['s']['language'].'_list.lng'; + $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_list.lng'; if(!file_exists($lng_file)) $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/en_'.'_list.lng'; include $lng_file; - $lng_file = "lib/lang/".$_SESSION["s"]["language"]."_".$app->searchform->listDef['name']."_search.lng"; + $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$app->searchform->listDef['name']."_search.lng"; if(!file_exists($lng_file)) $lng_file = 'lib/lang/en_'.$app->searchform->listDef['name']."_search.lng"; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php index 0e839c53d..3dc9edacc 100644 --- a/interface/lib/classes/tform_base.inc.php +++ b/interface/lib/classes/tform_base.inc.php @@ -134,7 +134,7 @@ class tform_base { $this->module = $module; $wb = array(); - include_once ISPC_ROOT_PATH.'/lib/lang/'.$_SESSION['s']['language'].'.lng'; + include_once ISPC_ROOT_PATH.'/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; if(is_array($wb)) $wb_global = $wb; @@ -143,7 +143,7 @@ class tform_base { if(!file_exists($lng_file)) $lng_file = "lib/lang/en_".$this->formDef["name"].".lng"; include $lng_file; } else { - $lng_file = "../$module/lib/lang/".$_SESSION["s"]["language"]."_".$this->formDef["name"].".lng"; + $lng_file = "../$module/lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$this->formDef["name"].".lng"; if(!file_exists($lng_file)) $lng_file = "../$module/lib/lang/en_".$this->formDef["name"].".lng"; include $lng_file; } diff --git a/interface/lib/classes/tform_tpl_generator.inc.php b/interface/lib/classes/tform_tpl_generator.inc.php index f841a09a6..f0d9649b9 100644 --- a/interface/lib/classes/tform_tpl_generator.inc.php +++ b/interface/lib/classes/tform_tpl_generator.inc.php @@ -298,7 +298,7 @@ class tform_tpl_generator { function lng_add($lang, $formDef) { global $go_api, $go_info, $conf; - $lng_file = "lib/lang/".$conf["language"]."_".$formDef['name'].".lng"; + $lng_file = "lib/lang/".$app->functions->check_language($conf["language"])."_".$formDef['name'].".lng"; if(is_file($lng_file)) { include $lng_file; } else { diff --git a/interface/web/admin/language_add.php b/interface/web/admin/language_add.php index f58a2db16..f36fd946d 100644 --- a/interface/web/admin/language_add.php +++ b/interface/web/admin/language_add.php @@ -104,7 +104,7 @@ $app->tpl->setVar('_csrf_id',$csrf_token['csrf_id']); $app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_add.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_add.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/language_complete.php b/interface/web/admin/language_complete.php index d28e89aa2..234685498 100644 --- a/interface/web/admin/language_complete.php +++ b/interface/web/admin/language_complete.php @@ -166,7 +166,7 @@ $app->tpl->setVar('_csrf_id',$csrf_token['csrf_id']); $app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_complete.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_complete.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/language_edit.php b/interface/web/admin/language_edit.php index c94a5eb28..f17c4ae9a 100644 --- a/interface/web/admin/language_edit.php +++ b/interface/web/admin/language_edit.php @@ -104,7 +104,7 @@ $app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_edit.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_edit.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/language_export.php b/interface/web/admin/language_export.php index 44bc787bd..3f54e53af 100644 --- a/interface/web/admin/language_export.php +++ b/interface/web/admin/language_export.php @@ -111,7 +111,7 @@ if(isset($_POST['lng_select']) && $error == '') { $app->tpl->setVar('msg', $msg); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_export.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_export.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/language_import.php b/interface/web/admin/language_import.php index 2e7021980..6a2d0b5ba 100644 --- a/interface/web/admin/language_import.php +++ b/interface/web/admin/language_import.php @@ -194,7 +194,7 @@ $app->tpl->setVar('_csrf_id',$csrf_token['csrf_id']); $app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_import.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_import.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/language_list.php b/interface/web/admin/language_list.php index 2cb28dc18..b935bddd9 100644 --- a/interface/web/admin/language_list.php +++ b/interface/web/admin/language_list.php @@ -97,7 +97,7 @@ $app->tpl->setLoop('records', $language_files_list); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_language_list.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_language_list.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/admin/remote_action_ispcupdate.php b/interface/web/admin/remote_action_ispcupdate.php index f22661e1d..938f25a1a 100644 --- a/interface/web/admin/remote_action_ispcupdate.php +++ b/interface/web/admin/remote_action_ispcupdate.php @@ -44,7 +44,7 @@ $app->tpl->newTemplate('form.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/remote_action_ispcupdate.htm'); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_remote_action.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_remote_action.lng'; include $lng_file; /* diff --git a/interface/web/admin/remote_action_osupdate.php b/interface/web/admin/remote_action_osupdate.php index 5e73cdfd0..e39cf0eed 100644 --- a/interface/web/admin/remote_action_osupdate.php +++ b/interface/web/admin/remote_action_osupdate.php @@ -43,7 +43,7 @@ $app->tpl->newTemplate('form.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/remote_action_osupdate.htm'); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_remote_action.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_remote_action.lng'; include $lng_file; /* diff --git a/interface/web/admin/software_package_list.php b/interface/web/admin/software_package_list.php index 5e552dbee..b6664d423 100644 --- a/interface/web/admin/software_package_list.php +++ b/interface/web/admin/software_package_list.php @@ -184,7 +184,7 @@ if(is_array($packages) && count($packages) > 0) { $app->tpl->setLoop('records', $packages); $language = (isset($_SESSION['s']['language']))?$_SESSION['s']['language']:$conf['language']; -include_once 'lib/lang/'.$language.'_software_package_list.lng'; +include_once 'lib/lang/'.$app->functions->check_language($language).'_software_package_list.lng'; $app->tpl->setVar($wb); diff --git a/interface/web/admin/software_update_list.php b/interface/web/admin/software_update_list.php index c987e9e04..6d680c0ec 100644 --- a/interface/web/admin/software_update_list.php +++ b/interface/web/admin/software_update_list.php @@ -193,7 +193,7 @@ if(is_array($installed_packages)) { $app->tpl->setLoop('records', $records_out); $language = (isset($_SESSION['s']['language']))?$_SESSION['s']['language']:$conf['language']; -include_once 'lib/lang/'.$language.'_software_update_list.lng'; +include_once 'lib/lang/'.$app->functions->check_language($language).'_software_update_list.lng'; $app->tpl->setVar($wb); diff --git a/interface/web/client/client_del.php b/interface/web/client/client_del.php index dfb4e7464..2bddd02a0 100644 --- a/interface/web/client/client_del.php +++ b/interface/web/client/client_del.php @@ -97,7 +97,7 @@ class page_action extends tform_actions { $app->tpl->setLoop('records', $table_list); //* load language file - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_client_del.lng'; + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_client_del.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/client/client_message.php b/interface/web/client/client_message.php index b4638bd21..2617bbe67 100644 --- a/interface/web/client/client_message.php +++ b/interface/web/client/client_message.php @@ -42,7 +42,7 @@ $app->tpl->newTemplate('form.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/client_message.htm'); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_client_message.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_client_message.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/client/domain_del.php b/interface/web/client/domain_del.php index 701b4494b..1165f3f93 100644 --- a/interface/web/client/domain_del.php +++ b/interface/web/client/domain_del.php @@ -54,7 +54,7 @@ class page_action extends tform_actions { global $app; $conf; //* load language file - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'.lng'; + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; include $lng_file; /* diff --git a/interface/web/client/domain_edit.php b/interface/web/client/domain_edit.php index 8867e2957..094e1899b 100644 --- a/interface/web/client/domain_edit.php +++ b/interface/web/client/domain_edit.php @@ -49,7 +49,7 @@ $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; include $lng_file; diff --git a/interface/web/dashboard/dashboard.php b/interface/web/dashboard/dashboard.php index 7f5fc6e2f..5426ba957 100644 --- a/interface/web/dashboard/dashboard.php +++ b/interface/web/dashboard/dashboard.php @@ -51,7 +51,7 @@ $app->uses('tpl'); $app->tpl->newTemplate("templates/dashboard.htm"); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/dns/dns_import.php b/interface/web/dns/dns_import.php index 49c14185d..540a731ba 100644 --- a/interface/web/dns/dns_import.php +++ b/interface/web/dns/dns_import.php @@ -204,7 +204,7 @@ if ($settings['use_domain_module'] == 'y') { } } -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dns_import.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_dns_import.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/dns/dns_wizard.php b/interface/web/dns/dns_wizard.php index 32112560a..17d767550 100644 --- a/interface/web/dns/dns_wizard.php +++ b/interface/web/dns/dns_wizard.php @@ -465,7 +465,7 @@ $csrf_token = $app->auth->csrf_token_get('dns_wizard'); $app->tpl->setVar('_csrf_id',$csrf_token['csrf_id']); $app->tpl->setVar('_csrf_key',$csrf_token['csrf_key']); -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_dns_wizard.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_dns_wizard.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/js/scrigo.js.php b/interface/web/js/scrigo.js.php index 7c6bf31cb..4022454f5 100644 --- a/interface/web/js/scrigo.js.php +++ b/interface/web/js/scrigo.js.php @@ -3,6 +3,7 @@ include '../../lib/config.inc.php'; header('Content-Type: text/javascript; charset=utf-8'); // the config file sets the content type header so we have to override it here! require_once '../../lib/app.inc.php'; $lang = (isset($_SESSION['s']['language']) && $_SESSION['s']['language'] != '')?$_SESSION['s']['language']:'en'; +$lang = $app->functions->check_language($lang); include_once ISPC_ROOT_PATH.'/web/strengthmeter/lib/lang/'.$lang.'_strengthmeter.lng'; $app->uses('ini_parser,getconf'); diff --git a/interface/web/login/index.php b/interface/web/login/index.php index 441de353c..558896acb 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -229,12 +229,12 @@ if(count($_POST) > 0) { if ($loginAs) $_SESSION['s_old'] = $oldSession; // keep the way back! $_SESSION['s']['user'] = $user; $_SESSION['s']['user']['theme'] = isset($user['app_theme']) ? $user['app_theme'] : 'default'; - $_SESSION['s']['language'] = $user['language']; + $_SESSION['s']['language'] = $app->functions->check_language($user['language']); $_SESSION["s"]['theme'] = $_SESSION['s']['user']['theme']; if ($loginAs) $_SESSION['s']['plugin_cache'] = $_SESSION['s_old']['plugin_cache']; if(is_file(ISPC_WEB_PATH . '/' . $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php')) { - include_once ISPC_WEB_PATH . '/' . $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php'; + include_once $app->functions->check_include_path(ISPC_WEB_PATH . '/' . $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php'); $menu_dir = ISPC_WEB_PATH.'/' . $_SESSION['s']['user']['startmodule'] . '/lib/menu.d'; if (is_dir($menu_dir)) { if ($dh = opendir($menu_dir)) { diff --git a/interface/web/login/login_as.php b/interface/web/login/login_as.php index 4b78c6c41..159f15b77 100644 --- a/interface/web/login/login_as.php +++ b/interface/web/login/login_as.php @@ -83,7 +83,7 @@ $dbData = $app->db->queryOneRecord( * TODO: move the login_as form to a template file -> themeability */ -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_login_as.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_login_as.lng'; include $lng_file; echo ' diff --git a/interface/web/login/logout.php b/interface/web/login/logout.php index a4a127ff8..dc1c9e4a4 100644 --- a/interface/web/login/logout.php +++ b/interface/web/login/logout.php @@ -43,7 +43,7 @@ if (isset($_GET['l']) && ($_GET['l']== 1)) $forceLogout = true; if ((isset($_SESSION['s_old']) && ($_SESSION['s_old']['user']['typ'] == 'admin' || $app->auth->has_clients($_SESSION['s_old']['user']['userid']))) && (!$forceLogout)){ $utype = ($_SESSION['s_old']['user']['typ'] == 'admin' ? 'admin' : 'reseller'); - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_login_as.lng'; + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_login_as.lng'; include $lng_file; echo '



diff --git a/interface/web/login/password_reset.php b/interface/web/login/password_reset.php index e6976bff7..02c71f294 100644 --- a/interface/web/login/password_reset.php +++ b/interface/web/login/password_reset.php @@ -43,7 +43,7 @@ $app->tpl->setInclude('content_tpl', 'templates/password_reset.htm'); $app->tpl_defaults(); -include ISPC_ROOT_PATH.'/web/login/lib/lang/'.$_SESSION['s']['language'].'.lng'; +include ISPC_ROOT_PATH.'/web/login/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'.lng'; $app->tpl->setVar($wb); $continue = true; diff --git a/interface/web/mailuser/index.php b/interface/web/mailuser/index.php index b7748ac1c..c9541df2b 100644 --- a/interface/web/mailuser/index.php +++ b/interface/web/mailuser/index.php @@ -13,7 +13,7 @@ $msg = ''; $error = ''; //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_index.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_index.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/nav.php b/interface/web/nav.php index 68ceb898b..1091276b8 100644 --- a/interface/web/nav.php +++ b/interface/web/nav.php @@ -75,7 +75,7 @@ if(isset($_GET['nav']) && $_GET['nav'] == 'top') { } include_once $mt.'/lib/module.conf.php'; - $language = (isset($_SESSION['s']['user']['language']))?$_SESSION['s']['user']['language']:$conf['language']; + $language = $app->functions->check_language((isset($_SESSION['s']['user']['language']))?$_SESSION['s']['user']['language']:$conf['language']); $app->load_language_file('web/'.$mt.'/lib/'.$language.'.lng'); $active = ($module['name'] == $_SESSION['s']['module']['name']) ? 1 : 0; $topnav[$module['order'].'-'.$module['name']] = array( 'title' => $app->lng($module['title']), diff --git a/interface/web/sites/aps_install_package.php b/interface/web/sites/aps_install_package.php index 19ab785c9..4739e25b8 100644 --- a/interface/web/sites/aps_install_package.php +++ b/interface/web/sites/aps_install_package.php @@ -42,7 +42,7 @@ $app->tpl->newTemplate("form.tpl.htm"); $app->tpl->setInclude('content_tpl', 'templates/aps_install_package.htm'); // Load the language file -$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; +$lngfile = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_aps.lng'; require_once $lngfile; $app->tpl->setVar($wb); $app->load_language_file('web/sites/'.$lngfile); diff --git a/interface/web/sites/aps_packagedetails_show.php b/interface/web/sites/aps_packagedetails_show.php index 1723ffbff..d0503bf9f 100644 --- a/interface/web/sites/aps_packagedetails_show.php +++ b/interface/web/sites/aps_packagedetails_show.php @@ -42,7 +42,7 @@ $app->tpl->newTemplate("listpage.tpl.htm"); $app->tpl->setInclude('content_tpl', 'templates/aps_packagedetails_show.htm'); // Load the language file -$lngfile = 'lib/lang/'.$_SESSION['s']['language'].'_aps.lng'; +$lngfile = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_aps.lng'; require_once $lngfile; $app->tpl->setVar($wb); diff --git a/interface/web/sites/aps_update_packagelist.php b/interface/web/sites/aps_update_packagelist.php index a1278d0eb..821da77bb 100644 --- a/interface/web/sites/aps_update_packagelist.php +++ b/interface/web/sites/aps_update_packagelist.php @@ -41,7 +41,7 @@ $msg = ''; $error = ''; //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_aps_update_packagelist.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_aps_update_packagelist.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/tools/import_ispconfig.php b/interface/web/tools/import_ispconfig.php index 4012802bc..e2b8bad64 100644 --- a/interface/web/tools/import_ispconfig.php +++ b/interface/web/tools/import_ispconfig.php @@ -44,7 +44,7 @@ $msg = ''; $error = ''; //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_import_ispconfig.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_import_ispconfig.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/tools/import_vpopmail.php b/interface/web/tools/import_vpopmail.php index 3ef87710e..0209c80e2 100644 --- a/interface/web/tools/import_vpopmail.php +++ b/interface/web/tools/import_vpopmail.php @@ -46,7 +46,7 @@ $msg = ''; $error = ''; //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_import_vpopmail.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_import_vpopmail.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/tools/index.php b/interface/web/tools/index.php index 05c7f71fb..0e223b98a 100644 --- a/interface/web/tools/index.php +++ b/interface/web/tools/index.php @@ -41,7 +41,7 @@ $app->uses('tpl'); $app->tpl->newTemplate('listpage.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/index.htm'); -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_index.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_index.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/tools/tpl_default.php b/interface/web/tools/tpl_default.php index dacbeae9b..b4ac189da 100644 --- a/interface/web/tools/tpl_default.php +++ b/interface/web/tools/tpl_default.php @@ -41,7 +41,7 @@ $app->uses('tpl'); $app->tpl->newTemplate('listpage.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/tpl_default.htm'); -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_tpl_default.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_tpl_default.lng'; include $lng_file; $app->tpl->setVar($wb); diff --git a/interface/web/tools/user_settings.php b/interface/web/tools/user_settings.php index ccf86adda..5c3876fb8 100644 --- a/interface/web/tools/user_settings.php +++ b/interface/web/tools/user_settings.php @@ -86,12 +86,10 @@ class page_action extends tform_actions { if($_POST['passwort'] != $_POST['repeat_password']) { $app->tform->errorMessage = $app->tform->lng('password_mismatch'); } - if(preg_match('/[a-z]{2}/',$_POST['language'])) { - $_SESSION['s']['user']['language'] = $_POST['language']; - $_SESSION['s']['language'] = $_POST['language']; - } else { - $app->error('Invalid language.'); - } + + $language = $app->functions->check_language($_POST['language']); + $_SESSION['s']['user']['language'] = $language; + $_SESSION['s']['language'] = $language; } function onAfterUpdate() { diff --git a/interface/web/vm/openvz_action.php b/interface/web/vm/openvz_action.php index 4b429eb44..c0bedf19b 100644 --- a/interface/web/vm/openvz_action.php +++ b/interface/web/vm/openvz_action.php @@ -32,7 +32,7 @@ $app->tpl->newTemplate('form.tpl.htm'); $app->tpl->setInclude('content_tpl', 'templates/openvz_action.htm'); //* load language file -$lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_openvz_action.lng'; +$lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_openvz_action.lng'; include_once $lng_file; $app->tpl->setVar($wb); -- GitLab From d09f4db508bcaae404b8db9d907900699901e1d7 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 18:20:37 +0200 Subject: [PATCH 100/310] Finetuning for #5102 --- interface/lib/classes/functions.inc.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index c94853461..878fc5d44 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -480,9 +480,9 @@ class functions { // Function to check paths before we use it as include. Use with absolute paths only. public function check_include_path($path) { - if(strpos($path,'//')) die('Include path seems to be an URL: '.$this->htmlentities($path)); - if(strpos($path,'..')) die('Two dots are not allowed in include path: '.$this->htmlentities($path)); - if(!preg_match("/^[a-zA-Z0-9_\/\.\-]{1,}$/", $path)) die('Wrong chars in include path: '.$this->htmlentities($path)); + if(strpos($path,'//') === false) die('Include path seems to be an URL: '.$this->htmlentities($path)); + if(strpos($path,'..') === false) die('Two dots are not allowed in include path: '.$this->htmlentities($path)); + if(!preg_match("/^[a-zA-Z0-9_\/\.\-]+$/", $path)) die('Wrong chars in include path: '.$this->htmlentities($path)); $path = realpath($path); if($path == '') die('Include path does not exist.'); if(substr($path,0,strlen(ISPC_ROOT_PATH)) != ISPC_ROOT_PATH) die('Path '.$this->htmlentities($path).' is outside of ISPConfig installation directory.'); @@ -495,7 +495,8 @@ class functions { if(preg_match('/^[a-z]{2}$/',$language)) { return $language; } else { - die('Invalid language string: '.$this->htmlentities($language)); + $app->log('Wrong language string: '.$this->htmlentities($language),1); + return 'en'; } } -- GitLab From a02ec6b0305689c14dbd06237b9d56c8f90969ef Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 17 Aug 2018 18:22:58 +0200 Subject: [PATCH 101/310] #5102 --- interface/lib/classes/functions.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index 878fc5d44..28ab9ce38 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -480,8 +480,8 @@ class functions { // Function to check paths before we use it as include. Use with absolute paths only. public function check_include_path($path) { - if(strpos($path,'//') === false) die('Include path seems to be an URL: '.$this->htmlentities($path)); - if(strpos($path,'..') === false) die('Two dots are not allowed in include path: '.$this->htmlentities($path)); + if(strpos($path,'//') !== false) die('Include path seems to be an URL: '.$this->htmlentities($path)); + if(strpos($path,'..') !== false) die('Two dots are not allowed in include path: '.$this->htmlentities($path)); if(!preg_match("/^[a-zA-Z0-9_\/\.\-]+$/", $path)) die('Wrong chars in include path: '.$this->htmlentities($path)); $path = realpath($path); if($path == '') die('Include path does not exist.'); -- GitLab From bf571f26d4d265cd74a38a9c0efda341bd610e12 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 7 Sep 2018 16:57:01 +0200 Subject: [PATCH 102/310] Allow single letter domain tld --- interface/lib/classes/validate_domain.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/validate_domain.inc.php b/interface/lib/classes/validate_domain.inc.php index 01293abd6..904fab2b2 100644 --- a/interface/lib/classes/validate_domain.inc.php +++ b/interface/lib/classes/validate_domain.inc.php @@ -191,7 +191,7 @@ class validate_domain { /* internal validator function to match regexp */ function _regex_validate($domain_name, $allow_wildcard = false) { - $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{2,30}$/'; + $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{1,30}$/'; return preg_match($pattern, $domain_name); } -- GitLab From b361d13b9f92a92a0c6baab89db06d3fcaaa058a Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Fri, 7 Sep 2018 17:00:55 +0200 Subject: [PATCH 103/310] Allow single letter domain not tld, corrected last commit. --- interface/lib/classes/validate_domain.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/validate_domain.inc.php b/interface/lib/classes/validate_domain.inc.php index 904fab2b2..57187805c 100644 --- a/interface/lib/classes/validate_domain.inc.php +++ b/interface/lib/classes/validate_domain.inc.php @@ -191,7 +191,7 @@ class validate_domain { /* internal validator function to match regexp */ function _regex_validate($domain_name, $allow_wildcard = false) { - $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{2,255}\.[a-zA-Z0-9\-]{1,30}$/'; + $pattern = '/^' . ($allow_wildcard == true ? '(\*\.)?' : '') . '[\w\.\-]{1,255}\.[a-zA-Z0-9\-]{2,30}$/'; return preg_match($pattern, $domain_name); } -- GitLab From 96f59e61b80e367c26547ca043de0e4e4b9a73f9 Mon Sep 17 00:00:00 2001 From: Olivier BOUMATI Date: Tue, 11 Sep 2018 09:43:38 +0200 Subject: [PATCH 104/310] Update monitor_tools.inc.php Preserve body structure in send_notification_email --- server/lib/classes/monitor_tools.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/lib/classes/monitor_tools.inc.php b/server/lib/classes/monitor_tools.inc.php index 9f7580fee..9be10e152 100644 --- a/server/lib/classes/monitor_tools.inc.php +++ b/server/lib/classes/monitor_tools.inc.php @@ -776,7 +776,8 @@ class monitor_tools { $mailSubject = ''; $inHeader = true; for($l = 0; $l < count($lines); $l++) { - if(trim($lines[$l]) == '') { + /* Trim only in headers */ + if($inHeader && trim($lines[$l]) == '') { $inHeader = false; continue; } -- GitLab From a27954c5006042c1e2a62210dd1265502d1f0f1c Mon Sep 17 00:00:00 2001 From: florian030 Date: Wed, 12 Sep 2018 17:09:15 +0200 Subject: [PATCH 105/310] fixed sql-query for master-server for mail-backups --- server/lib/classes/cron.d/500-backup_mail.inc.php | 2 +- server/plugins-available/backup_plugin.inc.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/lib/classes/cron.d/500-backup_mail.inc.php b/server/lib/classes/cron.d/500-backup_mail.inc.php index a6807021d..b05caf70d 100644 --- a/server/lib/classes/cron.d/500-backup_mail.inc.php +++ b/server/lib/classes/cron.d/500-backup_mail.inc.php @@ -242,7 +242,7 @@ class cronjob_backup_mail extends cronjob { if(!is_file($mail_backup_dir.'/'.$backup['filename'])){ $sql = "DELETE FROM mail_backup WHERE server_id = ? AND parent_domain_id = ? AND filename = ?"; $app->db->query($sql, $conf['server_id'], $backup['parent_domain_id'], $backup['filename']); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); + if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $backup['parent_domain_id'], $backup['filename']); } } } diff --git a/server/plugins-available/backup_plugin.inc.php b/server/plugins-available/backup_plugin.inc.php index 5cb2dde42..6ce8c9893 100644 --- a/server/plugins-available/backup_plugin.inc.php +++ b/server/plugins-available/backup_plugin.inc.php @@ -296,7 +296,7 @@ class backup_plugin { unlink($mail_backup_file); $sql = "DELETE FROM mail_backup WHERE server_id = ? AND parent_domain_id = ? AND filename = ?"; $app->db->query($sql, $conf['server_id'], $mail_backup['parent_domain_id'], $mail_backup['filename']); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql); + if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $mail_backup['parent_domain_id'], $mail_backup['filename']); $app->log('unlink '.$backup_dir.'/'.$mail_backup['filename'], LOGLEVEL_DEBUG); } } -- GitLab From e2465bd7a2d324259c3c1dae00dfca8c2535edcc Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 17 Sep 2018 11:13:31 +0200 Subject: [PATCH 106/310] Fixed #5128 Bug in password strength meter --- interface/lib/classes/validate_password.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/validate_password.inc.php b/interface/lib/classes/validate_password.inc.php index f36f16220..a0f6de2e9 100644 --- a/interface/lib/classes/validate_password.inc.php +++ b/interface/lib/classes/validate_password.inc.php @@ -71,7 +71,7 @@ class validate_password { } else if ($points == 1) { if ($length >= 5 && $length <= 6) { return 2; - } else if (length >= 7 && length <=10) { + } else if ($length >= 7 && $length <=10) { return 3; } else { return 4; -- GitLab From 741a08915729ee967af606a416640246e03a997f Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Wed, 31 Jan 2018 13:32:06 +0100 Subject: [PATCH 107/310] Remove old duplicate example, it is an old copy of sites_database_add.php --- .../examples/soap-database-add.php | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 remoting_client/examples/soap-database-add.php diff --git a/remoting_client/examples/soap-database-add.php b/remoting_client/examples/soap-database-add.php deleted file mode 100644 index 5ff7e4b79..000000000 --- a/remoting_client/examples/soap-database-add.php +++ /dev/null @@ -1,47 +0,0 @@ - $soap_location, - 'uri' => $soap_uri)); -try { - if($session_id = $client->login($username, $password)) { - echo "Logged:".$session_id."
\n"; - } - - $database_type = 'mysql'; //Only mysql type avaliable more types coming soon. - $database_name = 'yourdbname'; - $database_username = 'yourusername'; - $database_password = 'yourpassword'; - $database_charset = ''; // blank = db default, latin1 or utf8 - $database_remoteips = ''; //remote ip´s separated by commas - - $params = array( - 'server_id' => 1, - 'type' => $database_type, - 'database_name' => $database_name, - 'database_user' => $database_username, - 'database_password' => $database_password, - 'database_charset' => $database_charset, - 'remote_access' => 'n', // n disabled - y enabled - 'active' => 'y', // n disabled - y enabled - 'remote_ips' => $database_remoteips - ); - - $client_id = 1; - $database_id = $client->sites_database_add($session_id, $client_id, $params); - - if($client->logout($session_id)) { - echo "Logout.
\n"; - } - - -} catch (SoapFault $e) { - die('Error: '.$e->getMessage()); -} - -?> -- GitLab From a8d1dd2194508ec6a5710fc9b0f50afacca19d6b Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 17 Feb 2018 21:40:41 +0100 Subject: [PATCH 108/310] Set a descriptive name for the return vanlue of mail_user_add(); --- interface/lib/classes/remote.d/mail.inc.php | 4 ++-- remoting_client/examples/mail_user_add.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php index 25bc1e8f3..0a1f890b9 100644 --- a/interface/lib/classes/remote.d/mail.inc.php +++ b/interface/lib/classes/remote.d/mail.inc.php @@ -219,8 +219,8 @@ class remoting_mail extends remoting { if (!isset($params['gid'])) $params['gid'] = -1; if (!isset($params['maildir_format'])) $params['maildir_format'] = 'maildir'; - $affected_rows = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params); - return $affected_rows; + $mailuser_id = $this->insertQuery('../mail/form/mail_user.tform.php', $client_id, $params); + return $mailuser_id; } //* Update mail user diff --git a/remoting_client/examples/mail_user_add.php b/remoting_client/examples/mail_user_add.php index 3b7d240ec..26d942066 100644 --- a/remoting_client/examples/mail_user_add.php +++ b/remoting_client/examples/mail_user_add.php @@ -42,9 +42,9 @@ try { 'disablesmtp' => 'n' ); - $affected_rows = $client->mail_user_add($session_id, $client_id, $params); + $mailuser_id = $client->mail_user_add($session_id, $client_id, $params); - echo "New user: ".$affected_rows."
"; + echo "New user: ".$mailuser_id."
"; if($client->logout($session_id)) { echo 'Logged out.
'; -- GitLab From b0b62599527d1bcb21e3fa40e600fa4f22ad1e01 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 17 Feb 2018 21:41:58 +0100 Subject: [PATCH 109/310] fix typo --- remoting_client/readme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/remoting_client/readme b/remoting_client/readme index 1392888bc..92af7f824 100644 --- a/remoting_client/readme +++ b/remoting_client/readme @@ -3,8 +3,8 @@ - Remote API example files -------------------------------------------------------- -The examples folder contains a example script for every -Remote api function. The login details and URL for the +The examples folder contains an example script for every +remote api function. The login details and URL for the remote connection are defined in the file soap_config.php -------------------------------------------------------- -- GitLab From f112fd1a7cb88507655f0484f128f66a6bdfa9f9 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 17 Feb 2018 21:42:12 +0100 Subject: [PATCH 110/310] correct index path --- remoting_client/readme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/remoting_client/readme b/remoting_client/readme index 92af7f824..6e2ef10e6 100644 --- a/remoting_client/readme +++ b/remoting_client/readme @@ -11,4 +11,4 @@ remote connection are defined in the file soap_config.php - Remote API documentation -------------------------------------------------------- -The startpage of the API documentation is main.html +The startpage of the API documentation is API-docs/index.html -- GitLab From b73e97826715c3e7d38f531f435b0637d7c41e55 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Fri, 9 Mar 2018 10:14:31 +0100 Subject: [PATCH 111/310] Cleanup whitespace --- install/tpl/debian_postfix.conf.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index b7dbea630..22a9484b1 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -14,7 +14,7 @@ smtpd_sasl_auth_enable = yes broken_sasl_auth_clients = yes smtpd_sasl_authenticated_header = yes smtpd_restriction_classes = greylisting -greylisting = check_policy_service inet:127.0.0.1:10023 +greylisting = check_policy_service inet:127.0.0.1:10023 smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination{rbl_list}, check_recipient_access mysql:{config_dir}/mysql-virtual_recipient.cf{greylisting} smtpd_use_tls = yes smtpd_tls_security_level = may -- GitLab From bf7714a52ff51df57855e4b726d0cc20cb706e3e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Fri, 21 Sep 2018 08:51:10 +0200 Subject: [PATCH 112/310] Correct warning message --- server/cron.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/cron.php b/server/cron.php index 261abd983..23eeaa023 100644 --- a/server/cron.php +++ b/server/cron.php @@ -37,7 +37,7 @@ if (is_file($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')) { $pid = trim(file_get_contents($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')); if(preg_match('/^[0-9]+$/', $pid)) { if(file_exists('/proc/' . $pid)) { - if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - There is already an instance of server.php running with pid ' . $pid . '.' . "\n"; + if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - There is already an instance of cron.php running with pid ' . $pid . '.' . "\n"; exit; } } -- GitLab From 36684dcf752c761f02bc85c6513db81e6482facd Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 10 Oct 2018 18:37:08 +0200 Subject: [PATCH 113/310] Mulitple HSTS headers are not allowed, should either unset before adding new, or set conditionally. --- install/tpl/apache_ispconfig.vhost.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index 8eccbcba3..57c70885d 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -88,7 +88,7 @@ NameVirtualHost *:
- Header always add Strict-Transport-Security "max-age=15768000" + Header setifempty add Strict-Transport-Security "max-age=15768000" RequestHeader unset Proxy early -- GitLab From ca7c77d98cf8e8136be883ea29056de7097beef8 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 10 Oct 2018 18:41:26 +0200 Subject: [PATCH 114/310] Update apache_ispconfig.vhost.master --- install/tpl/apache_ispconfig.vhost.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index 57c70885d..5c4ef2248 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -88,7 +88,7 @@ NameVirtualHost *:
- Header setifempty add Strict-Transport-Security "max-age=15768000" + Header setifempty Strict-Transport-Security "max-age=15768000" RequestHeader unset Proxy early -- GitLab From c825a73677068845d56e32abc4e6b709ec4b65b6 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 11 Oct 2018 19:22:36 +0200 Subject: [PATCH 115/310] Revert "Update apache_ispconfig.vhost.master" This reverts commit ca7c77d98cf8e8136be883ea29056de7097beef8 --- install/tpl/apache_ispconfig.vhost.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index 5c4ef2248..57c70885d 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -88,7 +88,7 @@ NameVirtualHost *: - Header setifempty Strict-Transport-Security "max-age=15768000" + Header setifempty add Strict-Transport-Security "max-age=15768000" RequestHeader unset Proxy early -- GitLab From b5dd05ad4676a89362f91d8b12472181da2357c2 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Thu, 11 Oct 2018 21:51:53 +0200 Subject: [PATCH 116/310] Add Content-Security-Policy header and friends. --- install/tpl/apache_ispconfig.vhost.master | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index 57c70885d..33ff3bae8 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -88,8 +88,14 @@ NameVirtualHost *: - Header setifempty add Strict-Transport-Security "max-age=15768000" - RequestHeader unset Proxy early + # ISPConfig 3.1 currently requires unsafe-line for both scripts and styles, as well as unsafe-eval + Header set Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data:; object-src 'none'; upgrade-insecure-requests" + Header set X-Content-Type-Options: nosniff + Header set X-Frame-Options: SAMEORIGIN + Header set X-XSS-Protection: "1; mode=block" + Header always edit Set-Cookie (.*) "$1; HTTPOnly; Secure" + Header setifempty Strict-Transport-Security "max-age=15768000" + RequestHeader unset Proxy early -- GitLab From baf703b92b4644f132db15987346a893a0a00702 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Mon, 15 Oct 2018 14:56:35 +0200 Subject: [PATCH 117/310] Do not show db or site quota when the sites module is not active --- interface/web/dashboard/dashlets/databasequota.php | 5 +++++ interface/web/dashboard/dashlets/quota.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/interface/web/dashboard/dashlets/databasequota.php b/interface/web/dashboard/dashlets/databasequota.php index b126d95a5..a3f6f905d 100644 --- a/interface/web/dashboard/dashlets/databasequota.php +++ b/interface/web/dashboard/dashlets/databasequota.php @@ -8,6 +8,11 @@ class dashlet_databasequota { //* Loading Template $app->uses('tpl,quota_lib'); + $modules = $_SESSION['s']['user']['modules']; + if (!in_array($modules, 'sites')) { + return ''; + } + $tpl = new tpl; $tpl->newTemplate("dashlets/templates/databasequota.htm"); diff --git a/interface/web/dashboard/dashlets/quota.php b/interface/web/dashboard/dashlets/quota.php index 6ff975b62..f94150a0f 100644 --- a/interface/web/dashboard/dashlets/quota.php +++ b/interface/web/dashboard/dashlets/quota.php @@ -8,6 +8,11 @@ class dashlet_quota { //* Loading Template $app->uses('tpl,quota_lib'); + $modules = $_SESSION['s']['user']['modules']; + if (!in_array($modules, 'sites')) { + return ''; + } + $tpl = new tpl; $tpl->newTemplate("dashlets/templates/quota.htm"); -- GitLab From ab6cf3fcf8154ee1a1b9858f2a414a369b91cab1 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Fri, 5 Oct 2018 16:16:42 +0200 Subject: [PATCH 118/310] My first translation update --- interface/web/tools/lib/lang/nl_index.lng | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/tools/lib/lang/nl_index.lng b/interface/web/tools/lib/lang/nl_index.lng index a3ef38f21..6c82e4db9 100644 --- a/interface/web/tools/lib/lang/nl_index.lng +++ b/interface/web/tools/lib/lang/nl_index.lng @@ -1,4 +1,4 @@ -- GitLab From d641385baff2917cd66bafadf37a4ed0970941ef Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Mon, 15 Oct 2018 16:07:51 +0200 Subject: [PATCH 119/310] Add php syntax check via GitLab CI --- .gitignore | 3 ++- .gitlab-ci.yml | 18 ++++++++++++++++++ .phplint.yml | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .gitlab-ci.yml create mode 100644 .phplint.yml diff --git a/.gitignore b/.gitignore index 1a3b8bd98..d42aee61f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .DS_Store -/nbproject/private/ \ No newline at end of file +/nbproject/private/ +.phplint-cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..1c50a28b1 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,18 @@ +# Defines stages which are to be executed +stages: + - syntax + +# +### Stage syntax +# + +syntax:lint: + stage: syntax + image: bobey/docker-gitlab-ci-runner-php7 + allow_failure: false + + script: + - composer require overtrue/phplint + - echo "Syntax checking PHP files" + - echo "For more information http://www.icosaedro.it/phplint/" + - vendor/bin/phplint diff --git a/.phplint.yml b/.phplint.yml new file mode 100644 index 000000000..10fd2a25a --- /dev/null +++ b/.phplint.yml @@ -0,0 +1,9 @@ +path: ./ +jobs: 10 +cache: .phplint-cache +extensions: + - php + - lng +exclude: + - vendor + -- GitLab From b7794d7d7b9cfb4f1c81dcd7d1f93b6693c91e35 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Mon, 15 Oct 2018 16:28:07 +0200 Subject: [PATCH 120/310] Fix 3 syntax errors in Italian lang files --- interface/web/admin/lib/lang/it_server_config.lng | 2 +- interface/web/help/lib/lang/it_support_message.lng | 2 +- interface/web/mailuser/lib/lang/it_mail_user_cc.lng | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng index b29ea0175..baacc1bb9 100644 --- a/interface/web/admin/lib/lang/it_server_config.lng +++ b/interface/web/admin/lib/lang/it_server_config.lng @@ -281,7 +281,7 @@ $wb['xmpp_port_bosh_txt'] = 'BOSH'; $wb['disable_bind_log_txt'] = 'Disable bind9 messages for Loglevel WARN'; $wb['apps_vhost_enabled_txt'] = 'Apps-vhost enabled'; $wb['backup_time_txt'] = 'Backup time'; -$wb["mailinglist_manager_txt"] = 'Gestore delle Liste' +$wb["mailinglist_manager_txt"] = 'Gestore delle Liste'; $wb['skip_le_check_txt'] = 'Skip Lets Encrypt Check'; $wb['migration_mode_txt'] = 'Server Migration Mode'; $wb['nginx_enable_pagespeed_txt'] = 'Makes Pagespeed available'; diff --git a/interface/web/help/lib/lang/it_support_message.lng b/interface/web/help/lib/lang/it_support_message.lng index 89e0b9168..60999758f 100644 --- a/interface/web/help/lib/lang/it_support_message.lng +++ b/interface/web/help/lib/lang/it_support_message.lng @@ -12,5 +12,5 @@ $wb['answer_to_support_request_txt'] = 'Hai una risposta alla richiesta di suppo $wb['answer_to_support_request_sent_txt'] = 'La tua richiesta di supporto è stata trasmessa. Non rispondere a questa email.'; $wb['support_request_sent_txt'] = 'La tua richiesta di supporto è stata trasmessa. Non rispondere a questa email.'; $wb['recipient_or_sender_email_address_not_valid_txt'] = 'Impossibile trasmettere il messaggio. Destinatario non valido.'; -$wb['subject_is_empty'] = 'L'oggetto non può essere vuoto.'; +$wb['subject_is_empty'] = 'L\'oggetto non può essere vuoto.'; ?> diff --git a/interface/web/mailuser/lib/lang/it_mail_user_cc.lng b/interface/web/mailuser/lib/lang/it_mail_user_cc.lng index 555d04143..30805635d 100644 --- a/interface/web/mailuser/lib/lang/it_mail_user_cc.lng +++ b/interface/web/mailuser/lib/lang/it_mail_user_cc.lng @@ -3,7 +3,7 @@ $wb['mailbox_cc_txt'] = 'Invia copa delle e-mail'; $wb['cc_txt'] = 'Manda copia a'; $wb['email_txt'] = 'E-mail ricevute da'; $wb['cc_error_isemail'] = 'Indirizzo e-mail non valido'; -$wb['email_is_cc_error'] = 'Specificare un indirizzo e-mail diverso dalll'attuale e-mail.'; +$wb['email_is_cc_error'] = 'Specificare un indirizzo e-mail diverso dalll\'attuale e-mail.'; $wb['name_optional_txt'] = '(Opzionale)'; $wb['cc_note_txt'] = '(Separare con una virgola e-mail multiple)'; ?> -- GitLab From 3b44e5d42ce4a0d8fcb1839fe866f4a8090bb270 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Mon, 15 Oct 2018 19:39:45 +0200 Subject: [PATCH 121/310] Update apache_ispconfig.vhost.master --- install/tpl/apache_ispconfig.vhost.master | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index 33ff3bae8..55135299f 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -94,7 +94,12 @@ NameVirtualHost *: Header set X-Frame-Options: SAMEORIGIN Header set X-XSS-Protection: "1; mode=block" Header always edit Set-Cookie (.*) "$1; HTTPOnly; Secure" - Header setifempty Strict-Transport-Security "max-age=15768000" + = 2.4.7> + Header setifempty Strict-Transport-Security "max-age=15768000" + + + Header set Strict-Transport-Security "max-age=15768000" + RequestHeader unset Proxy early -- GitLab From 8c4359bb44c1d271234ee1f13c6af56289f62b26 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 17 Oct 2018 12:03:56 -0600 Subject: [PATCH 122/310] fix getDatabaseSize() --- interface/lib/classes/db_mysql.inc.php | 25 ++++++++++++++++++------- server/lib/classes/db_mysql.inc.php | 25 ++++++++++++++++++------- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index b0ae61ef3..b03ad5567 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -654,18 +654,29 @@ class db * @return int - database-size in bytes */ public function getDatabaseSize($database_name) { - global $app; - - require_once 'lib/mysql_clientdb.conf'; - - $result = $this->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$this->escape($database_name)."'"); + global $app, $conf; + static $db=null; + + if ( ! $db ) { + $clientdb_host = ($conf['db_host']) ? $conf['db_host'] : NULL; + $clientdb_user = ($conf['db_user']) ? $conf['db_user'] : NULL; + $clientdb_password = ($conf['db_password']) ? $conf['db_password'] : NULL; + $clientdb_port = ((int)$conf['db_port']) ? (int)$conf['db_port'] : NULL; + $clientdb_flags = ($conf['db_flags'] !== NULL) ? $conf['db_flags'] : NULL; + + require_once 'lib/mysql_clientdb.conf'; + + $db = new db($clientdb_host, $clientdb_user, $clientdb_password, NULL, $clientdb_port, $clientdb_flags); + } + + $result = $db->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$db->escape($database_name)."'"); if(!$result) { - $this->_sqlerror('Unable to determine the size of database ' . $database_name); + $db->_sqlerror('Unable to determine the size of database ' . $database_name); return; } $database_size = $result->getAsRow(); $result->free(); - return $database_size[0] ? $database_size[0] : 0; + return $database_size[0] ? $database_size[0] : 0; } //** Function to fill the datalog with a full differential record. diff --git a/server/lib/classes/db_mysql.inc.php b/server/lib/classes/db_mysql.inc.php index b0ae61ef3..b03ad5567 100644 --- a/server/lib/classes/db_mysql.inc.php +++ b/server/lib/classes/db_mysql.inc.php @@ -654,18 +654,29 @@ class db * @return int - database-size in bytes */ public function getDatabaseSize($database_name) { - global $app; - - require_once 'lib/mysql_clientdb.conf'; - - $result = $this->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$this->escape($database_name)."'"); + global $app, $conf; + static $db=null; + + if ( ! $db ) { + $clientdb_host = ($conf['db_host']) ? $conf['db_host'] : NULL; + $clientdb_user = ($conf['db_user']) ? $conf['db_user'] : NULL; + $clientdb_password = ($conf['db_password']) ? $conf['db_password'] : NULL; + $clientdb_port = ((int)$conf['db_port']) ? (int)$conf['db_port'] : NULL; + $clientdb_flags = ($conf['db_flags'] !== NULL) ? $conf['db_flags'] : NULL; + + require_once 'lib/mysql_clientdb.conf'; + + $db = new db($clientdb_host, $clientdb_user, $clientdb_password, NULL, $clientdb_port, $clientdb_flags); + } + + $result = $db->_query("SELECT SUM(data_length+index_length) FROM information_schema.TABLES WHERE table_schema='".$db->escape($database_name)."'"); if(!$result) { - $this->_sqlerror('Unable to determine the size of database ' . $database_name); + $db->_sqlerror('Unable to determine the size of database ' . $database_name); return; } $database_size = $result->getAsRow(); $result->free(); - return $database_size[0] ? $database_size[0] : 0; + return $database_size[0] ? $database_size[0] : 0; } //** Function to fill the datalog with a full differential record. -- GitLab From c3be1c38b5f71d6b36c54d3480c49a9b1e76198e Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 25 Oct 2018 14:55:01 +0200 Subject: [PATCH 123/310] Fixed #5165 PHP Syntax error in "install/dist/lib/opensuse.lib.php" on line 510 --- install/dist/lib/opensuse.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index b83b24dcf..6856317f9 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -507,7 +507,7 @@ class installer_dist extends installer_base { $content = str_replace('{mysql_server_port}', $conf["mysql"]["port"], $content); $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); $content = str_replace('{hostname}', $conf['hostname'], $content); - $content = str_replace('{amavis_config_dir}', $conf['amavis']['config_dir']); + $content = str_replace('{amavis_config_dir}', $conf['amavis']['config_dir'], $content); wf($conf["amavis"]["config_dir"].'/amavisd.conf', $content); chmod($conf['amavis']['config_dir'].'/amavisd.conf', 0640); -- GitLab From d8b0b8424f1d3cdc60bd150d94df08b17f4b860d Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 15:48:31 +0200 Subject: [PATCH 124/310] - added gitlab ci file for php syntax check --- .gitlab-ci.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..7d67a3449 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,19 @@ +# Defines stages which are to be executed +stages: + - syntax + +# +### Stage syntax +# + +syntax:lint: + stage: syntax + allow_failure: false + + script: + - echo "Syntax checking PHP files" + - echo "For more information http://www.icosaedro.it/phplint/" + - shopt -s globstar + - set -e + - for x in **/*.php **/*.lng ; do php -l "$x" ; done + -- GitLab From ca6e0cc0e5a17be3f2683e9bcf704febf571a7c7 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 16:09:53 +0200 Subject: [PATCH 125/310] taken gitlab ci from merge request !827 --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7d67a3449..67263d33f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,12 +8,12 @@ stages: syntax:lint: stage: syntax + image: bobey/docker-gitlab-ci-runner-php7 allow_failure: false script: + - composer require overtrue/phplint - echo "Syntax checking PHP files" - echo "For more information http://www.icosaedro.it/phplint/" - - shopt -s globstar - - set -e - - for x in **/*.php **/*.lng ; do php -l "$x" ; done + - vendor/bin/phplint -- GitLab From 9a1f097fac4b0e1625389ff94243f26af4a3daa0 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 16:10:33 +0200 Subject: [PATCH 126/310] - taken gitlab ci config from merge request !827 --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7d67a3449..67263d33f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,12 +8,12 @@ stages: syntax:lint: stage: syntax + image: bobey/docker-gitlab-ci-runner-php7 allow_failure: false script: + - composer require overtrue/phplint - echo "Syntax checking PHP files" - echo "For more information http://www.icosaedro.it/phplint/" - - shopt -s globstar - - set -e - - for x in **/*.php **/*.lng ; do php -l "$x" ; done + - vendor/bin/phplint -- GitLab From 3121ea9f2c1af9509f4d6678a2e9fded6379ccc0 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 16:11:45 +0200 Subject: [PATCH 127/310] phplint config from merge request !827 --- .phplint.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .phplint.yml diff --git a/.phplint.yml b/.phplint.yml new file mode 100644 index 000000000..10fd2a25a --- /dev/null +++ b/.phplint.yml @@ -0,0 +1,9 @@ +path: ./ +jobs: 10 +cache: .phplint-cache +extensions: + - php + - lng +exclude: + - vendor + -- GitLab From c8e56a74d23f9f92cd15984c8f680612b653761f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 17:12:45 +0200 Subject: [PATCH 128/310] - changed gitignore file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index e43b0f988..d42aee61f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_Store +/nbproject/private/ +.phplint-cache -- GitLab From c7e7e585d2a47bc9556dbda09dbe287761e62762 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 21:45:21 +0200 Subject: [PATCH 129/310] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 4676d2bd5..e1db5c122 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # ISPConfig - Hosting Control Panel +[![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/stable-3.1/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/stable-3.1) + + - Manage multiple servers from one control panel - Web server management (Apache2 and nginx) - Mail server management (with virtual mail users) -- GitLab From 6d629dd72acfb8fbd8542d18c3881c2e227c4f73 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 21:46:32 +0200 Subject: [PATCH 130/310] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e1db5c122..9f630afb8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # ISPConfig - Hosting Control Panel -[![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/stable-3.1/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/stable-3.1) +Nightly (master): [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) +Stable branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/stable-3.1/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/stable-3.1) - Manage multiple servers from one control panel -- GitLab From fa9840215f2da74f78ca0e737b668663f7283d7a Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 21:47:35 +0200 Subject: [PATCH 131/310] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f630afb8..5c251c0e2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ISPConfig - Hosting Control Panel -Nightly (master): [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) +Nightly (master): [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) Stable branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/stable-3.1/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/stable-3.1) -- GitLab From 0bc89b9c8983b3ce03197ed0169831031fdbfa36 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 21:48:28 +0200 Subject: [PATCH 132/310] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4676d2bd5..5c251c0e2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # ISPConfig - Hosting Control Panel +Nightly (master): [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/master/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/master) +Stable branch: [![pipeline status](https://git.ispconfig.org/ispconfig/ispconfig3/badges/stable-3.1/pipeline.svg)](https://git.ispconfig.org/ispconfig/ispconfig3/commits/stable-3.1) + + - Manage multiple servers from one control panel - Web server management (Apache2 and nginx) - Mail server management (with virtual mail users) -- GitLab From 52afa697c2c7fb0f69e51781a1671ef374dcaecf Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 21:55:29 +0200 Subject: [PATCH 133/310] - limit syntax pipeline to schedules --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 67263d33f..2d4314015 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,8 @@ syntax:lint: stage: syntax image: bobey/docker-gitlab-ci-runner-php7 allow_failure: false + only: + - schedules script: - composer require overtrue/phplint -- GitLab From d6444a324aa98d16f72629a8209b77cbeca360e7 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 22:16:16 +0200 Subject: [PATCH 134/310] - loosen limits for pipelines --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2d4314015..a88522f2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -12,6 +12,9 @@ syntax:lint: allow_failure: false only: - schedules + - web + - master@ispconfig/ispconfig3 + - stable-3.1@ispconfig/ispconfig3 script: - composer require overtrue/phplint -- GitLab From 6628fb3d446d8e5397ca566a2cb2f48ef3f9a3a9 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 25 Oct 2018 22:18:09 +0200 Subject: [PATCH 135/310] - partly revert previous --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a88522f2f..736fbc308 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -13,8 +13,6 @@ syntax:lint: only: - schedules - web - - master@ispconfig/ispconfig3 - - stable-3.1@ispconfig/ispconfig3 script: - composer require overtrue/phplint -- GitLab From aa8da84a820c0afa210db1d4415b54cc4dcb1120 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sun, 28 Oct 2018 14:10:37 +0100 Subject: [PATCH 136/310] Update nginx_ispconfig.vhost.master to support TLS v1.3 and its ciphers. --- install/tpl/nginx_ispconfig.vhost.master | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/tpl/nginx_ispconfig.vhost.master b/install/tpl/nginx_ispconfig.vhost.master index 3c8bf5dba..1a59c1576 100644 --- a/install/tpl/nginx_ispconfig.vhost.master +++ b/install/tpl/nginx_ispconfig.vhost.master @@ -2,10 +2,10 @@ server { listen {vhost_port}; listen [::]:{vhost_port} ipv6only=on; ssl {ssl_on}; - {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; {ssl_comment}ssl_certificate /usr/local/ispconfig/interface/ssl/ispserver.crt; {ssl_comment}ssl_certificate_key /usr/local/ispconfig/interface/ssl/ispserver.key; - {ssl_comment}ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; + {ssl_comment}ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; {ssl_comment}ssl_prefer_server_ciphers on; # redirect to https if accessed with http -- GitLab From f5543ea0cbdd3515657d5d85c609316f1b6dda6e Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sun, 28 Oct 2018 14:13:57 +0100 Subject: [PATCH 137/310] Update apache_ispconfig.vhost.master to support TLS v1.3 ciphers --- install/tpl/apache_ispconfig.vhost.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index aff01fce1..eab55f322 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -81,7 +81,7 @@ SSLCertificateKeyFile /usr/local/ispconfig/interface/ssl/ispserver.key SSLCertificateChainFile /usr/local/ispconfig/interface/ssl/ispserver.bundle - SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS + SSLCipherSuite TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder On SSLCompression Off -- GitLab From 01df7d60d68945afb7e03566fd1d486c83af335f Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sun, 28 Oct 2018 14:18:13 +0100 Subject: [PATCH 138/310] Update nginx_vhost.conf.master to support TLS v1.3 and its ciphers --- server/conf/nginx_vhost.conf.master | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master index 4f9178698..6b4e88aae 100644 --- a/server/conf/nginx_vhost.conf.master +++ b/server/conf/nginx_vhost.conf.master @@ -28,8 +28,8 @@ server { listen : ssl{tmpl_if name='enable_http2' op='==' value='y'} http2{/tmpl_if}{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if}; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + # ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; # ssl_prefer_server_ciphers on; listen []: ssl{tmpl_if name='enable_http2' op='==' value='y'} http2{/tmpl_if}{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if}; -- GitLab From b172e3f499f76eab23b8e0fe0724ae6bb24aec87 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sun, 28 Oct 2018 14:24:34 +0100 Subject: [PATCH 139/310] Update vhost.conf.master to support TLS v1.3 ciphers --- server/conf/vhost.conf.master | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index b3ed93960..62b629045 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -47,7 +47,7 @@ Protocols h2 http/1.1 SSLProtocol All -SSLv2 -SSLv3 - SSLCipherSuite 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS' + SSLCipherSuite 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS' @@ -74,7 +74,7 @@ SSLEngine on SSLProtocol All -SSLv2 -SSLv3 - # SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS + # SSLCipherSuite TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder on # # Header always add Strict-Transport-Security "max-age=15768000" -- GitLab From c1b703e2654297bdca51188dd10ffe115aa622f3 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Tue, 30 Oct 2018 15:20:10 +0100 Subject: [PATCH 140/310] Update installer_base.lib.php to use certbot standalone to create SSL certs for ISPConfig server(s). --- install/lib/installer_base.lib.php | 65 ++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 36b0ed022..dcf880071 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2398,16 +2398,57 @@ class installer_base { } public function make_ispconfig_ssl_cert() { - global $conf,$autoinstall; - - $install_dir = $conf['ispconfig_install_dir']; - - $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; - $ssl_csr_file = $install_dir.'/interface/ssl/ispserver.csr'; - $ssl_key_file = $install_dir.'/interface/ssl/ispserver.key'; - - if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); - + global $conf, $autoinstall; + + // This hostname can be taken from user entry too + // But I don't find a way for it yet so... + // I use this for now ;D + $hostname = exec('hostname -f'); + // Check if LE SSL folder for the hostname existed + $le_live_dir = '/etc/letsencrypt/live/' . $hostname; + // Check if this is web server + $check_nginx = exec("dpkg-query -W -f='\${Status}' nginx 2>/dev/null | grep -c 'ok installed'"); + $check_apache = exec("dpkg-query -W -f='\${Status}' apache2 2>/dev/null | grep -c 'ok installed'"); + // We support certbot so create standalone LE SSL certs for this server + if (!@is_dir($le_live_dir)) { + // If it is nginx webserver + if ($check_nginx == 1) + exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service nginx stop' --post-hook 'service nginx start'"); + // If it is apache2 webserver + elseif ($check_apache2 == 1) + exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service apache2 stop' --post-hook 'service apache2 start'"); + // If it is not webserver + else + exec("certbot certonly --authenticator standalone -d $hostname"); + } + + // If the LE SSL certs for this hostname exists + if (is_dir($le_live_dir)) { + + // Define and check ISPConfig SSL folder + $install_dir = $conf['ispconfig_install_dir']; + if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); + $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; + $ssl_csr_file = $install_dir.'/interface/ssl/ispserver.csr'; + $ssl_key_file = $install_dir.'/interface/ssl/ispserver.key'; + $ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem'; + $ssl_bak_file = $install_dir.'/interface/ssl/ispserver.*.bak'; + + // Delete old then backup existing ispserver ssl files + if (is_file($ssl_bak_file)) exec("rm $ssl_bak_file"); + if (is_file($ssl_crt_file)) exec("mv $ispccrt $ssl_crt_file-$(date +'%y%m%d%H%M%S).bak"); + if (is_file($ssl_key_file)) exec("mv $ispccrt $ssl_key_file-$(date +'%y%m%d%H%M%S).bak"); + if (is_file($ssl_pem_file)) exec("mv $ispccrt $ssl_pem_file-$(date +'%y%m%d%H%M%S).bak"); + + // Create symlink to LE fullchain and key for ISPConfig + exec("ln -s $le_live_dir/fullchain.pem $ssl_crt_file"); + exec("ln -s $le_live_dir/privkey.pem $ssl_key_file"); + + // Build ispserver.pem file and chmod it + exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file") + chmod 600 $ssl_pem_file + } +/* $ssl_pw = substr(md5(mt_rand()), 0, 6); exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); if(AUTOINSTALL){ @@ -2419,8 +2460,8 @@ class installer_base { exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); rename($ssl_key_file, $ssl_key_file.'.secure'); rename($ssl_key_file.'.insecure', $ssl_key_file); - - exec('chown -R root:root /usr/local/ispconfig/interface/ssl'); +*/ + exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From 924ccf84d6eb0d88538395d1821ad5550774121d Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Tue, 30 Oct 2018 15:59:33 +0100 Subject: [PATCH 141/310] Update installer_base.lib.php to fix line 2448 & 2449 --- install/lib/installer_base.lib.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index dcf880071..b26b13eb9 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2441,12 +2441,12 @@ class installer_base { if (is_file($ssl_pem_file)) exec("mv $ispccrt $ssl_pem_file-$(date +'%y%m%d%H%M%S).bak"); // Create symlink to LE fullchain and key for ISPConfig - exec("ln -s $le_live_dir/fullchain.pem $ssl_crt_file"); - exec("ln -s $le_live_dir/privkey.pem $ssl_key_file"); + exec("ln -sf $le_live_dir/fullchain.pem $ssl_crt_file"); + exec("ln -sf $le_live_dir/privkey.pem $ssl_key_file"); // Build ispserver.pem file and chmod it - exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file") - chmod 600 $ssl_pem_file + exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file"); + exec("chmod 600 $ssl_pem_file"); } /* $ssl_pw = substr(md5(mt_rand()), 0, 6); -- GitLab From 7a60aea149f38b059e1c70276cb2608737a70f21 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Tue, 30 Oct 2018 16:33:10 +0100 Subject: [PATCH 142/310] Update installer_base.lib.php to fix lines 2439-2441; remove line with .csr; use $conf['hostname'] if not localhost or empty. --- install/lib/installer_base.lib.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index b26b13eb9..ca60d4b17 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2403,19 +2403,19 @@ class installer_base { // This hostname can be taken from user entry too // But I don't find a way for it yet so... // I use this for now ;D - $hostname = exec('hostname -f'); + if($conf['hostname'] !== ('localhost' || '') ) $hostname = $conf['hostname']; + else $hostname = exec('hostname -f'); + // Check if LE SSL folder for the hostname existed $le_live_dir = '/etc/letsencrypt/live/' . $hostname; - // Check if this is web server - $check_nginx = exec("dpkg-query -W -f='\${Status}' nginx 2>/dev/null | grep -c 'ok installed'"); - $check_apache = exec("dpkg-query -W -f='\${Status}' apache2 2>/dev/null | grep -c 'ok installed'"); + // We support certbot so create standalone LE SSL certs for this server if (!@is_dir($le_live_dir)) { // If it is nginx webserver - if ($check_nginx == 1) + if($conf['nginx']['installed'] == true) exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service nginx stop' --post-hook 'service nginx start'"); // If it is apache2 webserver - elseif ($check_apache2 == 1) + elseif($conf['apache']['installed'] == true) exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service apache2 stop' --post-hook 'service apache2 start'"); // If it is not webserver else @@ -2428,17 +2428,17 @@ class installer_base { // Define and check ISPConfig SSL folder $install_dir = $conf['ispconfig_install_dir']; if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); + $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; - $ssl_csr_file = $install_dir.'/interface/ssl/ispserver.csr'; $ssl_key_file = $install_dir.'/interface/ssl/ispserver.key'; $ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem'; $ssl_bak_file = $install_dir.'/interface/ssl/ispserver.*.bak'; // Delete old then backup existing ispserver ssl files if (is_file($ssl_bak_file)) exec("rm $ssl_bak_file"); - if (is_file($ssl_crt_file)) exec("mv $ispccrt $ssl_crt_file-$(date +'%y%m%d%H%M%S).bak"); - if (is_file($ssl_key_file)) exec("mv $ispccrt $ssl_key_file-$(date +'%y%m%d%H%M%S).bak"); - if (is_file($ssl_pem_file)) exec("mv $ispccrt $ssl_pem_file-$(date +'%y%m%d%H%M%S).bak"); + if (is_file($ssl_crt_file)) exec("mv $ssl_crt_file-\$(date +'%y%m%d%H%M%S).bak"); + if (is_file($ssl_key_file)) exec("mv $ssl_key_file-\$(date +'%y%m%d%H%M%S).bak"); + if (is_file($ssl_pem_file)) exec("mv $ssl_pem_file-\$(date +'%y%m%d%H%M%S).bak"); // Create symlink to LE fullchain and key for ISPConfig exec("ln -sf $le_live_dir/fullchain.pem $ssl_crt_file"); -- GitLab From e5d96e0385a6ac2a23cfb8a46a55a9e0313f562a Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:10:30 +0100 Subject: [PATCH 143/310] Update installer_base.lib.php as per the discussions / feedback in the thread at https://www.howtoforge.com/community/threads/wip-use-certbot-standalone-to-create-lets-encrypt-ssl-certs-for-ispconfig-servers.80449 by adding check whether the hostname fqdn A record has the same ip with the server before requesting for Let's Encrypt SSL standalone certs. --- install/lib/installer_base.lib.php | 65 +++++++++++++++++------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index ca60d4b17..914799cdc 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2400,17 +2400,20 @@ class installer_base { public function make_ispconfig_ssl_cert() { global $conf, $autoinstall; - // This hostname can be taken from user entry too - // But I don't find a way for it yet so... - // I use this for now ;D + // Get hostname from user entry or shell command if($conf['hostname'] !== ('localhost' || '') ) $hostname = $conf['hostname']; else $hostname = exec('hostname -f'); + // Check dns a record exist and its ip equal to server public ip + $svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip'); + if (checkdnsrr(idn_to_ascii($hostname), 'A')) { + $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; + } // Check if LE SSL folder for the hostname existed $le_live_dir = '/etc/letsencrypt/live/' . $hostname; - // We support certbot so create standalone LE SSL certs for this server - if (!@is_dir($le_live_dir)) { + // We support certbot so let's create standalone LE SSL certs for this server + if (!@is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { // If it is nginx webserver if($conf['nginx']['installed'] == true) exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service nginx stop' --post-hook 'service nginx start'"); @@ -2421,20 +2424,21 @@ class installer_base { else exec("certbot certonly --authenticator standalone -d $hostname"); } + + // Define and check ISPConfig SSL folder + $install_dir = $conf['ispconfig_install_dir']; + + $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; + $ssl_csr_file = $install_dir.'/interface/ssl/ispserver.csr'; + $ssl_key_file = $install_dir.'/interface/ssl/ispserver.key'; + $ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem'; + + if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); // If the LE SSL certs for this hostname exists - if (is_dir($le_live_dir)) { - - // Define and check ISPConfig SSL folder - $install_dir = $conf['ispconfig_install_dir']; - if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); - - $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; - $ssl_key_file = $install_dir.'/interface/ssl/ispserver.key'; - $ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem'; - $ssl_bak_file = $install_dir.'/interface/ssl/ispserver.*.bak'; - - // Delete old then backup existing ispserver ssl files + if (is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { + + // Backup existing ispserver ssl files if (is_file($ssl_bak_file)) exec("rm $ssl_bak_file"); if (is_file($ssl_crt_file)) exec("mv $ssl_crt_file-\$(date +'%y%m%d%H%M%S).bak"); if (is_file($ssl_key_file)) exec("mv $ssl_key_file-\$(date +'%y%m%d%H%M%S).bak"); @@ -2448,19 +2452,22 @@ class installer_base { exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file"); exec("chmod 600 $ssl_pem_file"); } -/* - $ssl_pw = substr(md5(mt_rand()), 0, 6); - exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); - if(AUTOINSTALL){ - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); - } else { - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); + + if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { + + // We can still use the old self-signed method + $ssl_pw = substr(md5(mt_rand()), 0, 6); + exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); + if(AUTOINSTALL){ + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); + } else { + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); + } + exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); + exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); + rename($ssl_key_file, $ssl_key_file.'.secure'); + rename($ssl_key_file.'.insecure', $ssl_key_file); } - exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); - exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); - rename($ssl_key_file, $ssl_key_file.'.secure'); - rename($ssl_key_file.'.insecure', $ssl_key_file); -*/ exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From caa7b711baa71bedf5a23b5506fd8f3e4ef2422f Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:42:27 +0100 Subject: [PATCH 144/310] Update installer_base.lib.php to use php instead of cli / shell command in renaming files and creating symlinks. --- install/lib/installer_base.lib.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 914799cdc..c46454891 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2409,17 +2409,20 @@ class installer_base { if (checkdnsrr(idn_to_ascii($hostname), 'A')) { $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; } + // Check if LE SSL folder for the hostname existed + // Then create standalone LE SSL certs for this server $le_live_dir = '/etc/letsencrypt/live/' . $hostname; - - // We support certbot so let's create standalone LE SSL certs for this server if (!@is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { + // If it is nginx webserver if($conf['nginx']['installed'] == true) exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service nginx stop' --post-hook 'service nginx start'"); + // If it is apache2 webserver elseif($conf['apache']['installed'] == true) exec("certbot certonly --authenticator standalone -d $hostname --pre-hook 'service apache2 stop' --post-hook 'service apache2 start'"); + // If it is not webserver else exec("certbot certonly --authenticator standalone -d $hostname"); @@ -2439,18 +2442,17 @@ class installer_base { if (is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { // Backup existing ispserver ssl files - if (is_file($ssl_bak_file)) exec("rm $ssl_bak_file"); - if (is_file($ssl_crt_file)) exec("mv $ssl_crt_file-\$(date +'%y%m%d%H%M%S).bak"); - if (is_file($ssl_key_file)) exec("mv $ssl_key_file-\$(date +'%y%m%d%H%M%S).bak"); - if (is_file($ssl_pem_file)) exec("mv $ssl_pem_file-\$(date +'%y%m%d%H%M%S).bak"); + $date = new DateTime(); + if (file_exists($ssl_crt_file)) rename($ssl_crt_file, $ssl_crt_file . '-' .$date->format('YmdHis') . '.bak'); + if (file_exists($ssl_crt_file)) rename($ssl_key_file, $ssl_key_file . '-' .$date->format('YmdHis') . '.bak'); + if (file_exists($ssl_crt_file)) rename($ssl_pem_file, $ssl_pem_file . '-' .$date->format('YmdHis') . '.bak'); // Create symlink to LE fullchain and key for ISPConfig - exec("ln -sf $le_live_dir/fullchain.pem $ssl_crt_file"); - exec("ln -sf $le_live_dir/privkey.pem $ssl_key_file"); + symlink($le_live_dir.'/fullchain.pem', $ssl_crt_file); + symlink($le_live_dir.'/privkey.pem', $ssl_key_file); // Build ispserver.pem file and chmod it - exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file"); - exec("chmod 600 $ssl_pem_file"); + exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); } if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { -- GitLab From c2aabf76ae8f367aa930e782eabb564da931f5c2 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:47:03 +0100 Subject: [PATCH 145/310] Update installer_base.lib.php to tidy up missing tabs --- install/lib/installer_base.lib.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index c46454891..7e9e26f0a 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2456,19 +2456,19 @@ class installer_base { } if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { - - // We can still use the old self-signed method - $ssl_pw = substr(md5(mt_rand()), 0, 6); - exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); - if(AUTOINSTALL){ - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); - } else { - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); - } - exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); - exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); - rename($ssl_key_file, $ssl_key_file.'.secure'); - rename($ssl_key_file.'.insecure', $ssl_key_file); + + // We can still use the old self-signed method + $ssl_pw = substr(md5(mt_rand()), 0, 6); + exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); + if(AUTOINSTALL){ + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); + } else { + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); + } + exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); + exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); + rename($ssl_key_file, $ssl_key_file.'.secure'); + rename($ssl_key_file.'.insecure', $ssl_key_file); } exec("chown -R root:root $install_dir/interface/ssl"); -- GitLab From 713bda97ca3fbdf370c9f59923667a7b286dcc11 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:49:22 +0100 Subject: [PATCH 146/310] Update installer_base.lib.php --- install/lib/installer_base.lib.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 7e9e26f0a..e6563a66a 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2407,7 +2407,7 @@ class installer_base { // Check dns a record exist and its ip equal to server public ip $svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip'); if (checkdnsrr(idn_to_ascii($hostname), 'A')) { - $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; + $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; } // Check if LE SSL folder for the hostname existed @@ -2454,22 +2454,22 @@ class installer_base { // Build ispserver.pem file and chmod it exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); } - + if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { // We can still use the old self-signed method $ssl_pw = substr(md5(mt_rand()), 0, 6); exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); if(AUTOINSTALL){ - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); } else { - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); } exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); rename($ssl_key_file, $ssl_key_file.'.secure'); rename($ssl_key_file.'.insecure', $ssl_key_file); - } + } exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From 240f69d0006606093d3570be01d28461fa417425 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:51:17 +0100 Subject: [PATCH 147/310] Update installer_base.lib.php --- install/lib/installer_base.lib.php | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index e6563a66a..b086135dc 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2456,20 +2456,21 @@ class installer_base { } if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { - - // We can still use the old self-signed method - $ssl_pw = substr(md5(mt_rand()), 0, 6); - exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); - if(AUTOINSTALL){ - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); - } else { - exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); - } - exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); - exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); - rename($ssl_key_file, $ssl_key_file.'.secure'); - rename($ssl_key_file.'.insecure', $ssl_key_file); - } + + // We can still use the old self-signed method + $ssl_pw = substr(md5(mt_rand()), 0, 6); + exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); + if(AUTOINSTALL){ + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -key $ssl_key_file -out $ssl_csr_file"); + } else { + exec("openssl req -new -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -out $ssl_csr_file"); + } + exec("openssl req -x509 -passin pass:$ssl_pw -passout pass:$ssl_pw -key $ssl_key_file -in $ssl_csr_file -out $ssl_crt_file -days 3650"); + exec("openssl rsa -passin pass:$ssl_pw -in $ssl_key_file -out $ssl_key_file.insecure"); + rename($ssl_key_file, $ssl_key_file.'.secure'); + rename($ssl_key_file.'.insecure', $ssl_key_file); + } + exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From 497136b4a5fc7d4878e46f412568f8961b725617 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 04:53:02 +0100 Subject: [PATCH 148/310] Update installer_base.lib.php --- install/lib/installer_base.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index b086135dc..90413fe73 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2407,7 +2407,7 @@ class installer_base { // Check dns a record exist and its ip equal to server public ip $svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip'); if (checkdnsrr(idn_to_ascii($hostname), 'A')) { - $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; + $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; } // Check if LE SSL folder for the hostname existed -- GitLab From f93c38240b351a0ef3cec3baba353d9bf8b40db7 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 06:24:33 +0100 Subject: [PATCH 149/310] Update installer_base.lib.php to change if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) to else. --- install/lib/installer_base.lib.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 90413fe73..5537dafff 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2427,6 +2427,8 @@ class installer_base { else exec("certbot certonly --authenticator standalone -d $hostname"); } + // TODO: To implement webroot instead of standalone via + // probably ispconfig vhost to provide for port 80 && 443 // Define and check ISPConfig SSL folder $install_dir = $conf['ispconfig_install_dir']; @@ -2453,9 +2455,8 @@ class installer_base { // Build ispserver.pem file and chmod it exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); - } - - if (!@is_dir($le_live_dir) && ($svr_ip != $dns_ip)) { + + } else { // We can still use the old self-signed method $ssl_pw = substr(md5(mt_rand()), 0, 6); -- GitLab From 89a6f6efd47b80427211189fb3bda6c1b0bd85f4 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 08:07:12 +0100 Subject: [PATCH 150/310] Update installer_base.lib.php to replace ssl on / off that is already deprecated in Nginx 1.15 with ' ssl' / '' and to change the same in nginx_ispconfig.vhost.master as well. --- install/lib/installer_base.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 36b0ed022..f74192138 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2367,7 +2367,7 @@ class installer_base { $content = str_replace('{use_socket}', $use_socket, $content); // SSL in apps vhost is off by default. Might change later. - $content = str_replace('{ssl_on}', 'off', $content); + $content = str_replace('{ssl_on}', '', $content); $content = str_replace('{ssl_comment}', '#', $content); // Fix socket path on PHP 7 systems @@ -2802,11 +2802,11 @@ class installer_base { $content = str_replace('{vhost_port}', $conf['nginx']['vhost_port'], $content); if(is_file($install_dir.'/interface/ssl/ispserver.crt') && is_file($install_dir.'/interface/ssl/ispserver.key')) { - $content = str_replace('{ssl_on}', 'on', $content); + $content = str_replace('{ssl_on}', ' ssl', $content); $content = str_replace('{ssl_comment}', '', $content); $content = str_replace('{fastcgi_ssl}', 'on', $content); } else { - $content = str_replace('{ssl_on}', 'off', $content); + $content = str_replace('{ssl_on}', '', $content); $content = str_replace('{ssl_comment}', '#', $content); $content = str_replace('{fastcgi_ssl}', 'off', $content); } -- GitLab From 694c2c563eef007ad9fac91f4f608408ee194051 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 08:10:29 +0100 Subject: [PATCH 151/310] Update nginx_ispconfig.vhost.master to change the same in nginx_ispconfig.vhost.master and to change the same in installer_base.lib.php as well. --- install/tpl/nginx_ispconfig.vhost.master | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/tpl/nginx_ispconfig.vhost.master b/install/tpl/nginx_ispconfig.vhost.master index 1a59c1576..edd9471d3 100644 --- a/install/tpl/nginx_ispconfig.vhost.master +++ b/install/tpl/nginx_ispconfig.vhost.master @@ -1,7 +1,7 @@ server { - listen {vhost_port}; - listen [::]:{vhost_port} ipv6only=on; - ssl {ssl_on}; + listen {vhost_port}{ssl_on}; + listen [::]:{vhost_port} ipv6only=on{ssl_on}; + {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; {ssl_comment}ssl_certificate /usr/local/ispconfig/interface/ssl/ispserver.crt; {ssl_comment}ssl_certificate_key /usr/local/ispconfig/interface/ssl/ispserver.key; -- GitLab From 96f1ab06f82fde336520660d97568bc36f36f00f Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 14:07:12 +0100 Subject: [PATCH 152/310] Update installer_base.lib.php to fix line 2409-2410. --- install/lib/installer_base.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 5537dafff..379263a94 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2406,8 +2406,8 @@ class installer_base { // Check dns a record exist and its ip equal to server public ip $svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip'); - if (checkdnsrr(idn_to_ascii($hostname), 'A')) { - $dns_A=dns_get_record($hostname, DNS_A); $dns_ip=$dns_A[0][ip]; + if (checkdnsrr(idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46), 'A')) { + $dnsa=dns_get_record($hostname, DNS_A); $dns_ip=$dnsa[0]['ip']; } // Check if LE SSL folder for the hostname existed -- GitLab From e4fe8d9c49a185f75d9dafaab0225b286beabd5d Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 17:14:24 +0100 Subject: [PATCH 153/310] Update installer_base.lib.php accordingly to [Jesse Norell's suggestion](https://www.howtoforge.com/community/threads/wip-use-certbot-standalone-to-create-lets-encrypt-ssl-certs-for-ispconfig-servers.80449/#post-381238) which is supposedly more prudent. --- install/lib/installer_base.lib.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 379263a94..6e4176adf 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2401,19 +2401,23 @@ class installer_base { global $conf, $autoinstall; // Get hostname from user entry or shell command - if($conf['hostname'] !== ('localhost' || '') ) $hostname = $conf['hostname']; + if($conf['hostname'] !== ('localhost' || '')) $hostname = $conf['hostname']; else $hostname = exec('hostname -f'); // Check dns a record exist and its ip equal to server public ip $svr_ip = file_get_contents('http://dynamicdns.park-your-domain.com/getip'); if (checkdnsrr(idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46), 'A')) { - $dnsa=dns_get_record($hostname, DNS_A); $dns_ip=$dnsa[0]['ip']; + $dnsa=dns_get_record($hostname, DNS_A); + $dns_ips = array(); + foreach ($dnsa as $rec) { + $dns_ips[] = $rec['ip']; + } } // Check if LE SSL folder for the hostname existed // Then create standalone LE SSL certs for this server $le_live_dir = '/etc/letsencrypt/live/' . $hostname; - if (!@is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { + if (!@is_dir($le_live_dir) && in_array($srv_ip, $dns_ips)) { // If it is nginx webserver if($conf['nginx']['installed'] == true) @@ -2441,7 +2445,7 @@ class installer_base { if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); // If the LE SSL certs for this hostname exists - if (is_dir($le_live_dir) && ($svr_ip = $dns_ip)) { + if (is_dir($le_live_dir) && in_array($srv_ip, $dns_ips)) { // Backup existing ispserver ssl files $date = new DateTime(); -- GitLab From 2c08b06d3632b9a39466e6261088561c62677422 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Wed, 31 Oct 2018 17:16:20 +0100 Subject: [PATCH 154/310] Update installer_base.lib.php --- install/lib/installer_base.lib.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 6e4176adf..2fb7b2aa5 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2409,9 +2409,9 @@ class installer_base { if (checkdnsrr(idn_to_ascii($hostname, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46), 'A')) { $dnsa=dns_get_record($hostname, DNS_A); $dns_ips = array(); - foreach ($dnsa as $rec) { - $dns_ips[] = $rec['ip']; - } + foreach ($dnsa as $rec) { + $dns_ips[] = $rec['ip']; + } } // Check if LE SSL folder for the hostname existed -- GitLab From 9c5fbe7be7ef57a139a6df000fdf2025144c90ad Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Thu, 1 Nov 2018 05:32:27 +0100 Subject: [PATCH 155/310] Update installer_base.lib.php to fix typo error and add code to extend ISPConfig LE SSL certs to other services that are postfix and pureftpd, if they are installed. The code give user option whether to extend the certs or not. --- install/lib/installer_base.lib.php | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 2fb7b2aa5..801a37ab5 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2417,7 +2417,7 @@ class installer_base { // Check if LE SSL folder for the hostname existed // Then create standalone LE SSL certs for this server $le_live_dir = '/etc/letsencrypt/live/' . $hostname; - if (!@is_dir($le_live_dir) && in_array($srv_ip, $dns_ips)) { + if (!@is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) { // If it is nginx webserver if($conf['nginx']['installed'] == true) @@ -2445,7 +2445,7 @@ class installer_base { if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); // If the LE SSL certs for this hostname exists - if (is_dir($le_live_dir) && in_array($srv_ip, $dns_ips)) { + if (is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) { // Backup existing ispserver ssl files $date = new DateTime(); @@ -2460,6 +2460,44 @@ class installer_base { // Build ispserver.pem file and chmod it exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); + + + // Extend LE SSL certs to postfix + if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y')) { + + // Define folder, file(s) + $cf = $conf['postfix']; + $postfix_dir = $cf['config_dir']; + if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist."); + $smtpd_crt = $postfix_dir.'/smtpd.cert'; + $smtpd_key = $postfix_dir.'/smtpd.key'; + + // Backup existing postfix ssl files + if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak'); + if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_crt_file, $smtpd_crt); + symlink($ssl_key_file, $smtpd_key); + } + + // Extend LE SSL certs to pureftpd + if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times.', array('y', 'n'), 'y')) == 'y') { + + // Define folder, file(s) + $pureftpd_dir = '/etc/ssl/private'; + if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); + $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; + + // Backup existing postfix ssl files + if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_pem_file, $pureftpd_pem); + if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem")) + exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem"); + } + } else { // We can still use the old self-signed method -- GitLab From 301dfb7d29d7d6700928510533b1a95b3a6c75de Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Fri, 2 Nov 2018 16:27:11 +0100 Subject: [PATCH 156/310] Update installer_base.lib.php for ISPConfig to use certbot webroot for webservers and certbot standalone for other servers. Also extend the certs for postfix, dovecot and pure-ftpd-mysql. --- install/lib/installer_base.lib.php | 152 +++++++++++++++++------------ 1 file changed, 89 insertions(+), 63 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 801a37ab5..042768873 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -1,7 +1,7 @@ 99) { + $extra_domains = array_slice($extra_domains, 0, 99); + echo "\nExtra domains exceed limits. Only the first 99 will be expanded into the hostname FQDN cert.\n"; + } + foreach($extra_domains as $le_domain) $cli_domain_arg .= (string) ' -d ' . $le_domain; + } + + // Get the default LE client name and version + $le_client = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); + $le_client = reset($le_client); + $le_info = exec($le_client . ' --version 2>&1', $ret, $val); + if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $le_info, $matches)) { $le_name = $matches[1]; $le_version = $matches[2]; } + $acme_version = '--server https://acme-v0' . (($le_version >=0.22) ? '2' : '1') . '.api.letsencrypt.org/directory'; + $certonly = 'certonly --agree-tos --non-interactive --expand --rsa-key-size 4096'; + $webroot = '--authenticator webroot --webroot-path /var/www/html'; + $standalone = '--authenticator standalone'; + + // Only certbot is supported to prevent unknown failures + if($le_name == 'certbot' && is_executable($le_client)) { + // If this is a webserver, we use webroot + if(($conf['nginx']['installed'] || $conf['apache']['installed']) == true) { + $well_known = '/var/www/html/.well-known'; + $challenge = "$well_known/acme_challenge"; + $acme_challenge = '/usr/local/ispconfig/interface/acme/.well-known/acme-challenge'; + if (!is_dir($well_known)) mkdir($well_known, 0755, true); + if (!is_dir($challenge)) exec("ln -sf $acme_challenge $challenge"); + exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname $cli_domain_arg"); + } + // Else, it is not webserver, so we use standalone + else + exec("$le_client $certonly $acme_version $standalone --email postmaster@$hostname -d $hostname $cli_domain_arg"); + } } - // TODO: To implement webroot instead of standalone via - // probably ispconfig vhost to provide for port 80 && 443 - // Define and check ISPConfig SSL folder + //* Define and check ISPConfig SSL folder */ $install_dir = $conf['ispconfig_install_dir']; $ssl_crt_file = $install_dir.'/interface/ssl/ispserver.crt'; @@ -2443,63 +2470,62 @@ class installer_base { $ssl_pem_file = $install_dir.'/interface/ssl/ispserver.pem'; if(!@is_dir($install_dir.'/interface/ssl')) mkdir($install_dir.'/interface/ssl', 0755, true); - + + $date = new DateTime(); + // If the LE SSL certs for this hostname exists if (is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) { - + // Backup existing ispserver ssl files - $date = new DateTime(); if (file_exists($ssl_crt_file)) rename($ssl_crt_file, $ssl_crt_file . '-' .$date->format('YmdHis') . '.bak'); if (file_exists($ssl_crt_file)) rename($ssl_key_file, $ssl_key_file . '-' .$date->format('YmdHis') . '.bak'); if (file_exists($ssl_crt_file)) rename($ssl_pem_file, $ssl_pem_file . '-' .$date->format('YmdHis') . '.bak'); - + // Create symlink to LE fullchain and key for ISPConfig symlink($le_live_dir.'/fullchain.pem', $ssl_crt_file); symlink($le_live_dir.'/privkey.pem', $ssl_key_file); // Build ispserver.pem file and chmod it exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); - - - + // Extend LE SSL certs to postfix - if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y')) { - - // Define folder, file(s) - $cf = $conf['postfix']; - $postfix_dir = $cf['config_dir']; - if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist."); - $smtpd_crt = $postfix_dir.'/smtpd.cert'; - $smtpd_key = $postfix_dir.'/smtpd.key'; - - // Backup existing postfix ssl files - if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak'); - if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak'); - - // Create symlink to ISPConfig SSL files - symlink($ssl_crt_file, $smtpd_crt); - symlink($ssl_key_file, $smtpd_key); - } - + if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y') { + + // Define folder, file(s) + $cf = $conf['postfix']; + $postfix_dir = $cf['config_dir']; + if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist."); + $smtpd_crt = $postfix_dir.'/smtpd.cert'; + $smtpd_key = $postfix_dir.'/smtpd.key'; + + // Backup existing postfix ssl files + if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak'); + if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_crt_file, $smtpd_crt); + symlink($ssl_key_file, $smtpd_key); + } + // Extend LE SSL certs to pureftpd if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times.', array('y', 'n'), 'y')) == 'y') { - - // Define folder, file(s) - $pureftpd_dir = '/etc/ssl/private'; - if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); - $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; - - // Backup existing postfix ssl files - if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); - - // Create symlink to ISPConfig SSL files - symlink($ssl_pem_file, $pureftpd_pem); - if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem")) - exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem"); - } - + + // Define folder, file(s) + $pureftpd_dir = '/etc/ssl/private'; + if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); + $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; + + // Backup existing postfix ssl files + if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_pem_file, $pureftpd_pem); + if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem")) + exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem"); + } + } else { - + // We can still use the old self-signed method $ssl_pw = substr(md5(mt_rand()), 0, 6); exec("openssl genrsa -des3 -passout pass:$ssl_pw -out $ssl_key_file 4096"); @@ -2513,7 +2539,7 @@ class installer_base { rename($ssl_key_file, $ssl_key_file.'.secure'); rename($ssl_key_file.'.insecure', $ssl_key_file); } - + exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From 804cfa66c23b2d934c4cd2739c90e0885bd7be56 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Fri, 2 Nov 2018 17:09:34 +0100 Subject: [PATCH 157/310] Update installer_base.lib.php to remove support for multi domain since it requires working vhost / conf for the added domains. --- install/lib/installer_base.lib.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 042768873..63df56e63 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2418,13 +2418,16 @@ class installer_base { $le_live_dir = '/etc/letsencrypt/live/' . $hostname; if (!@is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) { - // Try to support for multi domain, if it is defined in letsencrypt_domains.master + /* // Try to support for multi domain, if it is defined in letsencrypt_domains.master + // Should try to get from ISPConfig database later on $domain_file = '/usr/local/ispconfig/server/conf-custom/letsencrypt_domains.master'; $cli_domain_arg = ''; // If file exist, get the unique domains but not more then 99 + // This won't work if the domain don't have working vhost / conf file + // In other words this won't work on non web-server if (file_exists($domain_file)) { - $extra_domains = file($domain_file, FILE_IGNORE_NEW_LINES); + $extra_domains = file($domain_file, FILE_SKIP_EMPTY_LINES); $extra_domains = array_unique($extra_domains); $le_domain_count = count($extra_domains); if($le_domain_count > 99) { @@ -2432,7 +2435,7 @@ class installer_base { echo "\nExtra domains exceed limits. Only the first 99 will be expanded into the hostname FQDN cert.\n"; } foreach($extra_domains as $le_domain) $cli_domain_arg .= (string) ' -d ' . $le_domain; - } + } */ // Get the default LE client name and version $le_client = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); @@ -2453,11 +2456,12 @@ class installer_base { $acme_challenge = '/usr/local/ispconfig/interface/acme/.well-known/acme-challenge'; if (!is_dir($well_known)) mkdir($well_known, 0755, true); if (!is_dir($challenge)) exec("ln -sf $acme_challenge $challenge"); - exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname $cli_domain_arg"); + //exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname $cli_domain_arg"); + exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname"); } // Else, it is not webserver, so we use standalone else - exec("$le_client $certonly $acme_version $standalone --email postmaster@$hostname -d $hostname $cli_domain_arg"); + exec("$le_client $certonly $acme_version $standalone --email postmaster@$hostname -d $hostname"); } } -- GitLab From 5251944242ffe0ee9ee02c10424d376528fc7d08 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Sat, 3 Nov 2018 04:40:26 +0100 Subject: [PATCH 158/310] Update installer_base.lib.php to finalize removal multi domain support. --- install/lib/installer_base.lib.php | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 63df56e63..4912f43d8 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2418,30 +2418,13 @@ class installer_base { $le_live_dir = '/etc/letsencrypt/live/' . $hostname; if (!@is_dir($le_live_dir) && in_array($svr_ip, $dns_ips)) { - /* // Try to support for multi domain, if it is defined in letsencrypt_domains.master - // Should try to get from ISPConfig database later on - $domain_file = '/usr/local/ispconfig/server/conf-custom/letsencrypt_domains.master'; - $cli_domain_arg = ''; - - // If file exist, get the unique domains but not more then 99 - // This won't work if the domain don't have working vhost / conf file - // In other words this won't work on non web-server - if (file_exists($domain_file)) { - $extra_domains = file($domain_file, FILE_SKIP_EMPTY_LINES); - $extra_domains = array_unique($extra_domains); - $le_domain_count = count($extra_domains); - if($le_domain_count > 99) { - $extra_domains = array_slice($extra_domains, 0, 99); - echo "\nExtra domains exceed limits. Only the first 99 will be expanded into the hostname FQDN cert.\n"; - } - foreach($extra_domains as $le_domain) $cli_domain_arg .= (string) ' -d ' . $le_domain; - } */ - // Get the default LE client name and version $le_client = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); $le_client = reset($le_client); $le_info = exec($le_client . ' --version 2>&1', $ret, $val); if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $le_info, $matches)) { $le_name = $matches[1]; $le_version = $matches[2]; } + + // Define certbot commands $acme_version = '--server https://acme-v0' . (($le_version >=0.22) ? '2' : '1') . '.api.letsencrypt.org/directory'; $certonly = 'certonly --agree-tos --non-interactive --expand --rsa-key-size 4096'; $webroot = '--authenticator webroot --webroot-path /var/www/html'; @@ -2456,7 +2439,6 @@ class installer_base { $acme_challenge = '/usr/local/ispconfig/interface/acme/.well-known/acme-challenge'; if (!is_dir($well_known)) mkdir($well_known, 0755, true); if (!is_dir($challenge)) exec("ln -sf $acme_challenge $challenge"); - //exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname $cli_domain_arg"); exec("$le_client $certonly $acme_version $webroot --email postmaster@$hostname -d $hostname"); } // Else, it is not webserver, so we use standalone @@ -2519,7 +2501,7 @@ class installer_base { if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; - // Backup existing postfix ssl files + // Backup existing pureftpd ssl files if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); // Create symlink to ISPConfig SSL files -- GitLab From 794b7c2119f6426a129fad851c88e18b5aed4a75 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Mon, 5 Nov 2018 13:37:28 +0100 Subject: [PATCH 159/310] Update install.php to support creating and extending LE SSL certs on ISPConfig non-webservers --- install/install.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/install/install.php b/install/install.php index 524918454..ff4f81731 100644 --- a/install/install.php +++ b/install/install.php @@ -597,6 +597,13 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPCon $inst->install_ispconfig_interface = false; } +// Create SSL certs for non-webserver(s)? +if(($conf['apache']['installed'] && $conf['apache']['installed']) == false) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { + $inst->make_ispconfig_ssl_cert(); + } +} + $inst->install_ispconfig(); //* Configure DBServer -- GitLab From 7eb8f4e95c85f680c1884adfe82c634a02baada1 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Mon, 5 Nov 2018 13:39:10 +0100 Subject: [PATCH 160/310] Update update.php to support creating and extending LE SSL certs on ISPConfig non-webservers --- install/update.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/install/update.php b/install/update.php index 3361c3c19..616bef6a2 100644 --- a/install/update.php +++ b/install/update.php @@ -524,6 +524,13 @@ if ($inst->install_ispconfig_interface) { } } +// Create SSL certs for non-webserver(s) ? +if(($conf['apache']['installed'] && $conf['apache']['installed']) == false) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { + $inst->make_ispconfig_ssl_cert(); + } +} + $inst->install_ispconfig(); // Cleanup -- GitLab From b30aaafec37512f9e4df6ff8b7fa7ba6d7ca7304 Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Mon, 5 Nov 2018 15:09:07 +0100 Subject: [PATCH 161/310] Update installer_base.lib.php to remove the creation of postfix self-signed cert prior to ISPConfig to avoid duplicity and time consuming, as it is now replaced and covered in function make_ispconfig_ssl_cert() via symlinks to the related files. --- install/lib/installer_base.lib.php | 97 +++++++++++++----------------- 1 file changed, 41 insertions(+), 56 deletions(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 4912f43d8..38a60263f 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -1120,21 +1120,6 @@ class installer_base { caselog($command." &> /dev/null", __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - if(!stristr($options, 'dont-create-certs')) { - //* Create the SSL certificate - if(AUTOINSTALL){ - $command = 'cd '.$config_dir.'; ' - ."openssl req -new -subj '/C=".escapeshellcmd($autoinstall['ssl_cert_country'])."/ST=".escapeshellcmd($autoinstall['ssl_cert_state'])."/L=".escapeshellcmd($autoinstall['ssl_cert_locality'])."/O=".escapeshellcmd($autoinstall['ssl_cert_organisation'])."/OU=".escapeshellcmd($autoinstall['ssl_cert_organisation_unit'])."/CN=".escapeshellcmd($autoinstall['ssl_cert_common_name'])."' -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509"; - } else { - $command = 'cd '.$config_dir.'; ' - .'openssl req -new -outform PEM -out smtpd.cert -newkey rsa:4096 -nodes -keyout smtpd.key -keyform PEM -days 3650 -x509'; - } - exec($command); - - $command = 'chmod o= '.$config_dir.'/smtpd.key'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - } - //** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. $command = 'chmod 755 /var/run/courier/authdaemon/'; if(is_file('/var/run/courier/authdaemon/')) caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); @@ -2471,45 +2456,6 @@ class installer_base { symlink($le_live_dir.'/fullchain.pem', $ssl_crt_file); symlink($le_live_dir.'/privkey.pem', $ssl_key_file); - // Build ispserver.pem file and chmod it - exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); - - // Extend LE SSL certs to postfix - if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y') { - - // Define folder, file(s) - $cf = $conf['postfix']; - $postfix_dir = $cf['config_dir']; - if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist."); - $smtpd_crt = $postfix_dir.'/smtpd.cert'; - $smtpd_key = $postfix_dir.'/smtpd.key'; - - // Backup existing postfix ssl files - if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak'); - if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak'); - - // Create symlink to ISPConfig SSL files - symlink($ssl_crt_file, $smtpd_crt); - symlink($ssl_key_file, $smtpd_key); - } - - // Extend LE SSL certs to pureftpd - if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times.', array('y', 'n'), 'y')) == 'y') { - - // Define folder, file(s) - $pureftpd_dir = '/etc/ssl/private'; - if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); - $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; - - // Backup existing pureftpd ssl files - if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); - - // Create symlink to ISPConfig SSL files - symlink($ssl_pem_file, $pureftpd_pem); - if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem")) - exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem"); - } - } else { // We can still use the old self-signed method @@ -2525,8 +2471,47 @@ class installer_base { rename($ssl_key_file, $ssl_key_file.'.secure'); rename($ssl_key_file.'.insecure', $ssl_key_file); } - - exec("chown -R root:root $install_dir/interface/ssl"); + + // Build ispserver.pem file and chmod it + exec("cat $ssl_key_file $ssl_crt_file > $ssl_pem_file; chmod 600 $ssl_pem_file"); + + // Extend LE SSL certs to postfix + if ($conf['postfix']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to postfix?', array('y', 'n'), 'y')) == 'y') { + + // Define folder, file(s) + $cf = $conf['postfix']; + $postfix_dir = $cf['config_dir']; + if(!is_dir($postfix_dir)) $this->error("The postfix configuration directory '$postfix_dir' does not exist."); + $smtpd_crt = $postfix_dir.'/smtpd.cert'; + $smtpd_key = $postfix_dir.'/smtpd.key'; + + // Backup existing postfix ssl files + if (file_exists($smtpd_crt)) rename($smtpd_crt, $smtpd_crt . '-' .$date->format('YmdHis') . '.bak'); + if (file_exists($smtpd_key)) rename($smtpd_key, $smtpd_key . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_crt_file, $smtpd_crt); + symlink($ssl_key_file, $smtpd_key); + } + + // Extend LE SSL certs to pureftpd + if ($conf['pureftpd']['installed'] == true && strtolower($this->simple_query('Symlink ISPConfig LE SSL certs to pureftpd? Creating dhparam file takes some times.', array('y', 'n'), 'y')) == 'y') { + + // Define folder, file(s) + $pureftpd_dir = '/etc/ssl/private'; + if(!is_dir($pureftpd_dir)) mkdir($pureftpd_dir, 0755, true); + $pureftpd_pem = $pureftpd_dir.'/pure-ftpd.pem'; + + // Backup existing pureftpd ssl files + if (file_exists($pureftpd_pem)) rename($pureftpd_pem, $pureftpd_pem . '-' .$date->format('YmdHis') . '.bak'); + + // Create symlink to ISPConfig SSL files + symlink($ssl_pem_file, $pureftpd_pem); + if (!file_exists("$pureftpd_dir/pure-ftpd-dhparams.pem")) + exec("cd $pureftpd_dir; openssl dhparam -out dhparam4096.pem 4096; ln -sf dhparam4096.pem pure-ftpd-dhparams.pem"); + } + + exec("chown -R root:root $install_dir/interface/ssl"); } -- GitLab From 2cd49f48e842b81961fbc2031b920c1835c829a8 Mon Sep 17 00:00:00 2001 From: Choong Wei Tjeng Date: Mon, 5 Nov 2018 15:32:25 +0100 Subject: [PATCH 162/310] Add website_symlink_plugin.inc.php --- .../website_symlink_plugin.inc.php | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 server/plugins-available/website_symlink_plugin.inc.php diff --git a/server/plugins-available/website_symlink_plugin.inc.php b/server/plugins-available/website_symlink_plugin.inc.php new file mode 100644 index 000000000..f40e59947 --- /dev/null +++ b/server/plugins-available/website_symlink_plugin.inc.php @@ -0,0 +1,77 @@ + ../../web + */ +class website_symlink_plugin { + + var $plugin_name = 'website_symlink_plugin'; + var $class_name = 'website_symlink_plugin'; + + public function onInstall() { + global $conf; + + if ($conf['services']['web'] == true) { + return true; + } + + return false; + } + + public function onLoad() { + global $app; + + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'createSymlinkForWebDomain'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'createSymlinkForWebDomain'); + + $app->plugins->registerEvent('shell_user_insert', $this->plugin_name, 'createSymlinkForShellUser'); + $app->plugins->registerEvent('shell_user_update', $this->plugin_name, 'createSymlinkForShellUser'); + } + + public function createSymlinkForWebDomain($event_name, $data) { + $homeDirectories = glob(sprintf('%s/home', $data['new']['document_root']) . '/*', GLOB_ONLYDIR); + + foreach ($homeDirectories as $dir) { + $target = sprintf('%s/web', $data['new']['document_root']); + $link = sprintf('%s/website', $dir); + + $this->createSymlink($target, $link); + } + } + + public function createSymlinkForShellUser($event_name, $data) { + $target = sprintf('%s/web', $data['new']['dir']); + $link = sprintf('%s/home/%s/website', $data['new']['dir'], $data['new']['username']); + + $this->createSymlink($target, $link); + } + + private function createSymlink($target, $link) { + global $app; + + if (file_exists($link)) { + $app->log(sprintf('Not creating symlink because "%s" already exists', $link), LOGLEVEL_DEBUG); + + return; + } + + if ($app->system->create_relative_link($target, $link)) { + $app->log(sprintf('Created symlink from "%s" to "%s"', $link, $target), LOGLEVEL_DEBUG); + } else { + $app->log(sprintf('Failed to create symlink from "%s" to "%s"', $link, $target), LOGLEVEL_WARN); + } + } +} \ No newline at end of file -- GitLab From f96269735b7f9dd7f49131fda5fc4bf9d9e428cb Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Mon, 5 Nov 2018 15:56:04 +0100 Subject: [PATCH 163/310] Update website_symlink_plugin.inc.php --- server/plugins-available/website_symlink_plugin.inc.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/plugins-available/website_symlink_plugin.inc.php b/server/plugins-available/website_symlink_plugin.inc.php index f40e59947..a17732c5e 100644 --- a/server/plugins-available/website_symlink_plugin.inc.php +++ b/server/plugins-available/website_symlink_plugin.inc.php @@ -24,9 +24,12 @@ class website_symlink_plugin { public function onInstall() { global $conf; + // Enable the following code section to activate the plugin automatically at install time + /* if ($conf['services']['web'] == true) { return true; } + */ return false; } -- GitLab From 27e0c32e06ee8a00f846b2d4a5e30a897b42be0b Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Mon, 5 Nov 2018 17:26:37 +0100 Subject: [PATCH 164/310] Update install.php to fix the condition for non-webservers to check for ispserver.crt file instead of whether apache or nginx is installed since apache might be installed together with mailman. --- install/install.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/install/install.php b/install/install.php index ff4f81731..8e4c2be06 100644 --- a/install/install.php +++ b/install/install.php @@ -598,10 +598,9 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPCon } // Create SSL certs for non-webserver(s)? -if(($conf['apache']['installed'] && $conf['apache']['installed']) == false) { - if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { +if(!file_exists(/usr/local/ispconfig/interface/ssl/ispserver.crt)) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') $inst->make_ispconfig_ssl_cert(); - } } $inst->install_ispconfig(); -- GitLab From d74f0addd498ba75ff7cac5e39fbbb4d72930c3a Mon Sep 17 00:00:00 2001 From: Hj Ahmad Rasyid Hj Ismail Date: Mon, 5 Nov 2018 17:27:59 +0100 Subject: [PATCH 165/310] Update update.php to fix the condition for non-webservers to check for ispserver.crt file instead of whether apache or nginx is installed since apache might be installed together with mailman. --- install/update.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/install/update.php b/install/update.php index 616bef6a2..3311272a2 100644 --- a/install/update.php +++ b/install/update.php @@ -524,11 +524,10 @@ if ($inst->install_ispconfig_interface) { } } -// Create SSL certs for non-webserver(s) ? -if(($conf['apache']['installed'] && $conf['apache']['installed']) == false) { - if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { +// Create SSL certs for non-webserver(s)? +if(!file_exists(/usr/local/ispconfig/interface/ssl/ispserver.crt)) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') $inst->make_ispconfig_ssl_cert(); - } } $inst->install_ispconfig(); -- GitLab From fb5626881336ea6c10f2d39daf6aaa6346adf3f7 Mon Sep 17 00:00:00 2001 From: Choong Wei Tjeng Date: Mon, 5 Nov 2018 20:49:33 +0100 Subject: [PATCH 166/310] #5161 DNSSEC support for PowerDNS --- interface/web/dns/lib/lang/ar_dns_soa.lng | 2 +- interface/web/dns/lib/lang/bg_dns_soa.lng | 2 +- interface/web/dns/lib/lang/br_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ca_dns_soa.lng | 2 +- interface/web/dns/lib/lang/cz_dns_soa.lng | 2 +- interface/web/dns/lib/lang/de_dns_soa.lng | 2 +- interface/web/dns/lib/lang/dk_dns_soa.lng | 2 +- interface/web/dns/lib/lang/el_dns_soa.lng | 2 +- interface/web/dns/lib/lang/en_dns_soa.lng | 2 +- interface/web/dns/lib/lang/es_dns_soa.lng | 2 +- interface/web/dns/lib/lang/fi_dns_soa.lng | 2 +- interface/web/dns/lib/lang/fr_dns_soa.lng | 2 +- interface/web/dns/lib/lang/hr_dns_soa.lng | 2 +- interface/web/dns/lib/lang/hu_dns_soa.lng | 2 +- interface/web/dns/lib/lang/id_dns_soa.lng | 2 +- interface/web/dns/lib/lang/it_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ja_dns_soa.lng | 2 +- interface/web/dns/lib/lang/nl_dns_soa.lng | 2 +- interface/web/dns/lib/lang/pl_dns_soa.lng | 2 +- interface/web/dns/lib/lang/pt_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ro_dns_soa.lng | 2 +- interface/web/dns/lib/lang/ru_dns_soa.lng | 2 +- interface/web/dns/lib/lang/se_dns_soa.lng | 2 +- interface/web/dns/lib/lang/sk_dns_soa.lng | 2 +- interface/web/dns/lib/lang/tr_dns_soa.lng | 2 +- interface/web/dns/templates/dns_soa_edit.htm | 11 + .../plugins-available/powerdns_plugin.inc.php | 210 +++++++++++++++++- 27 files changed, 238 insertions(+), 33 deletions(-) diff --git a/interface/web/dns/lib/lang/ar_dns_soa.lng b/interface/web/dns/lib/lang/ar_dns_soa.lng index 98b79d586..4e93c5b41 100644 --- a/interface/web/dns/lib/lang/ar_dns_soa.lng +++ b/interface/web/dns/lib/lang/ar_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/bg_dns_soa.lng b/interface/web/dns/lib/lang/bg_dns_soa.lng index fa0852119..151e3ead1 100644 --- a/interface/web/dns/lib/lang/bg_dns_soa.lng +++ b/interface/web/dns/lib/lang/bg_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/br_dns_soa.lng b/interface/web/dns/lib/lang/br_dns_soa.lng index 34f71ba5a..fcad62b44 100644 --- a/interface/web/dns/lib/lang/br_dns_soa.lng +++ b/interface/web/dns/lib/lang/br_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'O ttl mínimo são 60 segundos.'; $wb['xfer_error_regex'] = 'Também notificar: Por favor, insira um endereço IP.'; $wb['dnssec_info_txt'] = 'Registro para DNSSEC (DS-Data)'; $wb['dnssec_wanted_txt'] = 'Zona assinada (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Quando desabilitar o DNSSEC as chaves não são eliminadas mas a zona não será disponibilizada assinada.'; +$wb['dnssec_wanted_info'] = 'Quando desabilitar o DNSSEC as chaves não são eliminadas mas a zona não será disponibilizada assinada. Se você usar o PowerDNS, as chaves serão excluídas!'; $wb['error_not_allowed_server_id'] = 'O servidor selecionado não tem permissão para esta conta.'; $wb['soa_cannot_be_changed_txt'] = 'A zona SOA não pode ser modificada. Entre em contato com o administrador para alterar esta zona.'; $wb['configuration_error_txt'] = 'ERRO DE CONFIGURAÇÃO'; diff --git a/interface/web/dns/lib/lang/ca_dns_soa.lng b/interface/web/dns/lib/lang/ca_dns_soa.lng index 6ecc2762a..aaf07a0b9 100644 --- a/interface/web/dns/lib/lang/ca_dns_soa.lng +++ b/interface/web/dns/lib/lang/ca_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'La TTL minimum est 60 secondes.'; $wb['xfer_error_regex'] = 'A noter également : Veuillez utiliser une adresse IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/cz_dns_soa.lng b/interface/web/dns/lib/lang/cz_dns_soa.lng index c3e75ca2e..7dfbb0e91 100644 --- a/interface/web/dns/lib/lang/cz_dns_soa.lng +++ b/interface/web/dns/lib/lang/cz_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL čas je 60 sekund.'; $wb['xfer_error_regex'] = 'Také oznámí: Prosím, použijte IP adresu.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Podepsat zónu (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Když deaktivujete DNSSEC klíče nebudou odstraněny, ale DNS záznamy (zóna) již nebudou propagovány v podepsaném formátu.'; +$wb['dnssec_wanted_info'] = 'Když deaktivujete DNSSEC klíče nebudou odstraněny, ale DNS záznamy (zóna) již nebudou propagovány v podepsaném formátu. Pokud používáte PowerDNS, budou klíče WILL vymazány!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/de_dns_soa.lng b/interface/web/dns/lib/lang/de_dns_soa.lng index 719162e20..35d0e54cc 100644 --- a/interface/web/dns/lib/lang/de_dns_soa.lng +++ b/interface/web/dns/lib/lang/de_dns_soa.lng @@ -13,7 +13,7 @@ $wb['xfer_txt'] = 'Zonentransfer zu diesen IP Adressen erlauben (mit Komma getre $wb['active_txt'] = 'Aktiv'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Daten für Registry'; $wb['dnssec_wanted_txt'] = 'Zone signieren (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'Wenn DNSSEC bereits aktiviert war und ein Key erstellt wurde, wird dieser durch deaktivieren nicht gelöscht. Die Zone wird dann jedoch nicht länger signiert ausgeliefert.'; +$wb['dnssec_wanted_info'] = 'Wenn DNSSEC bereits aktiviert war und ein Key erstellt wurde, wird dieser durch deaktivieren nicht gelöscht. Die Zone wird dann jedoch nicht länger signiert ausgeliefert. Wenn Sie PowerDNS verwenden, werden die Schlüssel gelöscht!'; $wb['limit_dns_zone_txt'] = 'Die maximale Anzahl an DNS Einträgen für Ihr Konto wurde erreicht.'; $wb['client_txt'] = 'Kunde'; $wb['no_zone_perm'] = 'Sie haben nicht die Berechtigung, einen Eintrag zu dieser DNS Zone hinzuzufügen.'; diff --git a/interface/web/dns/lib/lang/dk_dns_soa.lng b/interface/web/dns/lib/lang/dk_dns_soa.lng index 193dc9f4a..1c8c5cc53 100644 --- a/interface/web/dns/lib/lang/dk_dns_soa.lng +++ b/interface/web/dns/lib/lang/dk_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'Min. Minimum tid er 60 sekunder.'; $wb['ttl_range_error'] = 'Min. TTL tid er 60 sekunder.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/el_dns_soa.lng b/interface/web/dns/lib/lang/el_dns_soa.lng index 773d25ab6..4d8c876d2 100644 --- a/interface/web/dns/lib/lang/el_dns_soa.lng +++ b/interface/web/dns/lib/lang/el_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/en_dns_soa.lng b/interface/web/dns/lib/lang/en_dns_soa.lng index af1f3db56..03dd6834c 100644 --- a/interface/web/dns/lib/lang/en_dns_soa.lng +++ b/interface/web/dns/lib/lang/en_dns_soa.lng @@ -13,7 +13,7 @@ $wb["xfer_txt"] = 'Allow zone transfers to
these IPs (comma separated list $wb["active_txt"] = 'Active'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb["limit_dns_zone_txt"] = 'The max. number of DNS zones for your account is reached.'; $wb["client_txt"] = 'Client'; $wb["no_zone_perm"] = 'You do not have the permission to add a record to this DNS zone.'; diff --git a/interface/web/dns/lib/lang/es_dns_soa.lng b/interface/web/dns/lib/lang/es_dns_soa.lng index 189f8f5ad..23f4cc5ff 100755 --- a/interface/web/dns/lib/lang/es_dns_soa.lng +++ b/interface/web/dns/lib/lang/es_dns_soa.lng @@ -4,7 +4,7 @@ $wb['also_notify_error_regex'] = 'También notificar a: Por favor use una direcc $wb['also_notify_txt'] = 'También notificar a'; $wb['client_txt'] = 'Cliente'; $wb['dnssec_info_txt'] = 'Datos DS para el registro DNSSEC'; -$wb['dnssec_wanted_info'] = 'Cuando se deshabilita, las claves DNSSEC no se borrarán si DNSSEC fué habilitado anteriormente y las claves fueron generadas, pero la zona no se entregará en formato firmado después de ello.'; +$wb['dnssec_wanted_info'] = 'Cuando se deshabilita, las claves DNSSEC no se borrarán si DNSSEC fué habilitado anteriormente y las claves fueron generadas, pero la zona no se entregará en formato firmado después de ello. Si usas PowerDNS, las claves serán borradas!'; $wb['dnssec_wanted_txt'] = 'Zona de firmado (DNSSEC)'; $wb['eg_domain_tld'] = 'eje. dominio.tld'; $wb['eg_ns1_domain_tld'] = 'eje. ns1.dominio.tld'; diff --git a/interface/web/dns/lib/lang/fi_dns_soa.lng b/interface/web/dns/lib/lang/fi_dns_soa.lng index a33b593e9..3e1062596 100755 --- a/interface/web/dns/lib/lang/fi_dns_soa.lng +++ b/interface/web/dns/lib/lang/fi_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/fr_dns_soa.lng b/interface/web/dns/lib/lang/fr_dns_soa.lng index c20afd373..fa5a5202f 100644 --- a/interface/web/dns/lib/lang/fr_dns_soa.lng +++ b/interface/web/dns/lib/lang/fr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'La TTL minimum est 60 secondes.'; $wb['xfer_error_regex'] = 'A noter également : Veuillez utiliser une adresse IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/hr_dns_soa.lng b/interface/web/dns/lib/lang/hr_dns_soa.lng index 5789ace31..b4a9f2f9b 100644 --- a/interface/web/dns/lib/lang/hr_dns_soa.lng +++ b/interface/web/dns/lib/lang/hr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Minimalno TTL vrijeme je 60 sekundi.'; $wb['xfer_error_regex'] = 'Također obavijesti: Koristite IP adresu.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/hu_dns_soa.lng b/interface/web/dns/lib/lang/hu_dns_soa.lng index 8de33c83a..80388e405 100644 --- a/interface/web/dns/lib/lang/hu_dns_soa.lng +++ b/interface/web/dns/lib/lang/hu_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/id_dns_soa.lng b/interface/web/dns/lib/lang/id_dns_soa.lng index d1eee1c5f..a8b9df0d5 100644 --- a/interface/web/dns/lib/lang/id_dns_soa.lng +++ b/interface/web/dns/lib/lang/id_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/it_dns_soa.lng b/interface/web/dns/lib/lang/it_dns_soa.lng index 9fd7a5aa0..48ba33d55 100644 --- a/interface/web/dns/lib/lang/it_dns_soa.lng +++ b/interface/web/dns/lib/lang/it_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time di 60 secondi.'; $wb['xfer_error_regex'] = 'Also notify: Per cortesia utilizzare un indirizzo IP.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ja_dns_soa.lng b/interface/web/dns/lib/lang/ja_dns_soa.lng index f03be582f..2e0fd5515 100644 --- a/interface/web/dns/lib/lang/ja_dns_soa.lng +++ b/interface/web/dns/lib/lang/ja_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/nl_dns_soa.lng b/interface/web/dns/lib/lang/nl_dns_soa.lng index 1acf7bd45..b29c040df 100644 --- a/interface/web/dns/lib/lang/nl_dns_soa.lng +++ b/interface/web/dns/lib/lang/nl_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/pl_dns_soa.lng b/interface/web/dns/lib/lang/pl_dns_soa.lng index dc2780f61..f2d7e1ad8 100644 --- a/interface/web/dns/lib/lang/pl_dns_soa.lng +++ b/interface/web/dns/lib/lang/pl_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'Min. czas minimalny wynosi 60 sekund'; $wb['ttl_range_error'] = 'Min. czas TTL wynosi 60 sekund'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/pt_dns_soa.lng b/interface/web/dns/lib/lang/pt_dns_soa.lng index dd443444d..61ff07f0c 100644 --- a/interface/web/dns/lib/lang/pt_dns_soa.lng +++ b/interface/web/dns/lib/lang/pt_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ro_dns_soa.lng b/interface/web/dns/lib/lang/ro_dns_soa.lng index 625281f26..134758f95 100644 --- a/interface/web/dns/lib/lang/ro_dns_soa.lng +++ b/interface/web/dns/lib/lang/ro_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/ru_dns_soa.lng b/interface/web/dns/lib/lang/ru_dns_soa.lng index 9f9ea3126..fe716cdc1 100644 --- a/interface/web/dns/lib/lang/ru_dns_soa.lng +++ b/interface/web/dns/lib/lang/ru_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Мин. время TTL 60 секунд.'; $wb['xfer_error_regex'] = 'Also-notify: Пожалуйста, используйте IP-адрес.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'При отключении DNSSEC ключи не будут удалены, если DNSSEC был включен раньше, а ключи уже были созданы, но пояс не будет доставлен далее в подписанном формате.'; +$wb['dnssec_wanted_info'] = 'При отключении DNSSEC ключи не будут удалены, если DNSSEC был включен раньше, а ключи уже были созданы, но пояс не будет доставлен далее в подписанном формате. Если вы используете PowerDNS, ключи будут удалены!'; $wb['error_not_allowed_server_id'] = 'Выбранный сервер не доступен для этой учетной записи.'; $wb['soa_cannot_be_changed_txt'] = 'Зона (SOA) не может быть изменена. Пожалуйста, обратитесь к администратору, чтобы изменить зону.'; $wb['configuration_error_txt'] = 'ОШИБКА КОНФИГУРАЦИИ'; diff --git a/interface/web/dns/lib/lang/se_dns_soa.lng b/interface/web/dns/lib/lang/se_dns_soa.lng index 944c9c38f..034d3235a 100644 --- a/interface/web/dns/lib/lang/se_dns_soa.lng +++ b/interface/web/dns/lib/lang/se_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/sk_dns_soa.lng b/interface/web/dns/lib/lang/sk_dns_soa.lng index 176f00139..ac1f11624 100644 --- a/interface/web/dns/lib/lang/sk_dns_soa.lng +++ b/interface/web/dns/lib/lang/sk_dns_soa.lng @@ -37,7 +37,7 @@ $wb['ttl_range_error'] = 'Min. TTL time is 60 seconds.'; $wb['xfer_error_regex'] = 'Also notify: Please use an IP address.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'Die Zone (SOA) kann nicht verändert werden. Bitte kontaktieren Sie ihren Administrator, um die Zone zu ändern.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/lib/lang/tr_dns_soa.lng b/interface/web/dns/lib/lang/tr_dns_soa.lng index b406e274c..02e325e42 100644 --- a/interface/web/dns/lib/lang/tr_dns_soa.lng +++ b/interface/web/dns/lib/lang/tr_dns_soa.lng @@ -37,7 +37,7 @@ $wb['minimum_range_error'] = 'En kısa en kısa süre 60 saniyedir.'; $wb['ttl_range_error'] = 'En düşük TTL süresi 60 saniyedir.'; $wb['dnssec_info_txt'] = 'DNSSEC DS-Data for registry'; $wb['dnssec_wanted_txt'] = 'Sign zone (DNSSEC)'; -$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delievered in signed format afterwards.'; +$wb['dnssec_wanted_info'] = 'When disabling DNSSEC keys are not going to be deleted if DNSSEC was enabled before and keys already have been generated but the zone will no longer be delivered in signed format afterwards. If you use PowerDNS, keys WILL be deleted!'; $wb['error_not_allowed_server_id'] = 'The selected server is not allowed for this account.'; $wb['soa_cannot_be_changed_txt'] = 'The Zone (SOA) can not be changed. Please contact your administrator to change the zone.'; $wb['configuration_error_txt'] = 'CONFIGURATION ERROR'; diff --git a/interface/web/dns/templates/dns_soa_edit.htm b/interface/web/dns/templates/dns_soa_edit.htm index 94faec4fa..7a069cb3b 100644 --- a/interface/web/dns/templates/dns_soa_edit.htm +++ b/interface/web/dns/templates/dns_soa_edit.htm @@ -179,4 +179,15 @@ searchFieldWatermark: '', resultBoxPosition: '' }); + jQuery('#dnssec_wanted').on('click', function(event) { + if ($(this).is(':checked')) { + return; + } + + if (window.confirm('{tmpl_var name="dnssec_wanted_info"}')) { + return; + } + + event.preventDefault(); + }); diff --git a/server/plugins-available/powerdns_plugin.inc.php b/server/plugins-available/powerdns_plugin.inc.php index 412050d00..f5f5158c4 100644 --- a/server/plugins-available/powerdns_plugin.inc.php +++ b/server/plugins-available/powerdns_plugin.inc.php @@ -151,6 +151,8 @@ class powerdns_plugin { //* tell pdns to rediscover zones in DB $this->zoneRediscover(); + //* handle dnssec + $this->handle_dnssec($data); //* tell pdns to use 'pdnssec rectify' on the new zone $this->rectifyZone($data); //* tell pdns to send notify to slave @@ -181,10 +183,6 @@ class powerdns_plugin { $ttl = $data["new"]["ttl"]; $app->db->query("UPDATE powerdns.records SET name = ?, content = ?, ttl = ?, change_date = UNIX_TIMESTAMP() WHERE ispconfig_id = ? AND type = 'SOA'", $origin, $content, $ttl, $data["new"]["id"]); - //* tell pdns to use 'pdnssec rectify' on the new zone - $this->rectifyZone($data); - //* tell pdns to send notify to slave - $this->notifySlave($data); } else { $this->soa_insert($event_name, $data); $ispconfig_id = $data["new"]["id"]; @@ -196,11 +194,14 @@ class powerdns_plugin { $this->rr_insert("dns_rr_insert", $data); } } - //* tell pdns to use 'pdnssec rectify' on the new zone - $this->rectifyZone($data); - //* tell pdns to send notify to slave - $this->notifySlave($data); } + + //* handle dnssec + $this->handle_dnssec($data); + //* tell pdns to use 'pdnssec rectify' on the new zone + $this->rectifyZone($data); + //* tell pdns to send notify to slave + $this->notifySlave($data); } } @@ -465,6 +466,199 @@ class powerdns_plugin { } } + function handle_dnssec($data) { + // If origin changed, delete keys first + if ($data['old']['origin'] != $data['new']['origin']) { + if (@$data['old']['dnssec_initialized'] == 'Y' && strlen(@$data['old']['origin']) > 3) { + $this->soa_dnssec_delete($data); + } + } + + // If DNSSEC is disabled, but was enabled before, just disable DNSSEC but leave the keys in dns_info + if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_initialized'] === 'Y') { + $this->soa_dnssec_disable($data); + + return; + } + + // If DNSSEC is wanted, enable it + if ($data['new']['dnssec_wanted'] === 'Y') { + $this->soa_dnssec_create($data); + } + } + + function soa_dnssec_create($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['new']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_secure_zone = sprintf('%s secure-zone %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running secure-zone command...'); + exec($cmd_secure_zone, $log); + + $cmd_set_nsec3 = sprintf('%s set-nsec3 %s "1 0 10 deadbeef" 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running set-nsec3 command...'); + exec($cmd_set_nsec3, $log); + + $pubkeys = []; + $cmd_show_zone = sprintf('%s show-zone %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running show-zone command...'); + exec($cmd_show_zone, $pubkeys); + + $log = array_merge($log, $pubkeys); + + $dnssec_info = array_merge($this->format_dnssec_pubkeys($pubkeys), ['', '== Raw log ============================'], $log); + $dnssec_info = implode("\r\n", $dnssec_info); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'Y', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'Y', intval($data['new']['id'])); + } + + function format_dnssec_pubkeys($lines) { + $formatted = []; + + // We don't care about the first two lines about presigning and NSEC + array_shift($lines); + array_shift($lines); + + foreach ($lines as $line) { + switch ($part = substr($line, 0, 3)) { + case 'ID ': + // Only process active keys + if (!strpos($line, 'Active: 1')) { + continue; + } + + // Determine key type (KSK or ZSK) + preg_match('/(KSK|ZSK)/', $line, $matches_key_type); + $key_type = $matches_key_type[1]; + + // We only care about the KSK + if ('ZSK' === $key_type) { + continue; + } + + // Determine key tag + preg_match('/ tag = (\d+),/', $line, $matches_key_tag); + $formatted[] = sprintf('%s key tag: %d', $key_type, $matches_key_tag[1]); + + // Determine algorithm + preg_match('/ algo = (\d+),/', $line, $matches_algo_id); + preg_match('/ \( (.*) \)$/', $line, $matches_algo_name); + $formatted[] = sprintf('Algo: %d (%s)', $matches_algo_id[1], $matches_algo_name[1]); + + // Determine bits + preg_match('/ bits = (\d+)/', $line, $matches_bits); + $formatted[] = sprintf('Bits: %d', $matches_bits[1]); + + break; + + case 'KSK': + // Determine DNSKEY + preg_match('/ IN DNSKEY \d+ \d+ \d+ (.*) ;/', $line, $matches_dnskey); + $formatted[] = sprintf('DNSKEY: %s', $matches_dnskey[1]); + + break; + + case 'DS ': + // Determine key tag + preg_match('/ IN DS (\d+) \d+ \d+ /', $line, $matches_ds_key_tag); + $formatted[] = sprintf(' - DS key tag: %d', $matches_ds_key_tag[1]); + + // Determine key tag + preg_match('/ IN DS \d+ (\d+) \d+ /', $line, $matches_ds_algo); + $formatted[] = sprintf(' Algo: %d', $matches_ds_algo[1]); + + // Determine digest + preg_match('/ IN DS \d+ \d+ (\d+) /', $line, $matches_ds_digest_id); + preg_match('/ \( (.*) \)$/', $line, $matches_ds_digest_name); + $formatted[] = sprintf(' Digest: %d (%s)', $matches_ds_digest_id[1], $matches_ds_digest_name[1]); + + // Determine public key + preg_match('/ IN DS \d+ \d+ \d+ (.*) ;/', $line, $matches_ds_key); + $formatted[] = sprintf(' Public key: %s', $matches_ds_key[1]); + break; + + default: + break; + } + } + + return $formatted; + } + + function soa_dnssec_disable($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['new']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_disable_dnssec = sprintf('%s disable-dnssec %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running disable-dnssec command...'); + exec($cmd_disable_dnssec, $log); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_initialized=? WHERE id=?', 'N', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_initialized=? WHERE id=?', 'N', intval($data['new']['id'])); + } + + function soa_dnssec_delete($data) { + global $app; + + if (!preg_match('/^3/',$this->get_pdns_version()) ) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec(); + if ($pdns_pdnssec === false) { + return; + } + + $zone = rtrim($data['old']['origin'],'.'); + $log = array(); + + // We don't log the actual commands here, because having commands in the dnssec_info field will trigger + // the IDS if you try to save the record using the interface afterwards. + $cmd_disable_dnssec = sprintf('%s disable-dnssec %s 2>&1', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running disable-dnssec command...'); + exec($cmd_disable_dnssec, $log); + + + $dnssec_info = array_merge(['== Raw log ============================'], $log); + $dnssec_info = implode("\r\n", $dnssec_info); + + if ($app->dbmaster !== $app->db) { + $app->dbmaster->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'N', intval($data['new']['id'])); + } + $app->db->query('UPDATE dns_soa SET dnssec_info=?, dnssec_initialized=? WHERE id=?', $dnssec_info, 'N', intval($data['new']['id'])); + } + function rectifyZone($data) { global $app, $conf; if ( preg_match('/^3/',$this->get_pdns_version()) ) { -- GitLab From abcae111ff719259f3204cf1d52293d30aff6d5f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 10:07:56 +0100 Subject: [PATCH 167/310] - fixed spare merge conflict line --- interface/lib/classes/functions.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index a1cda41e8..a86057a06 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -536,7 +536,6 @@ class functions { } } ->>>>>>> ispconfig3.official/master } ?> -- GitLab From 7349f551349dac2cecddf708341fd6a40966c952 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 11:08:57 +0100 Subject: [PATCH 168/310] - removed all deprecated PHP handlers (hhvm, cgi, suphp) --- install/dist/conf/gentoo.conf.php | 3 - install/dist/lib/fedora.lib.php | 5 - install/dist/lib/gentoo.lib.php | 13 -- install/dist/lib/opensuse.lib.php | 10 -- install/lib/installer_base.lib.php | 6 - interface/lib/classes/remote.d/server.inc.php | 2 +- .../web/admin/form/server_config.tform.php | 2 +- interface/web/client/form/client.tform.php | 2 +- .../web/client/form/client_template.tform.php | 2 +- interface/web/client/form/reseller.tform.php | 2 +- interface/web/sites/ajax_get_json.php | 4 +- .../web/sites/form/web_vhost_domain.tform.php | 2 +- .../sites/templates/web_vhost_domain_edit.htm | 30 ++--- interface/web/sites/web_vhost_domain_edit.php | 18 +-- interface/web/tools/import_vpopmail.php | 2 +- remoting_client/examples/client_add.php | 2 +- server/conf/hhvm_monit.master | 3 - server/conf/hhvm_starter.master | 95 --------------- server/conf/nginx_vhost.conf.master | 35 ------ server/conf/vhost.conf.master | 115 +----------------- .../plugins-available/apache2_plugin.inc.php | 96 +-------------- server/plugins-available/nginx_plugin.inc.php | 90 +------------- .../pma_symlink_plugin.inc.php | 4 +- .../webmail_symlink_plugin.inc.php | 4 +- 24 files changed, 37 insertions(+), 510 deletions(-) delete mode 100644 server/conf/hhvm_monit.master delete mode 100644 server/conf/hhvm_starter.master diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index 83a487f29..f15eac65d 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -72,9 +72,6 @@ $conf['mysql']['master_admin_password'] = ''; $conf['mysql']['master_ispconfig_user'] = ''; $conf['mysql']['master_ispconfig_password'] = md5(uniqid(rand())); -//* SuPHP -$conf['suphp']['config_file'] = '/etc/suphp.conf'; - //* Apache $conf['apache']['installed'] = false; // will be detected automatically during installation $conf['apache']['user'] = 'apache'; diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index f8ca1eb6a..176245cea 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -696,11 +696,6 @@ class installer_dist extends installer_base { global $conf; if($conf['apache']['installed'] == false) return; - if(is_file('/etc/suphp.conf')) { - //replaceLine('/etc/suphp.conf','php=php:/usr/bin','x-httpd-suphp=php:/usr/bin/php-cgi',0); - replaceLine('/etc/suphp.conf', 'docroot=', 'docroot=/var/www', 0); - replaceLine('/etc/suphp.conf', 'umask=0077', 'umask=0022', 0); - } //* Create the logging directory for the vhost logfiles exec('mkdir -p /var/log/ispconfig/httpd'); diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index f0c28a61c..dad0f880e 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -555,19 +555,6 @@ class installer extends installer_base mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true); } - if (is_file($conf['suphp']['config_file'])) - { - $content = rf($conf['suphp']['config_file']); - - if (!preg_match('|^x-httpd-suphp=php:/usr/bin/php-cgi$|m', $content)) - { - $content = preg_replace('/;Handler for php-scripts/', ";Handler for php-scripts\nx-httpd-suphp=php:/usr/bin/php-cgi", $content); - $content = preg_replace('/;?umask=\d+/', 'umask=0022', $content); - } - - $this->write_config_file($conf['suphp']['config_file'], $content); - } - //* Enable ISPConfig default vhost settings $default_vhost_path = $conf['apache']['vhost_conf_dir'].'/'.$conf['apache']['vhost_default']; if (is_file($default_vhost_path)) diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index 32d74a6d1..ea862a67e 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -663,13 +663,6 @@ class installer_dist extends installer_base { //* enable apache logio module exec('a2enmod logio'); - //if(is_file('/etc/suphp.conf')) { - replaceLine('/etc/suphp.conf', 'php=php', 'x-httpd-suphp="php:/srv/www/cgi-bin/php5"', 0, 0); - replaceLine('/etc/suphp.conf', 'php="php', 'x-httpd-suphp="php:/srv/www/cgi-bin/php5"', 0, 0); - replaceLine('/etc/suphp.conf', 'docroot=', 'docroot=/srv/www', 0, 0); - replaceLine('/etc/suphp.conf', 'umask=0077', 'umask=0022', 0); - //} - if(!file_exists('/srv/www/cgi-bin/php5') && file_exists('/srv/www/cgi-bin/php')) { symlink('/srv/www/cgi-bin/php', '/srv/www/cgi-bin/php5'); } @@ -1249,9 +1242,6 @@ class installer_dist extends installer_base { } } - - // Fix a setting in vhost master file for suse - replaceLine('/usr/local/ispconfig/server/conf/vhost.conf.master', "suPHP_UserGroup", " suPHP_UserGroup ", 0); } if($conf['nginx']['installed'] == true && $this->install_ispconfig_interface == true){ diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 36b0ed022..6011a2c4a 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -1938,12 +1938,6 @@ class installer_base { //* Create the logging directory for the vhost logfiles if(!@is_dir($conf['ispconfig_log_dir'].'/httpd')) mkdir($conf['ispconfig_log_dir'].'/httpd', 0755, true); - if(is_file('/etc/suphp/suphp.conf')) { - replaceLine('/etc/suphp/suphp.conf', 'php="php:/usr/bin', 'x-httpd-suphp="php:/usr/bin/php-cgi"', 0); - //replaceLine('/etc/suphp/suphp.conf','docroot=','docroot=/var/clients',0); - replaceLine('/etc/suphp/suphp.conf', 'umask=00', 'umask=0022', 0); - } - if(is_file('/etc/apache2/sites-enabled/000-default')) { replaceLine('/etc/apache2/sites-available/000-default', 'NameVirtualHost *', 'NameVirtualHost *:80', 1, 0); replaceLine('/etc/apache2/sites-available/000-default', '', '', 1, 0); diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index a9961784e..4e8179d06 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -269,7 +269,7 @@ class remoting_server extends remoting { $web_config[$server_id] = $app->getconf->get_server_config($server_id, 'web'); $server_type = !empty($web_config[$server_id]['server_type']) ? $web_config[$server_id]['server_type'] : 'apache'; - if ($php === 'php-fpm' || ($php === 'hhvm' && $server_type === 'nginx')) { + if ($php === 'php-fpm') { $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 (client_id = 0)", $server_id); foreach ($php_records as $php_record) { $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index a1a4dfb19..aa0e1188a 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1242,7 +1242,7 @@ $form["tabs"]['web'] = array( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', 'default' => 'fast-cgi', - 'value' => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM'), + 'value' => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'mod' => 'Mod-PHP', 'php-fpm' => 'PHP-FPM'), 'searchable' => 2 ), 'nginx_cgi_socket' => array( diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index 396cbff4e..09db5c1ff 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -1100,7 +1100,7 @@ $form["tabs"]['limits'] = array ( 'default' => '', 'separator' => ',', 'valuelimit' => 'client:web_php_options', - 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM') + 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'mod' => 'Mod-PHP', 'php-fpm' => 'PHP-FPM') ), 'limit_cgi' => array ( 'datatype' => 'VARCHAR', diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php index 76cc26c02..2196ad4d0 100644 --- a/interface/web/client/form/client_template.tform.php +++ b/interface/web/client/form/client_template.tform.php @@ -508,7 +508,7 @@ $form["tabs"]['limits'] = array ( 'default' => '', 'separator' => ',', 'valuelimit' => 'client:web_php_options', - 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM') + 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'mod' => 'Mod-PHP', 'php-fpm' => 'PHP-FPM') ), 'limit_cgi' => array ( 'datatype' => 'VARCHAR', diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index bd839da34..d5c22e206 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -1097,7 +1097,7 @@ $form["tabs"]['limits'] = array ( ), 'default' => '', 'separator' => ',', - 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM') + 'value' => array('no' => 'Disabled', 'fast-cgi' => 'Fast-CGI', 'mod' => 'Mod-PHP', 'php-fpm' => 'PHP-FPM') ), 'limit_cgi' => array ( 'datatype' => 'VARCHAR', diff --git a/interface/web/sites/ajax_get_json.php b/interface/web/sites/ajax_get_json.php index ff915e780..1b67a4ed2 100644 --- a/interface/web/sites/ajax_get_json.php +++ b/interface/web/sites/ajax_get_json.php @@ -92,7 +92,7 @@ if($type == 'getphpfastcgi'){ $sql_where .= ")"; } - if($php_type == 'php-fpm' || ($php_type == 'hhvm' && $server_type == 'nginx')){ + if($php_type == 'php-fpm'){ $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' ORDER BY name".$sql_where, $server_id); } elseif($php_type == 'fast-cgi'){ $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND active = 'y' ORDER BY name".$sql_where, $server_id); @@ -102,7 +102,7 @@ if($type == 'getphpfastcgi'){ $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { - if($php_type == 'php-fpm' || ($php_type == 'hhvm' && $server_type == 'nginx')){ + if($php_type == 'php-fpm'){ $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; } else { $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; diff --git a/interface/web/sites/form/web_vhost_domain.tform.php b/interface/web/sites/form/web_vhost_domain.tform.php index f47fe709f..ad1d4ff55 100644 --- a/interface/web/sites/form/web_vhost_domain.tform.php +++ b/interface/web/sites/form/web_vhost_domain.tform.php @@ -251,7 +251,7 @@ $form["tabs"]['domain'] = array ( 'formtype' => 'SELECT', 'default' => 'fast-cgi', 'valuelimit' => 'client:web_php_options', - 'value' => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'cgi' => 'CGI', 'mod' => 'Mod-PHP', 'suphp' => 'SuPHP', 'php-fpm' => 'PHP-FPM', 'hhvm' => 'HHVM'), + 'value' => array('no' => 'disabled_txt', 'fast-cgi' => 'Fast-CGI', 'mod' => 'Mod-PHP', 'php-fpm' => 'PHP-FPM'), 'searchable' => 2 ), 'fastcgi_php_version' => array ( diff --git a/interface/web/sites/templates/web_vhost_domain_edit.htm b/interface/web/sites/templates/web_vhost_domain_edit.htm index 149d43088..6a6dc2d28 100644 --- a/interface/web/sites/templates/web_vhost_domain_edit.htm +++ b/interface/web/sites/templates/web_vhost_domain_edit.htm @@ -293,31 +293,21 @@ reloadFastcgiPHPVersions(); }); - if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm' || (jQuery('#php').val() == 'hhvm' && serverType == 'nginx')){ + if(jQuery('#php').val() == 'fast-cgi' || jQuery('#php').val() == 'php-fpm'){ jQuery('.fastcgi_php_version:hidden').show(); - if(jQuery('#php').val() == 'hhvm'){ - jQuery('#fastcgi_php_version_txt').hide(); - jQuery('#fastcgi_php_fallback_version_txt').show(); - } else { - jQuery('#fastcgi_php_version_txt').show(); - jQuery('#fastcgi_php_fallback_version_txt').hide(); - } - } else { + jQuery('#fastcgi_php_version_txt').show(); + jQuery('#fastcgi_php_fallback_version_txt').hide(); + } else { jQuery('.fastcgi_php_version:visible').hide(); } //ISPConfig.resetFormChanged(); jQuery('#php').change(function(){ reloadFastcgiPHPVersions(); - if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm' || (jQuery(this).val() == 'hhvm' && serverType == 'nginx')){ + if(jQuery(this).val() == 'fast-cgi' || jQuery(this).val() == 'php-fpm'){ jQuery('.fastcgi_php_version:hidden').show(); - if(jQuery(this).val() == 'hhvm'){ - jQuery('#fastcgi_php_version_txt').hide(); - jQuery('#fastcgi_php_fallback_version_txt').show(); - } else { - jQuery('#fastcgi_php_version_txt').show(); - jQuery('#fastcgi_php_fallback_version_txt').hide(); - } + jQuery('#fastcgi_php_version_txt').show(); + jQuery('#fastcgi_php_fallback_version_txt').hide(); } else { jQuery('.fastcgi_php_version:visible').hide(); } @@ -373,21 +363,17 @@ } }); */ - if(selected != "no" && selected != "php-fpm" && selected != "hhvm") { + if(selected != "no" && selected != "php-fpm") { jQuery('#php option[value="php-fpm"]').attr('selected', 'selected').val('php-fpm'); } jQuery('#php option[value="fast-cgi"]').hide(); - jQuery('#php option[value="cgi"]').hide(); jQuery('#php option[value="mod"]').hide(); - jQuery('#php option[value="suphp"]').hide(); } else { serverType = 'apache'; jQuery('.nginx').hide(); jQuery('.apache').show(); jQuery('#php option[value="fast-cgi"]').show(); - jQuery('#php option[value="cgi"]').show(); jQuery('#php option[value="mod"]').show(); - jQuery('#php option[value="suphp"]').show(); } if(noFormChange) { ISPConfig.resetFormChanged(); diff --git a/interface/web/sites/web_vhost_domain_edit.php b/interface/web/sites/web_vhost_domain_edit.php index 5d6aed2e4..d85e5da9a 100644 --- a/interface/web/sites/web_vhost_domain_edit.php +++ b/interface/web/sites/web_vhost_domain_edit.php @@ -243,14 +243,14 @@ class page_action extends tform_actions { if($server_type == 'nginx' && $this->dataRecord['php'] == 'fast-cgi') $this->dataRecord['php'] = 'php-fpm'; if($this->_vhostdomain_type == 'domain') { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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 (client_id = 0 OR client_id=?) AND active = 'y' ORDER BY name", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $_SESSION['s']['user']['client_id']); } if($this->dataRecord['php'] == 'fast-cgi'){ $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ? AND (client_id = 0 OR client_id=?) AND active = 'y' ORDER BY name", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $_SESSION['s']['user']['client_id']); } } else { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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 (client_id = 0 OR client_id=?) AND active = 'y' ORDER BY name", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } if($this->dataRecord['php'] == 'fast-cgi'){ @@ -260,7 +260,7 @@ class page_action extends tform_actions { $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; } else { $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; @@ -390,14 +390,14 @@ class page_action extends tform_actions { $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = ?", $selected_client_group_id); $sql_where = " AND (client_id = 0 OR client_id = ?) AND active = 'y'"; if($this->_vhostdomain_type == 'domain') { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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 = ?".$sql_where." ORDER BY name", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $selected_client['client_id']); } if($this->dataRecord['php'] == 'fast-cgi') { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ?".$sql_where." ORDER BY name", ($this->id > 0 ? $this->dataRecord['server_id'] : $client['default_webserver']), $selected_client['client_id']); } } else { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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 (client_id = 0 OR client_id=?) AND active = 'y' ORDER BY name", $parent_domain['server_id'], $_SESSION['s']['user']['client_id']); } if($this->dataRecord['php'] == 'fast-cgi') { @@ -407,7 +407,7 @@ class page_action extends tform_actions { $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; } else { $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; @@ -610,14 +610,14 @@ class page_action extends tform_actions { $selected_client = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = ?", $selected_client_group_id); $sql_where = " AND (client_id = 0 OR client_id = ?) AND active = 'y'"; if($this->_vhostdomain_type == 'domain') { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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 = ?".$sql_where." ORDER BY name", $server_id, $selected_client['client_id']); } if($this->dataRecord['php'] == 'fast-cgi') { $php_records = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fastcgi_binary != '' AND php_fastcgi_ini_dir != '' AND server_id = ?".$sql_where." ORDER BY name", $server_id, $selected_client['client_id']); } } else { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $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' ORDER BY name", $parent_domain['server_id']); } if($this->dataRecord['php'] == 'fast-cgi') { @@ -627,7 +627,7 @@ class page_action extends tform_actions { $php_select = ""; if(is_array($php_records) && !empty($php_records)) { foreach( $php_records as $php_record) { - if($this->dataRecord['php'] == 'php-fpm' || ($this->dataRecord['php'] == 'hhvm' && $server_type == 'nginx')){ + if($this->dataRecord['php'] == 'php-fpm'){ $php_version = $php_record['name'].':'.$php_record['php_fpm_init_script'].':'.$php_record['php_fpm_ini_dir'].':'.$php_record['php_fpm_pool_dir']; } else { $php_version = $php_record['name'].':'.$php_record['php_fastcgi_binary'].':'.$php_record['php_fastcgi_ini_dir']; diff --git a/interface/web/tools/import_vpopmail.php b/interface/web/tools/import_vpopmail.php index 3e732d374..d95e405a2 100644 --- a/interface/web/tools/import_vpopmail.php +++ b/interface/web/tools/import_vpopmail.php @@ -111,7 +111,7 @@ function start_import() { //* add client $sql = "INSERT INTO `client` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `company_name`, `company_id`, `contact_name`, `customer_no`, `vat_id`, `street`, `zip`, `city`, `state`, `country`, `telephone`, `mobile`, `fax`, `email`, `internet`, `icq`, `notes`, `bank_account_owner`, `bank_account_number`, `bank_code`, `bank_name`, `bank_account_iban`, `bank_account_swift`, `default_mailserver`, `limit_maildomain`, `limit_mailbox`, `limit_mailalias`, `limit_mailaliasdomain`, `limit_mailforward`, `limit_mailcatchall`, `limit_mailrouting`, `limit_mailfilter`, `limit_fetchmail`, `limit_mailquota`, `limit_spamfilter_wblist`, `limit_spamfilter_user`, `limit_spamfilter_policy`, `default_webserver`, `limit_web_ip`, `limit_web_domain`, `limit_web_quota`, `web_php_options`, `limit_cgi`, `limit_ssi`, `limit_perl`, `limit_ruby`, `limit_python`, `force_suexec`, `limit_hterror`, `limit_wildcard`, `limit_ssl`, `limit_web_subdomain`, `limit_web_aliasdomain`, `limit_ftp_user`, `limit_shell_user`, `ssh_chroot`, `limit_webdav_user`, `limit_aps`, `default_dnsserver`, `limit_dns_zone`, `limit_dns_slave_zone`, `limit_dns_record`, `default_dbserver`, `limit_database`, `limit_cron`, `limit_cron_type`, `limit_cron_frequency`, `limit_traffic_quota`, `limit_client`, `limit_mailmailinglist`, `limit_openvz_vm`, `limit_openvz_vm_template_id`, `parent_client_id`, `username`, `password`, `language`, `usertheme`, `template_master`, `template_additional`, `created_at`, `id_rsa`, `ssh_rsa`) - VALUES(1, 1, 'riud', 'riud', '', '', '', ?, '', '', '', '', '', '', ?, '', '', '', '', 'http://', '', '', '', '', '', '', '', '', 1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1, NULL, -1, -1, 'no,fast-cgi,cgi,mod,suphp', 'n', 'n', 'n', 'n', 'n', 'y', 'n', 'n', 'n', -1, -1, -1, 0, 'no,jailkit', 0, 0, 1, -1, -1, -1, 1, -1, 0, 'url', 5, -1, 0, -1, 0, 0, 0, ?, ?, ?, 'default', 0, '', NOW(), '', '')"; + VALUES(1, 1, 'riud', 'riud', '', '', '', ?, '', '', '', '', '', '', ?, '', '', '', '', 'http://', '', '', '', '', '', '', '', '', 1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1, NULL, -1, -1, 'no,fast-cgi,mod', 'n', 'n', 'n', 'n', 'n', 'y', 'n', 'n', 'n', -1, -1, -1, 0, 'no,jailkit', 0, 0, 1, -1, -1, -1, 1, -1, 0, 'url', 5, -1, 0, -1, 0, 0, 0, ?, ?, ?, 'default', 0, '', NOW(), '', '')"; $app->db->query($sql, $pw_domain,$country, $pw_domain, $pw_crypt_password, $conf['language']); $client_id = $app->db->insertID(); diff --git a/remoting_client/examples/client_add.php b/remoting_client/examples/client_add.php index 6d5b5934d..c4d993bb2 100644 --- a/remoting_client/examples/client_add.php +++ b/remoting_client/examples/client_add.php @@ -51,7 +51,7 @@ try { 'limit_web_ip' => '', 'limit_web_domain' => -1, 'limit_web_quota' => -1, - 'web_php_options' => 'no,fast-cgi,cgi,mod,suphp', + 'web_php_options' => 'no,fast-cgi,mod', 'limit_web_subdomain' => -1, 'limit_web_aliasdomain' => -1, 'limit_ftp_user' => -1, diff --git a/server/conf/hhvm_monit.master b/server/conf/hhvm_monit.master deleted file mode 100644 index 79697eae5..000000000 --- a/server/conf/hhvm_monit.master +++ /dev/null @@ -1,3 +0,0 @@ -check process hhvm_{SYSTEM_USER} with pidfile /var/run/hhvm/hhvm_{SYSTEM_USER}.pid - start program = "/etc/init.d/hhvm_{SYSTEM_USER} restart" - stop program = "/etc/init.d/hhvm_{SYSTEM_USER} stop" \ No newline at end of file diff --git a/server/conf/hhvm_starter.master b/server/conf/hhvm_starter.master deleted file mode 100644 index e530a405a..000000000 --- a/server/conf/hhvm_starter.master +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/bash -# -# /etc/init.d/hhvm_{SYSTEM_USER} -# -### BEGIN INIT INFO -# Provides: hhvm_{SYSTEM_USER} -# Required-Start: $remote_fs $network -# Required-Stop: $remote_fs $network -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Description: Starts The HHVM FastCGI Daemon -### END INIT INFO -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="HHVM FastCGI Daemon" -NAME=hhvm - -do_start() -{ - if [ ! -d /var/run/hhvm ]; then - mkdir -p -m1777 /var/run/hhvm - else - chmod 1777 /var/run/hhvm - fi - - if [[ -e "/var/run/hhvm/hhvm_{SYSTEM_USER}.pid" ]] ; then - kill -0 `cat /var/run/hhvm/hhvm_{SYSTEM_USER}.pid` >/dev/null 2>&1 ; - case "$?" in - 0) - return 1 - ;; - esac - fi - - if [[ -S /var/run/mysqld/mysqld.sock && ! -S /tmp/mysql.sock ]] ; then - ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock ; - fi - - umask 027 - sudo -u {SYSTEM_USER} touch /var/run/hhvm/hhvm_{SYSTEM_USER}.pid - - BASEINIFILE="" - if [[ -e "/etc/hhvm/php.ini" ]] ; then - BASEINIFILE="--config /etc/hhvm/php.ini" ; - fi - - INIFILE="" - if [[ -e "/var/www/conf/{SYSTEM_USER}/php.ini" ]] ; then - INIFILE="--config /var/www/conf/{SYSTEM_USER}/php.ini" ; - elif [[ -e "/etc/php5/hhvm/php.ini" ]] ; then - INIFILE="--config /etc/php5/hhvm/php.ini" ; - elif [[ -e "/etc/php5/fpm/php.ini" ]] ; then - INIFILE="--config /etc/php5/fpm/php.ini" ; - elif [[ -e "/etc/php5/cgi/php.ini" ]] ; then - INIFILE="--config /etc/php5/cgi/php.ini" ; - fi - - CUSTOMINIFILE="" - if [[ -e "/etc/hhvm/{SYSTEM_USER}.ini" ]] ; then - CUSTOMINIFILE="--config /etc/hhvm/{SYSTEM_USER}.ini" ; - fi - - /usr/bin/hhvm --mode daemon -vServer.Type=fastcgi -vEval.PerfPidMap=false --user {SYSTEM_USER} -vServer.FileSocket=/var/run/hhvm/hhvm.{SYSTEM_USER}.sock -vLog.Level=Warning -vLog.UseLogFile=false -vRepo.Central.Path=/var/run/hhvm/hhvm.{SYSTEM_USER}.hhbc -vServer.FixPathInfo=true $BASEINIFILE $INIFILE $CUSTOMINIFILE -vPidFile=/var/run/hhvm/hhvm_{SYSTEM_USER}.pid & echo $! > /var/run/hhvm/hhvm_{SYSTEM_USER}.pid -} - -do_stop() -{ - if [[ -e "/var/run/hhvm/hhvm_{SYSTEM_USER}.pid" ]] ; then - kill -SIGTERM `cat /var/run/hhvm/hhvm_{SYSTEM_USER}.pid` >/dev/null 2>&1 ; - fi - rm -f /var/run/hhvm/hhvm.{SYSTEM_USER}.sock /var/run/hhvm/hhvm.{SYSTEM_USER}.hhbc /var/run/hhvm/hhvm_{SYSTEM_USER}.pid -} - -case "$1" in - start) - do_start - ;; - stop) - do_stop - ;; - restart|force-reload) - do_stop - case "$?" in - 0|1) - do_start - ;; - *) - ;; - esac - ;; - *) - exit 3 - ;; -esac - -: diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master index 6b4e88aae..c072d0ae3 100644 --- a/server/conf/nginx_vhost.conf.master +++ b/server/conf/nginx_vhost.conf.master @@ -201,44 +201,9 @@ server { fastcgi_intercept_errors on; } - - location @php { - try_files $uri =404; - include /etc/nginx/fastcgi_params; - fastcgi_pass unix:/var/run/hhvm/hhvm..sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - #fastcgi_param PATH_INFO $fastcgi_script_name; - - fastcgi_param SERVER_NAME ; - - fastcgi_intercept_errors on; - error_page 500 501 502 503 = @phpfallback; - } - - location @phpfallback { - try_files $uri =404; - include /etc/nginx/fastcgi_params; - - fastcgi_pass 127.0.0.1:; - - - fastcgi_pass unix:; - - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - #fastcgi_param PATH_INFO $fastcgi_script_name; - - fastcgi_param SERVER_NAME ; - - fastcgi_intercept_errors on; - } - - location @php { deny all; } - diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index 62b629045..52b0dc372 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -19,22 +19,10 @@ - - DocumentRoot + +DocumentRoot - - DocumentRoot - - - DocumentRoot - - - DocumentRoot - - DocumentRoot - - - +DocumentRoot ServerName @@ -253,45 +241,6 @@ php_admin_value open_basedir - - # suphp enabled - - - suPHP_Engine on - # suPHP_UserGroup - - suPHP_ConfigPath - - - SetHandler x-httpd-suphp - - suPHP_AddHandler x-httpd-suphp - - - - - # php as cgi enabled - ScriptAlias /php-cgi - Action php-cgi /php-cgi - - - SetHandler php-cgi - - - - - SetHandler php-cgi - - - - - Require all granted - - Order allow,deny - Allow from all - - - # php as fast-cgi enabled # For config options see: http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html @@ -426,64 +375,6 @@
- - - - - Require all granted - - Order allow,deny - Allow from all - - - - - SetHandler hhvm-fcgi - - - SetHandler hhvm-fcgi - - - - - SetHandler hhvm-fcgi - - - SetHandler hhvm-fcgi - - - Action hhvm-fcgi /hhvm-fcgi virtual - Alias /hhvm-fcgi {tmpl_var name='document_root'}/cgi-bin/hhvm-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} - FastCgiExternalServer {tmpl_var name='document_root'}/cgi-bin/hhvm-fcgi-{tmpl_var name='ip_address'}-{tmpl_var name='port'}-{tmpl_var name='domain'} -idle-timeout 300 -socket /var/run/hhvm/hhvm..sock -pass-header Authorization -pass-header Content-Type - - - - - Require all granted - - Order allow,deny - Allow from all - - - - - SetHandler "proxy:unix:/var/run/hhvm/hhvm..sock|fcgi://localhost" - - - SetHandler "proxy:unix:/var/run/hhvm/hhvm..sock|fcgi://localhost" - - - - - SetHandler "proxy:unix:/var/run/hhvm/hhvm..sock|fcgi://localhost" - - - SetHandler "proxy:unix:/var/run/hhvm/hhvm..sock|fcgi://localhost" - - - - - RewriteEngine on diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index bb4d7fdd7..5be47d050 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -159,7 +159,7 @@ class apache2_plugin { /* $data contains an array with these keys: * file -> full path of changed php_ini - * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm, hhvm or '' for all except 'mod') + * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') * php_version -> php ini path that changed (additional php versions) */ @@ -179,12 +179,6 @@ class apache2_plugin { $qrystr .= " AND fastcgi_php_version LIKE ?"; $param = '%:' . $data['php_version'] . ':%'; } - } elseif($data['mode'] == 'hhvm') { - $qrystr .= " AND php = 'hhvm'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version'] . ':%'; - } } else { $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; } @@ -1099,11 +1093,6 @@ class apache2_plugin { if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - //* add open_basedir restriction to custom php.ini content, required for suphp only - if(!stristr($data['new']['custom_php_ini'], 'open_basedir') && $data['new']['php'] == 'suphp') { - $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n"; - } - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); if(trim($data['new']['fastcgi_php_version']) != ''){ @@ -1550,7 +1539,7 @@ class apache2_plugin { $default_php_fpm = true; } } else { - if(trim($data['old']['fastcgi_php_version']) != '' && ($data['old']['php'] == 'php-fpm' || $data['old']['php'] == 'hhvm')){ + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ $default_php_fpm = false; list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; @@ -1823,7 +1812,6 @@ class apache2_plugin { } $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - $this->hhvm_update($data, $web_config); if($web_config['check_apache_config'] == 'y') { //* Test if apache starts with the new configuration file @@ -2143,8 +2131,6 @@ class apache2_plugin { // remove PHP-FPM pool if ($data['old']['php'] == 'php-fpm') { $this->php_fpm_pool_delete($data, $web_config); - } elseif($data['old']['php'] == 'hhvm') { - $this->hhvm_update($data, $web_config); } //remove the php cgi starter script if available @@ -2895,84 +2881,6 @@ class apache2_plugin { } } - private function hhvm_update($data, $web_config) { - global $app, $conf; - - if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_starter.master')) { - $content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_starter.master'); - } else { - $content = file_get_contents($conf['rootpath'] . '/conf/hhvm_starter.master'); - } - if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_monit.master')) { - $monit_content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_monit.master'); - } else { - $monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master'); - } - - if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || ($data['new']['php'] == 'hhvm' && isset($data['old']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) { - - // Custom php.ini settings - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - if(@is_dir('/etc/hhvm')) file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings); - } else { - if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini'); - } - - $content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content); - file_put_contents('/etc/init.d/hhvm_' . $data['new']['system_user'], $content); - exec('chmod +x /etc/init.d/hhvm_' . $data['new']['system_user'] . ' >/dev/null 2>&1'); - exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1'); - exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1'); - - if(is_dir('/etc/monit/conf.d')){ - $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content); - file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content); - if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']); - exec('/etc/init.d/monit restart >/dev/null 2>&1'); - } - - } elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') { - if($data['old']['system_user'] != ''){ - exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1'); - exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1'); - unlink('/etc/init.d/hhvm_' . $data['old']['system_user']); - if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini'); - } - - if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){ - if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user'])){ - unlink('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']); - } - if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){ - unlink('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user']); - } - exec('/etc/init.d/monit restart >/dev/null 2>&1'); - } - } - } - //* Update the PHP-FPM pool configuration file private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { global $app, $conf; diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index c1c71ac61..5024a3bff 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -1003,7 +1003,7 @@ class nginx_plugin { $default_php_fpm = true; } */ - if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){ + if($data['new']['php'] == 'php-fpm'){ if(trim($data['new']['fastcgi_php_version']) != ''){ $default_php_fpm = false; list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); @@ -1897,7 +1897,6 @@ class nginx_plugin { } $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - $this->hhvm_update($data, $web_config); if($web_config['check_apache_config'] == 'y') { //* Test if nginx starts with the new configuration file @@ -2219,9 +2218,6 @@ class nginx_plugin { // remove PHP-FPM pool if ($data['old']['php'] == 'php-fpm') { $this->php_fpm_pool_delete($data, $web_config); - } elseif($data['old']['php'] == 'hhvm') { - $this->hhvm_update($data, $web_config); - $this->php_fpm_pool_delete($data, $web_config); } //remove the php cgi starter script if available @@ -2577,92 +2573,13 @@ class nginx_plugin { } } - private function hhvm_update($data, $web_config) { - global $app, $conf; - - if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_starter.master')) { - $content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_starter.master'); - } else { - $content = file_get_contents($conf['rootpath'] . '/conf/hhvm_starter.master'); - } - if(file_exists($conf['rootpath'] . '/conf-custom/hhvm_monit.master')) { - $monit_content = file_get_contents($conf['rootpath'] . '/conf-custom/hhvm_monit.master'); - } else { - $monit_content = file_get_contents($conf['rootpath'] . '/conf/hhvm_monit.master'); - } - - if($data['new']['php'] == 'hhvm' && $data['old']['php'] != 'hhvm' || ($data['new']['php'] == 'hhvm' && isset($data['old']['custom_php_ini']) && isset($data['new']['custom_php_ini']) && $data['new']['custom_php_ini'] != $data['old']['custom_php_ini'])) { - - // Custom php.ini settings - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - if(@is_dir('/etc/hhvm')) file_put_contents('/etc/hhvm/'.$data['new']['system_user'].'.ini', $custom_php_ini_settings); - } else { - if($data['old']['system_user'] != '' && is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini'); - } - - $content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $content); - file_put_contents('/etc/init.d/hhvm_' . $data['new']['system_user'], $content); - exec('chmod +x /etc/init.d/hhvm_' . $data['new']['system_user'] . ' >/dev/null 2>&1'); - exec('/usr/sbin/update-rc.d hhvm_' . $data['new']['system_user'] . ' defaults >/dev/null 2>&1'); - exec('/etc/init.d/hhvm_' . $data['new']['system_user'] . ' restart >/dev/null 2>&1'); - - if(is_dir('/etc/monit/conf.d')){ - $monit_content = str_replace('{SYSTEM_USER}', $data['new']['system_user'], $monit_content); - file_put_contents('/etc/monit/conf.d/00-hhvm_' . $data['new']['system_user'], $monit_content); - if(is_file('/etc/monit/conf.d/hhvm_' . $data['new']['system_user'])) unlink('/etc/monit/conf.d/hhvm_' . $data['new']['system_user']); - exec('/etc/init.d/monit restart >/dev/null 2>&1'); - } - - } elseif($data['new']['php'] != 'hhvm' && $data['old']['php'] == 'hhvm') { - if($data['old']['system_user'] != ''){ - exec('/etc/init.d/hhvm_' . $data['old']['system_user'] . ' stop >/dev/null 2>&1'); - exec('/usr/sbin/update-rc.d hhvm_' . $data['old']['system_user'] . ' remove >/dev/null 2>&1'); - unlink('/etc/init.d/hhvm_' . $data['old']['system_user']); - if(is_file('/etc/hhvm/'.$data['old']['system_user'].'.ini')) unlink('/etc/hhvm/'.$data['old']['system_user'].'.ini'); - } - - if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']) || is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){ - if(is_file('/etc/monit/conf.d/hhvm_' . $data['old']['system_user'])){ - unlink('/etc/monit/conf.d/hhvm_' . $data['old']['system_user']); - } - if(is_file('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user'])){ - unlink('/etc/monit/conf.d/00-hhvm_' . $data['old']['system_user']); - } - exec('/etc/init.d/monit restart >/dev/null 2>&1'); - } - } - } - //* Update the PHP-FPM pool configuration file private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { global $app, $conf; $pool_dir = trim($pool_dir); $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); - // HHVM => PHP-FPM-Fallback - if($data['new']['php'] == 'php-fpm' || $data['new']['php'] == 'hhvm'){ + if($data['new']['php'] == 'php-fpm'){ if(trim($data['new']['fastcgi_php_version']) != ''){ $default_php_fpm = false; list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); @@ -2683,8 +2600,7 @@ class nginx_plugin { $app->uses("getconf"); $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - // HHVM => PHP-FPM-Fallback - if($data['new']['php'] != 'php-fpm' && $data['new']['php'] != 'hhvm'){ + if($data['new']['php'] != 'php-fpm'){ if(@is_file($pool_dir.$pool_name.'.conf')){ $app->system->unlink($pool_dir.$pool_name.'.conf'); //$reload = true; diff --git a/server/plugins-available/pma_symlink_plugin.inc.php b/server/plugins-available/pma_symlink_plugin.inc.php index 6b9b4fb26..88c68da83 100644 --- a/server/plugins-available/pma_symlink_plugin.inc.php +++ b/server/plugins-available/pma_symlink_plugin.inc.php @@ -101,9 +101,7 @@ class pma_symlink_plugin { } $symlink = true; - if($data["new"]["php"] == "suphp") $symlink = false; - elseif($data["new"]["php"] == "cgi" && $data["new"]["suexec"] == "y") $symlink = false; - elseif($data["new"]["php"] == "fast-cgi" && $data["new"]["suexec"] == "y") $symlink = false; + if($data["new"]["php"] == "fast-cgi" && $data["new"]["suexec"] == "y") $symlink = false; if(!is_dir($data["new"]["document_root"]."/web")) mkdir($data["new"]["document_root"].'/web', 0755, true); diff --git a/server/plugins-available/webmail_symlink_plugin.inc.php b/server/plugins-available/webmail_symlink_plugin.inc.php index c64b706d7..9edce913d 100644 --- a/server/plugins-available/webmail_symlink_plugin.inc.php +++ b/server/plugins-available/webmail_symlink_plugin.inc.php @@ -101,9 +101,7 @@ class webmail_symlink_plugin { } $symlink = true; - if($data["new"]["php"] == "suphp") $symlink = false; - elseif($data["new"]["php"] == "cgi" && $data["new"]["suexec"] == "y") $symlink = false; - elseif($data["new"]["php"] == "fast-cgi" && $data["new"]["suexec"] == "y") $symlink = false; + if($data["new"]["php"] == "fast-cgi" && $data["new"]["suexec"] == "y") $symlink = false; if(!is_dir($data["new"]["document_root"]."/web")) mkdir($data["new"]["document_root"].'/web', 0755, true); -- GitLab From 9070533758aa3a8af9da7efab6436fa7bdadbe46 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 21:27:20 +0100 Subject: [PATCH 169/310] - unified nginx and apache plugin - sourced out duplicate code --- .../classes/plugin_webserver_apache.inc.php | 501 +++ .../lib/classes/plugin_webserver_base.inc.php | 3011 ++++++++++++++++ .../classes/plugin_webserver_nginx.inc.php | 840 +++++ .../plugins-available/apache2_plugin.inc.php | 3043 +--------------- server/plugins-available/nginx_plugin.inc.php | 3064 +---------------- 5 files changed, 4462 insertions(+), 5997 deletions(-) create mode 100644 server/lib/classes/plugin_webserver_apache.inc.php create mode 100644 server/lib/classes/plugin_webserver_base.inc.php create mode 100644 server/lib/classes/plugin_webserver_nginx.inc.php diff --git a/server/lib/classes/plugin_webserver_apache.inc.php b/server/lib/classes/plugin_webserver_apache.inc.php new file mode 100644 index 000000000..8393f529a --- /dev/null +++ b/server/lib/classes/plugin_webserver_apache.inc.php @@ -0,0 +1,501 @@ +getconf->get_server_config($conf['server_id'], 'web'); + + // Rewrite rules + $rewrite_rules = array(); + $rewrite_wildcard_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ + $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8); + $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8); + } else { + $rewrite_target = $data['new']['redirect_path']; + $rewrite_target_ssl = $data['new']['redirect_path']; + } + /* Disabled path extension + if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { + $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; + } + */ + + switch($data['new']['subdomain']) { + case 'www': + $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_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')); + break; + case '*': + $rewrite_wildcard_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')); + break; + default: + $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')); + } + } + + $server_alias = array(); + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); + $alias_seo_redirects = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain']; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain']; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + switch($alias['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; + break; + case '*': + $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; + break; + default: + $server_alias[] .= $alias['domain']; + break; + } + $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); + + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'apache'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + + // Rewriting + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { + if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ + $rewrite_target = 'http'.substr($alias['redirect_path'], 8); + $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8); + } else { + $rewrite_target = $alias['redirect_path']; + $rewrite_target_ssl = $alias['redirect_path']; + } + + switch($alias['subdomain']) { + case 'www': + $rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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.'.$alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + break; + case '*': + $rewrite_wildcard_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + break; + default: + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2)); + else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']); + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + } + } + } + } + + //* If we have some alias records + if($server_alias) { + //* begin a new ServerAlias line after 32 alias domains to avoid apache bugs + $server_alias_str = 'ServerAlias '.$server_alias[0]; + for($n=1;$nsetVar('alias', $server_alias_str); + unset($server_alias_str); + unset($n); + } else { + $tpl->setVar('alias', ''); + } + + if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules + + if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0 || $data['new']['rewrite_to_https'] == 'y') { + $tpl->setVar('rewrite_enabled', 1); + } else { + $tpl->setVar('rewrite_enabled', 0); + } + + //$tpl->setLoop('redirects',$rewrite_rules); + $this->rewrite_rules = $rewrite_rules; + $this->alias_seo_redirects = $alias_seo_redirects; + + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processCustomDirectives(&$tpl, &$data, &$vhost_data) { + global $app; + + // Custom Apache directives + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $vhost_data['apache_directives'] = $snippet['snippet']; + } + } + // Make sure we only have Unix linebreaks + $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); + $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] + ); + $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); + + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processPhpStarters(&$tpl, &$data, &$vhost_data) { + global $app, $conf; + + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + /** + * install fast-cgi starter script and add script aliasd config + * first we create the script directory if not already created, then copy over the starter script + * settings are copied over from the server ini config for now + * TODO: Create form for fastcgi configs per site. + */ + + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + if ($data['new']['php'] == 'fast-cgi') { + + $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']); + $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); + + if (!is_dir($fastcgi_starter_path)) { + $app->system->mkdirpath($fastcgi_starter_path); + $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG); + } + + $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); + $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); + if($web_config['security_level'] == 10) { + $app->system->chmod($fastcgi_starter_path, 0755); + } else { + $app->system->chmod($fastcgi_starter_path, 0550); + } + + $fcgi_tpl = new tpl(); + $fcgi_tpl->newTemplate('php-fcgi-starter.master'); + $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion()); + $fcgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + + if(trim($data['new']['fastcgi_php_version']) != ''){ + // $custom_fastcgi_php_name + list(, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); + if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); + } + + if(trim($data['new']['custom_php_ini']) != '') { + $has_custom_php_ini = true; + } else { + $has_custom_php_ini = false; + } + + $web_folder = $app->plugin_webserver_base->getWebFolder($data, 'web', false); + + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; + if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; + if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); + + // Support for multiple PHP versions (FastCGI) + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_fastcgi_php = false; + if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/'; + } else { + $default_fastcgi_php = true; + } + + if($has_custom_php_ini) { + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); + } else { + if($default_fastcgi_php){ + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); + } else { + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir)); + } + } + $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); + $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children'])); + $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests'])); + if($default_fastcgi_php){ + $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin'])); + } else { + $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable)); + } + $fcgi_tpl->setVar('security_level', intval($web_config['security_level'])); + $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain'])); + + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; + $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); + + $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab()); + unset($fcgi_tpl); + + $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); + + if($web_config['security_level'] == 10) { + $app->system->chmod($fcgi_starter_script, 0755); + } else { + $app->system->chmod($fcgi_starter_script, 0550); + } + $app->system->chown($fcgi_starter_script, $data['new']['system_user']); + $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); + + $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); + $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); + $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); + $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); + + } else { + //remove the php fastgi starter script if available + $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : ''); + if ($data['old']['php'] == 'fast-cgi') { + $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); + $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); + if($data['old']['type'] == 'vhost') { + if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); + if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path); + } else { + if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); + } + } + } + + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processVhosts(&$tpl, &$data, &$vhost_data, $ssl_data) { + global $app, $conf; + + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + //* create empty vhost array + $vhosts = array(); + + //* Add vhost for ipv4 IP + + //* use ip-mapping for web-mirror + if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { + $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; + $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); + $data['new']['ip_address'] = $newip['destination_ip']; + unset($newip); + } + + $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80); + if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); + if(count($this->alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $this->alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr); + + //* Add vhost for ipv4 IP with SSL + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { + $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); + if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); + $ipv4_ssl_alias_seo_redirects = $this->alias_seo_redirects; + if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){ + for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); + } + + //* Add vhost for IPv6 IP + if($data['new']['ipv6_address'] != '') { + //* rewrite ipv6 on mirrors + /* chang $conf to $web_config */ + if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':', $data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':', $explode_v6); + } + } + if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::'; + $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); + if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); + if(count($this->alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $this->alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr); + + //* Add vhost for ipv6 IP with SSL + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { + $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); + if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); + $ipv6_ssl_alias_seo_redirects = $this->alias_seo_redirects; + if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){ + for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); + } + } + + //* Set the vhost loop + $tpl->setLoop('vhosts', $vhosts); + return; + } + + public function testWebserverConfig() { + global $app; + // if no output is given, check again + $webserver_binary = ''; + $webserver_check_output = null; + $webserver_check_retval = 0; + exec('which apache2ctl apache2 httpd2 httpd apache 2>/dev/null', $webserver_check_output, $webserver_check_retval); + if($webserver_check_retval == 0){ + $webserver_binary = reset($webserver_check_output); + } + if($webserver_binary != ''){ + $tmp_output = null; + $tmp_retval = 0; + exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } + } +} diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php new file mode 100644 index 000000000..715270cc5 --- /dev/null +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -0,0 +1,3011 @@ +plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); + + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); + + $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); + + $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); + + $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + + $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + + $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); + + $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); + + $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); + + if($server_type === 'apache') { + $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); + } + } + + private function get_master_php_ini_content($web_data) { + global $app, $conf; + + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + $php_ini_content = ''; + $master_php_ini_path = ''; + + if($web_data['php'] == 'mod') { + $master_php_ini_path = $web_config['php_ini_path_apache']; + } else { + // check for custom php + if($web_data['fastcgi_php_version'] != '') { + $tmp = explode(':', $web_data['fastcgi_php_version']); + if(isset($tmp[2])) { + $tmppath = $tmp[2]; + if(substr($tmppath, -7) != 'php.ini') { + if(substr($tmppath, -1) != '/') $tmppath .= '/'; + $tmppath .= 'php.ini'; + } + if(file_exists($tmppath)) { + $master_php_ini_path = $tmppath; + } + unset($tmppath); + } + unset($tmp); + } + + if(!$master_php_ini_path) { + if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { + $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; + } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) { + $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; + } else { + $master_php_ini_path = $web_config['php_ini_path_cgi']; + } + } + } + + // Resolve inconsistant path settings + if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) { + $master_php_ini_path .= '/php.ini'; + } + + // Load the custom php.ini content + if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) { + $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; + } + + return $php_ini_content; + } + + // Handle php.ini changes + /* TODO: change to be compatible to nginx, too */ + public function eventPhpIniChanged($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + if($server_type === 'nginx') { + // not yet implemented + return; + } + + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + /* $data contains an array with these keys: + * file -> full path of changed php_ini + * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') + * php_version -> php ini path that changed (additional php versions) + */ + + $param = ''; + $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''"; + if($data['mode'] == 'mod') { + $qrystr .= " AND php = 'mod'"; + } elseif($data['mode'] == 'fast-cgi') { + $qrystr .= " AND php = 'fast-cgi'"; + if($data['php_version']) { + $qrystr .= " AND fastcgi_php_version LIKE ?"; + $param = '%:' . $data['php_version']; + } + } elseif($data['mode'] == 'php-fpm') { + $qrystr .= " AND php = 'php-fpm'"; + if($data['php_version']) { + $qrystr .= " AND fastcgi_php_version LIKE ?"; + $param = '%:' . $data['php_version'] . ':%'; + } + } else { + $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; + } + + + //** Get all the webs + $web_domains = $app->db->queryAllRecords($qrystr, $param); + foreach($web_domains as $web_data) { + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user']; + $web_folder = 'web'; + if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') { + $web_folder = $web_data['web_folder']; + $custom_php_ini_dir .= '_' . $web_folder; + } + if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); + + if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir); + + $php_ini_content = $this->get_master_php_ini_content($web_data); + + if(intval($web_data['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini'])); + $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); + $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG); + } + + if(count($web_domains) > 0) { + //* We do not check the apache config here - we only changed the php.ini + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $is_chrooted = true; + $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); + } else { + $is_chrooted = false; + } + + $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG); + if($is_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + } else { + $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG); + } + } + + // Handle the creation of SSL certificates + public function eventSsl($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + $app->uses('system'); + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) + $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); + + //* Only vhosts can have a ssl cert + if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; + + // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); + if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + //* Create a SSL Certificate, but only if this is not a mirror server. + if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { + + $this->ssl_certificate_changed = true; + + //* Rename files if they exist + if(file_exists($key_file)){ + $app->system->rename($key_file, $key_file.'.bak'); + $app->system->chmod($key_file.'.bak', 0400); + } + if(file_exists($key_file2)){ + $app->system->rename($key_file2, $key_file2.'.bak'); + $app->system->chmod($key_file2.'.bak', 0400); + } + if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); + if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); + + $rand_file = $ssl_dir.'/random_file'; + $rand_data = md5(uniqid(microtime(), 1)); + for($i=0; $i<1000; $i++) { + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + } + $app->system->file_put_contents($rand_file, $rand_data); + + $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); + + $ssl_cnf = " RANDFILE = $rand_file + + [ req ] + default_bits = 2048 + default_md = sha256 + default_keyfile = keyfile.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + prompt = no + output_password = $ssl_password + + [ req_distinguished_name ] + C = ".trim($data['new']['ssl_country'])." + " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " + " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." + " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." + " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." + CN = $domain + emailAddress = webmaster@".$data['new']['domain']." + + [ req_attributes ] + ";//challengePassword = A challenge password"; + + $ssl_cnf_file = $ssl_dir.'/openssl.conf'; + $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); + + $rand_file = escapeshellcmd($rand_file); + $key_file2 = escapeshellcmd($key_file2); + $openssl_cmd_key_file2 = $key_file2; + if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate + $key_file = escapeshellcmd($key_file); + $openssl_cmd_key_file = $key_file; + if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate + $ssl_days = 3650; + $csr_file = escapeshellcmd($csr_file); + $openssl_cmd_csr_file = $csr_file; + if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate + $config_file = escapeshellcmd($ssl_cnf_file); + $crt_file = escapeshellcmd($crt_file); + $openssl_cmd_crt_file = $crt_file; + if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate + + if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { + + exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); + exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); + exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); + + if(file_exists($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); + $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); + } + if (@filesize($crt_file)==0 || !file_exists($crt_file)){ + exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); + $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + } + + } + + $app->system->chmod($key_file2, 0400); + $app->system->chmod($key_file, 0400); + @$app->system->unlink($config_file); + @$app->system->unlink($rand_file); + $ssl_request = $app->system->file_get_contents($csr_file); + $ssl_cert = $app->system->file_get_contents($crt_file); + $ssl_key = $app->system->file_get_contents($key_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + + //* Check that the SSL key is not password protected + if($data["new"]["ssl_action"] == 'save') { + if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* and check that SSL cert does not contain subdomain of domain acme.invalid + if($data["new"]["ssl_action"] == 'save') { + $tmp = array(); + $crt_data = ''; + exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); + $crt_data = implode("\n",$tmp); + if(stristr($crt_data,'.acme.invalid')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + $this->ssl_certificate_changed = true; + + //* Backup files + if(file_exists($key_file)){ + $app->system->copy($key_file, $key_file.'~'); + $app->system->chmod($key_file.'~', 0400); + } + if(file_exists($key_file2)){ + $app->system->copy($key_file2, $key_file2.'~'); + $app->system->chmod($key_file2.'~', 0400); + } + if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); + if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); + if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~'); + + //* Write new ssl files + if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); + + if($server_type === 'nginx' || ($server_type === 'apache' && version_compare($app->system->getapacheversion(true), '2.4.8', '>='))) { + // In nginx and apache 2.4.8 and newer, the ssl crt file contains the bundle, so we need no separate bundle file + $tmp_data = ''; + if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n"; + if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"]; + if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $app->file->unix_nl($tmp_data)); + } else { + // Write separate crt and bundle file + if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); + if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]); + } + + //* Write the key file, if field is empty then import the key into the db + if(trim($data["new"]["ssl_key"]) != '') { + $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); + $app->system->chmod($key_file, 0400); + } else { + $ssl_key = $app->system->file_get_contents($key_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); + } + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } + + //* Delete a SSL certificate + if($data['new']['ssl_action'] == 'del') { + if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); + $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + } + $app->system->unlink($csr_file); + $app->system->unlink($crt_file); + $app->system->unlink($bundle_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } + + } + + + //* Update the awstats configuration file + public function awstats_update($data, $web_config) { + global $app; + + $web_folder = $data['new']['web_folder']; + if($data['new']['type'] == 'vhost') $web_folder = 'web'; + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); + if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + } + + $content = ''; + if (is_file($awstats_conf_dir."/awstats.conf")) { + $include_file = $awstats_conf_dir."/awstats.conf"; + } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { + $include_file = $awstats_conf_dir."/awstats.model.conf"; + } + $content .= "Include \"".$include_file."\"\n"; + $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; + $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; + $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; + + if (isset($include_file)) { + $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); + $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); + } else { + $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); + } + } + + if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); + if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { + $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } else { + $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } + } + + //* Delete the awstats configuration file + public function awstats_delete ($data, $web_config) { + global $app; + + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); + } + } + + public function eventUpdate($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + if($server_type === 'nginx') { + //* Check if the apache plugin is enabled + if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { + $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN); + return 0; + } + } + + if($this->action != 'insert') $this->action = 'update'; + + if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { + + $old_parent_domain_id = intval($data['old']['parent_domain_id']); + $new_parent_domain_id = intval($data['new']['parent_domain_id']); + + // If the parent_domain_id has been changed, we will have to update the old site as well. + if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update($event_name, $data); + } + + // This is not a vhost, so we need to update the parent record instead. + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + } + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $is_chrooted = true; + $app->log('Info: Webserver is chrooted.', LOGLEVEL_DEBUG); + } else { + $is_chrooted = false; + } + + if($data['new']['document_root'] == '') { + if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); + return 0; + } + if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false + || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { + $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); + return 0; + } + if(trim($data['new']['domain']) == '') { + $app->log('domain is empty', LOGLEVEL_WARN); + return 0; + } + + $web_folder = $this->getWebFolder($data, 'web', false); + $log_folder = $this->getWebFolder($data, 'log', false); + $old_web_folder = $this->getWebFolder($data, 'web', true); + $old_log_folder = $this->getWebFolder($data, 'log', true); + + // Create group and user, if not exist + $app->uses('system'); + + if($web_config['connect_userid_to_webid'] == 'y') { + //* Calculate the uid and gid + $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); + $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); + $fixed_uid_param = '--uid '.$fixed_uid_gid; + $fixed_gid_param = '--gid '.$fixed_uid_gid; + + //* Check if a ispconfigend user and group exists and create them + if(!$app->system->is_group('ispconfigend')) { + exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + if(!$app->system->is_user('ispconfigend')) { + exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + } else { + $fixed_uid_param = ''; + $fixed_gid_param = ''; + } + + $groupname = escapeshellcmd($data['new']['system_group']); + if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { + exec('groupadd '.$fixed_gid_param.' '.$groupname); + if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); + $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); + } + + $username = escapeshellcmd($data['new']['system_user']); + if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + } else { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + } + $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); + } + + //* If the client of the site has been changed, we have a change of the document root + if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { + + //* Get the old client ID + $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $old_client_id = intval($old_client['client_id']); + unset($old_client); + + //* Remove the old symlinks + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + //* Remove protection of old folders + $app->system->web_folder_protection($data['old']['document_root'], false); + + if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { + //* Move the site data + $tmp_docroot = explode('/', $data['new']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $new_dir = implode('/', $tmp_docroot); + + $tmp_docroot = explode('/', $data['old']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $old_dir = implode('/', $tmp_docroot); + + //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path + if(@is_dir($data['new']['document_root'])) { + $app->system->web_folder_protection($data['new']['document_root'], false); + $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); + $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); + } + + //* Unmount the old log directory bfore we move the log dir + exec('umount -l '.escapeshellcmd($old_dir.'/log')); + + //* Create new base directory, if it does not exist yet + if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); + $app->system->web_folder_protection($data['old']['document_root'], false); + exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); + //$app->system->rename($data['old']['document_root'],$new_dir); + $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); + + // Handle the change in php_open_basedir + $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); + + //* Change the owner of the website files to the new website owner + exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); + + //* Change the home directory and group of the website user + $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; + $command .= ' --home '.escapeshellcmd($data['new']['document_root']); + $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + exec($command); + } + + if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* Change the log mount + /* + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + */ + + $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + + if($web_config['network_filesystem'] == 'y') { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } + + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + + } + + //print_r($data); + + // Check if the directories are there and create them if necessary. + $app->system->web_folder_protection($data['new']['document_root'], false); + + if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); + 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); + 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($server_type === 'apache') { + if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); + } + + if(!is_dir($data['new']['document_root'].'/.ssh')) { + $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); + $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); + $app->system->chown($data['new']['document_root'].'/.ssh', $username); + $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); + } + + //* Create the new private directory + if(!is_dir($data['new']['document_root'].'/private')) { + $app->system->mkdirpath($data['new']['document_root'].'/private'); + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + } + + + // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); + if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); + + //* remove old log mount + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + + //* Unmount log directory + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + } + + //* Create the log dir if nescessary and mount it + if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { + if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); + if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); + $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + //* add mountpoint to fstab + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; + $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); + } + + $app->system->web_folder_protection($data['new']['document_root'], true); + + // Get the client ID + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // Remove old symlinks, if site is renamed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // remove the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + } + + // Create the symlinks for the sites + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + //* Remove symlink if target folder has been changed. + if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + } + // create the symlinks, if not exist + if(!is_link($tmp_symlink)) { + // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + if ($web_config["website_symlinks_rel"] == 'y') { + $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); + } else { + exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + } + + $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + + + // Install the Standard or Custom Error, Index and other related files + // /usr/local/ispconfig/server/conf is for the standard files + // /usr/local/ispconfig/server/conf-custom is for the custom files + // setting a local var here + + // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; + if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + + // Copy the error pages + if($data['new']['errordocs']) { + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + } + + //* Copy the web skeleton files only when there is no index.ph or index.html file yet + if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + + if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { + // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + //} + } else { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + } else { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + } + } + exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + + //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before + } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { + + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); + } // end copy error docs + + // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias + if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { + if($data['new']['hd_quota'] > 0) { + $blocks_soft = $data['new']['hd_quota'] * 1024; + $blocks_hard = $blocks_soft + 1024; + $mb_soft = $data['new']['hd_quota']; + $mb_hard = $mb_soft + 1; + } else { + $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; + } + + // get the primitive folder for document_root and the filesystem, will need it later. + $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); + $file_system = $df_output[0]; + $primitive_root = $df_output[1]; + + if($file_system == 'xfs') { + exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); + + // xfs only supports timers globally, not per user. + exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); + + unset($primitive_root, $df_output, $mb_hard, $mb_soft); + } else { + if($app->system->is_installed('setquota')) { + exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); + exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); + } + } + } + + if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { + // Chown and chmod the directories below the document root + $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + // The document root itself has to be owned by root in normal level and by the web owner in security level 20 + if($web_config['security_level'] == 20) { + $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } else { + $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } + } + + //* add the user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update + $user_config_key = 'user'; + if($server_type === 'nginx') { + $user_config_key = 'nginx_user'; + } + if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config[$user_config_key])); + + //* If the security level is set to high + if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) { + + $app->system->web_folder_protection($data['new']['document_root'], false); + + //* Check if we have the new private folder and create it if nescessary + if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); + + if($web_config['security_level'] == 20) { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0711); + if($server_type === 'apache') { + $app->system->chmod($data['new']['document_root'].'/webdav', 0710); + } + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751); + + // make tmp directory writable for webserver and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + $command = 'usermod'; + $command .= ' --groups sshusers'; + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + $app->system->_exec($command); + } + + //* if we have a chrooted environment + if($is_chrooted) { + $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* add the user to the client group in the chroot environment + $tmp_groupfile = $app->system->server_conf['group_datei']; + $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; + $app->system->add_user_to_group($groupname, escapeshellcmd($web_config[$user_config_key])); + $app->system->server_conf['group_datei'] = $tmp_groupfile; + unset($tmp_groupfile); + } + + //* Chown all default directories + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + if($server_type === 'apache') { + $app->system->chown($data['new']['document_root'].'/webdav', $username); + $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); + } + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + + if($web_folder != 'web'){ + $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); + } + + // If the security Level is set to medium + } else { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0755); + if($server_type === 'apache') { + $app->system->chmod($data['new']['document_root'].'/webdav', 0755); + } + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); + if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755); + + // make temp directory writable for webserver and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + if($server_type === 'apache') { + $app->system->chown($data['new']['document_root'].'/webdav', $username); + $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); + } + if($web_folder != 'web'){ + $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); + } + } + } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && + (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { + + if($web_config['security_level'] == 20) { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } else { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } + } + + //* Protect web folders + $app->system->web_folder_protection($data['new']['document_root'], true); + + if($data['new']['type'] == 'vhost') { + // Change the ownership of the error log to the root user + if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); + $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + } + + //* Write the custom php.ini file, if custom_php_ini field is not empty + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; + if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; + if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); + + if(trim($data['new']['fastcgi_php_version']) != ''){ + // $custom_fastcgi_php_name, $custom_fastcgi_php_executable + list(,, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); + if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); + } + + //* Create custom php.ini + if(trim($data['new']['custom_php_ini']) != '') { + $has_custom_php_ini = true; + if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); + + $php_ini_content = $this->get_master_php_ini_content($data['new']); + $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini'])); + + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $php_ini_content .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); + } else { + $has_custom_php_ini = false; + if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); + } + + $vhost_template_name = 'vhost.conf.master'; + if($server_type === 'nginx') { + $vhost_template_name = 'nginx_vhost.conf.master'; + } + + //* Create the vhost config file + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate($vhost_template_name); + + $vhost_data = $data['new']; + //unset($vhost_data['ip_address']); + $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; + $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; + $vhost_data['web_basedir'] = $web_config['website_basedir']; + $vhost_data['security_level'] = $web_config['security_level']; + $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override']; + $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; + $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; + $vhost_data['has_custom_php_ini'] = $has_custom_php_ini; + $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir); + $vhost_data['logging'] = $web_config['logging']; + + // IPv6 + if($data['new']['ipv6_address'] != ''){ + $tpl->setVar('ipv6_enabled', 1); + if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':', $data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':', $explode_v6); + $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; + } + } + } + + if($server_type === 'nginx') { + $app->plugin_webserver_nginx->processPhpFpm($tpl, $data, $vhost_data); + $app->plugin_webserver_nginx->processRewriteRules($tpl, $data, $vhost_data); + } else { + $app->plugin_webserver_apache->processCustomDirectives($tpl, $data, $vhost_data); + } + + // Custom Apache directives + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $vhost_data['apache_directives'] = $snippet['snippet']; + } + } + // Make sure we only have Unix linebreaks + $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); + $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] + ); + $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); + + $app->uses('letsencrypt'); + // Check if a SSL cert exists + $tmp = $app->letsencrypt->get_website_certificate_paths($data); + $domain = $tmp['domain']; + $key_file = $tmp['key']; + $key_file2 = $tmp['key2']; + $csr_file = $tmp['csr']; + $crt_file = $tmp['crt']; + $bundle_file = $tmp['bundle']; + unset($tmp); + + $data['new']['ssl_domain'] = $domain; + $vhost_data['ssl_domain'] = $domain; + $vhost_data['ssl_crt_file'] = $crt_file; + $vhost_data['ssl_key_file'] = $key_file; + $vhost_data['ssl_bundle_file'] = $bundle_file; + + //* Generate Let's Encrypt SSL certificat + if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server + ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration + || ($data['old']['domain'] != $data['new']['domain']) // we have domain update + || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain + || $this->update_letsencrypt == true + )) { + + $success = $app->letsencrypt->request_certificates($data, $server_type); + if($success) { + /* we don't need to store it. + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } else { + $data['new']['ssl_letsencrypt'] = 'n'; + if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); + } + } + + if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; + + // HTTP/2.0 ? + $vhost_data['enable_http2'] = 'n'; + if($vhost_data['enable_spdy'] == 'y'){ + $tmp_output = null; + $tmp_retval = 0; + if($server_type === 'apache') { + // check if apache supports http_v2 + exec("2>&1 apachectl -M | grep http2_module", $tmp_output, $tmp_retval); + } else { + // check if nginx support http_v2; if so, use that instead of spdy + exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval); + } + if($tmp_retval == 0){ + $vhost_data['enable_http2'] = 'y'; + $vhost_data['enable_spdy'] = 'n'; + } + unset($tmp_output, $tmp_retval); + } + + // Set SEO Redirect + if($data['new']['seo_redirect'] != ''){ + $vhost_data['seo_redirect_enabled'] = 1; + $tmp_seo_redirects = $this->get_seo_redirects($data['new'], '', false, $server_type); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + foreach($tmp_seo_redirects as $key => $val){ + $vhost_data[$key] = $val; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + + if($server_type === 'nginx') { + if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $vhost_data['ssl_enabled'] = 1; + $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); + } else { + $vhost_data['ssl_enabled'] = 0; + $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG); + } + } + + // set logging variable + $vhost_data['logging'] = $web_config['logging']; + + $tpl->setVar($vhost_data); + + $config_prefix = ''; + if($server_type === 'apache') { + $ssl_data = array( + 'crt_file' => $crt_file, + 'key_file' => $key_file, + ); + + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + $app->plugin_webserver_apache->processRewriteRules($tpl, $data, $vhost_data); + $app->plugin_webserver_apache->processPhpStarters($tpl, $data, $vhost_data); + $app->plugin_webserver_apache->processVhosts($tpl, $data, $vhost_data, $ssl_data); + } elseif($server_type === 'nginx') { + $app->plugin_webserver_nginx->processStatsAuth($tpl, $data, $vhost_data); + $config_prefix = 'nginx_'; + } + + + $vhost_file = escapeshellcmd($web_config[$config_prefix.'vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); + //* Make a backup copy of vhost file + if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~'); + + //* Write vhost file + if($server_type === 'apache') { + $app->system->file_put_contents($vhost_file, $tpl->grab()); + } else { + $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); + } + $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + unset($tpl); + + if($server_type === 'apache') { + /* + * maybe we have some webdav - user. If so, add them... + */ + $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav'); + } + + //* Set the symlink to enable the vhost + //* First we check if there is a old type of symlink and remove it + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); + + //* Remove old or changed symlinks + if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + } + + //* New symlink + if($data['new']['subdomain'] == '*') { + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + } else { + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + } + if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { + symlink($vhost_file, $vhost_symlink); + $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + // remove old symlink and vhost file, if domain name of the site has changed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_file = escapeshellcmd($web_config[$config_prefix.'vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + $app->system->unlink($vhost_file); + $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); + } + + if($server_type === 'apache') { + //* Create .htaccess and .htpasswd file for website statistics + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats'); + $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user"; + $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file); + $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755); + unset($ht_file); + + if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { + if(trim($data['new']['stats_password']) != '') { + $htp_file = 'admin:'.trim($data['new']['stats_password']); + $app->system->web_folder_protection($data['new']['document_root'], false); + $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file); + $app->system->web_folder_protection($data['new']['document_root'], true); + $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755); + unset($htp_file); + } + } + } else { + // create password file for stats directory + $stats_web_folder = $app->plugin_webserver_nginx->getStatsFolder($data); + + if(!is_file($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { + if(trim($data['new']['stats_password']) != '') { + $htp_file = 'admin:'.trim($data['new']['stats_password']); + $app->system->file_put_contents($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', $htp_file); + $app->system->chmod($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', 0755); + unset($htp_file); + } + } + } + + //* Create awstats configuration + if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + $app->plugin_webserver_base->awstats_update($data, $web_config); + } + + /** + * PHP-FPM + */ + // Support for multiple PHP versions + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + + $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type); + if($server_type === 'nginx') { + $fpm_data = array( + 'use_tcp' => $use_tcp, + 'use_socket' => $use_socket, + 'socket_dir' => $socket_dir, + 'fpm_socket' => $fpm_socket, + 'fpm_port' => $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1 + ); + $app->plugin_webserver_nginx->processCustomDirectives($tpl, $data, $vhost_data, $fpm_data); + } + + if($web_config['check_apache_config'] == 'y') { + //* Test if server starts with the new configuration file + $online_status_before_restart = $this->_checkTcp('localhost', 80); + $app->log('web server status is: '.($online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + + $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure + $app->log('web server restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); + + // wait a few seconds, before we test the status again + $online_status_after_restart = false; + sleep(2); + for($i = 0; $i < 5; $i++) { + $online_status_after_restart = $this->_checkTcp('localhost', 80); + if($online_status_after_restart) break; + sleep(1); + } + //* Check if server restarted successfully if it was online before + $app->log('web server online status after restart is: '.($online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + if($online_status_before_restart && !$online_status_after_restart || $retval['retval'] > 0) { + $app->log('web server did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); + if(is_array($retval['output']) && !empty($retval['output'])){ + $app->log('Reason for web server restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $retval['output'])); + } else { + $app->plugin_webserver_apache->testWebserverConfig(); + } + $app->system->copy($vhost_file, $vhost_file.'.err'); + + if(is_file($vhost_file.'~')) { + //* Copy back the last backup file + $app->system->copy($vhost_file.'~', $vhost_file); + } else { + //* There is no backup file, so we create a empty vhost file with a warning message inside + $app->system->file_put_contents($vhost_file, "# web server did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); + } + + if($this->ssl_certificate_changed === true) { + if($server_type === 'nginx') { + /* TODO: check if needed! */ + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + } + + //* Backup the files that might have caused the error + if(is_file($key_file)){ + $app->system->copy($key_file, $key_file.'.err'); + $app->system->chmod($key_file.'.err', 0400); + } + if(is_file($key_file2)){ + $app->system->copy($key_file2, $key_file2.'.err'); + $app->system->chmod($key_file2.'.err', 0400); + } + if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); + if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); + if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err'); + + //* Restore the ~ backup files + if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); + if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); + if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); + if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); + if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file); + + $app->log('web server did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); + } + + $app->services->restartService('httpd', 'restart'); + } + } else { + //* We do not check the web server config after changes (is faster) + if($is_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + } + + //* The vhost is written and apache has been restarted, so we + // can reset the ssl changed var to false and cleanup some files + $this->ssl_certificate_changed = false; + + if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); + if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); + if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); + if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); + if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); + + // Remove the backup copy of the config file. + if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); + + //* Unset action to clean it for next processed vhost. + $this->action = ''; + } + + public function eventDelete($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + // load the server configuration options + $app->uses('getconf'); + $app->uses('system'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); + $app->system->web_folder_protection($tmp['document_root'], false); + } + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $is_chrooted = true; + } else { + $is_chrooted = false; + } + + //* Remove the mounts + $log_folder = 'log'; + $web_folder = ''; + if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + if($tmp['domain'] != ''){ + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + } else { + // we are deleting the parent domain, so we can delete everything in the log directory + $subdomain_hosts = array(); + $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ + $subdomain_hosts[] = $file; + } + } + } + } + if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ + $log_folders = array(); + foreach($subdomain_hosts as $subdomain_host){ + $log_folders[] = $log_folder.'/'.$subdomain_host; + } + } else { + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $log_folder .= '/' . $subdomain_host; + } + $web_folder = $data['old']['web_folder']; + unset($tmp); + unset($subdomain_hosts); + } + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder) . ' 2>/dev/null'); + } + } else { + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder) . ' 2>/dev/null'); + } + + //try umount mysql + if(file_exists($data['old']['document_root'].'/var/run/mysqld')) { + $fstab_line = '/var/run/mysqld ' . $data['old']['document_root'] . '/var/run/mysqld none bind,nobootwait 0 0'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $command = 'umount ' . escapeshellarg($data['old']['document_root']) . '/var/run/mysqld/'; + exec($command); + } + + // remove letsencrypt if it exists (renew will always fail otherwise) + + $old_domain = $data['old']['domain']; + if(substr($old_domain, 0, 2) === '*.') { + // wildcard domain not yet supported by letsencrypt! + $old_domain = substr($old_domain, 2); + } + @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); + } + + //* remove mountpoint from fstab + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + unset($log_folders); + + if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { + //* This is a alias domain or subdomain, so we have to update the website instead + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + // just run the update function + $this->update($event_name, $data); + + } else { + $conf_prefix = ''; + if($server_type === 'nginx') { + $conf_prefix = 'nginx_'; + } + + //* This is a website + // Deleting the vhost file, symlink and the data directory + $vhost_file = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + + $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + $app->system->unlink($vhost_file); + $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $docroot = escapeshellcmd($data['old']['document_root']); + if($docroot != '' && !stristr($docroot, '..')) { + if($data['old']['type'] == 'vhost') { + // this is a vhost - we delete everything in here. + exec('rm -rf '.$docroot); + } elseif(!stristr($data['old']['web_folder'], '..')) { + // this is a vhost subdomain + // IMPORTANT: do some folder checks before we delete this! + $do_delete = true; + $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times + if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); + if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); + + $path_elements = explode('/', $delete_folder); + + if($path_elements[0] == 'web' || $path_elements[0] === '') { + // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! + // we use strict check as otherwise directories named '0' may not be deleted + $do_delete = false; + } else { + // read all vhost subdomains and alias with same parent domain + $used_paths = array(); + $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); + foreach($tmp as $tmprec) { + // we normalize the folder entries because we need to compare them + $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times + if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); + if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); + + // add this path and it's parent paths to used_paths array + while(strpos($tmp_folder, '/') !== false) { + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); + } + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + } + unset($tmp); + + // loop and check if the path is still used and stop at first used one + // set do_delete to false so nothing gets deleted if the web_folder itself is still used + $do_delete = false; + while(count($path_elements) > 0) { + $tmp_folder = implode('/', $path_elements); + if(in_array($tmp_folder, $used_paths) == true) break; + + // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true + $delete_folder = $tmp_folder; + $do_delete = true; + array_pop($path_elements); + } + unset($tmp_folder); + unset($used_paths); + } + + if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); + + unset($delete_folder); + unset($path_elements); + } + } + + //remove the php fastgi starter script if available + if ($data['old']['php'] == 'fast-cgi') { + $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($fastcgi_starter_path)) { + exec('rm -rf '.$fastcgi_starter_path); + } + } else { + $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; + if (file_exists($fcgi_starter_script)) { + exec('rm -f '.$fcgi_starter_script); + } + } + } + + // remove PHP-FPM pool + if ($data['old']['php'] == 'php-fpm') { + $this->php_fpm_pool_delete($data, $web_config, $server_type); + } + + //remove the php cgi starter script if available + if ($data['old']['php'] == 'cgi') { + // TODO: fetch the date from the server-settings + $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; + + $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($cgi_starter_path)) { + exec('rm -rf '.$cgi_starter_path); + } + } else { + $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; + if (file_exists($cgi_starter_script)) { + exec('rm -f '.$cgi_starter_script); + } + } + } + + $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); + + // Delete the symlinks for the sites + $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // delete the symlink + if(is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + // end removing symlinks + } + + // Delete the log file directory + $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); + if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); + $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost') { + //delete the web user + $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; + $command .= ' '.escapeshellcmd($data['old']['system_user']); + exec($command); + if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + } + + //* Remove the awstats configuration file + if($data['old']['stats_type'] == 'awstats') { + $this->awstats_delete($data, $web_config); + } + + if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); $app->system->web_folder_protection($tmp['document_root'], true); + } + + if($is_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + + //* Delete the web-backups + if($data['old']['type'] == 'vhost') { + $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); + $backup_dir = $server_config['backup_dir']; + $mount_backup = true; + if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { + //* mount backup directory, if necessary + if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; + + if($mount_backup){ + $web_backup_dir = $backup_dir.'/web'.$data['old']['domain_id']; + //** do not use rm -rf $web_backup_dir because database(s) may exits + exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data['old']['domain_id'].'_').'*'); + //* cleanup database + $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; + $app->db->query($sql, $conf['server_id'], $data['old']['domain_id'], "web".$data['old']['domain_id']."_%"); + if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data['old']['domain_id'], "web".$data['old']['domain_id']."_%"); + + $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); + } + } + } + } + if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); + } + + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered + function eventServerIp($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + if($server_type === 'nginx') { + // not yet implemented + return; + } + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('apache_ispconfig.conf.master'); + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('logging', $web_config['logging']); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']); + + $records_out= array(); + if(is_array($records)) { + foreach($records as $rec) { + if($rec['ip_type'] == 'IPv6') { + $ip_address = '['.$rec['ip_address'].']'; + } else { + $ip_address = $rec['ip_address']; + } + $ports = explode(',', $rec['virtualhost_port']); + if(is_array($ports)) { + foreach($ports as $port) { + $port = intval($port); + if($port > 0 && $port < 65536 && $ip_address != '') { + $records_out[] = array('ip_address' => $ip_address, 'port' => $port); + } + } + } + } + } + + + if(count($records_out) > 0) { + $tpl->setLoop('ip_adresses', $records_out); + } + + $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf'); + $app->system->file_put_contents($vhost_file, $tpl->grab()); + $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG); + unset($tpl); + + } + + //* Create or update the .htaccess folder protection + public function eventWebFolderUser($event_name, $data, $server_type = 'apache') { + global $app; + + $app->uses('system'); + + if($event_name == 'web_folder_user_delete') { + $folder_id = $data['old']['web_folder_id']; + } else { + $folder_id = $data['new']['web_folder_id']; + } + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { + $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($folder_path)) { + $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); + } + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + $app->system->touch($folder_path.'.htpasswd'); + $app->system->chmod($folder_path.'.htpasswd', 0751); + $app->system->chown($folder_path.'.htpasswd', $website['system_user']); + $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); + $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } + + //* Add or remove the user from .htpasswd file + if($event_name == 'web_folder_user_delete') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } else { + if($data['new']['active'] == 'y') { + $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); + $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); + } + } + + if($server_type === 'apache') { + //* Create the .htaccess file + //if(!is_file($folder_path.'.htaccess')) { + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; + $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + + if(file_exists($folder_path.'.htaccess')) { + $old_content = $app->system->file_get_contents($folder_path.'.htaccess'); + + $matches = array(); + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { + $ht_file = str_replace($matches[0], $ht_file, $old_content); + } else { + $ht_file .= $old_content; + } + } + unset($old_content); + + $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); + $app->system->chmod($folder_path.'.htaccess', 0751); + $app->system->chown($folder_path.'.htaccess', $website['system_user']); + $app->system->chgrp($folder_path.'.htaccess', $website['system_group']); + $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + } + + //* Remove .htaccess and .htpasswd file, when folder protection is removed + public function eventWebFolderDelete($event_name, $data, $server_type = 'apache') { + global $app; + + $folder = $data['old']; + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + + //* Remove .htpasswd file + if(is_file($folder_path.'.htpasswd')) { + $app->system->unlink($folder_path.'.htpasswd'); + $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + if($server_type === 'apache') { + //* Remove .htaccess file + if(is_file($folder_path.'.htaccess')) { + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; + + $ht_file = $app->system->file_get_contents($folder_path.'.htaccess'); + + $matches = array(); + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + + if(trim($ht_file) == '') { + $app->system->unlink($folder_path.'.htaccess'); + $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } + } else { + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + } + + //* Update folder protection, when path has been changed + public function eventWebFolderUpdate($event_name, $data, $server_type = 'apache') { + global $app; + + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); + + if(!is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); + if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); + $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); + if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; + + if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); + if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); + $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); + if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { + $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { + $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + + //* Check if the resulting path is inside the docroot + if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); + + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; + + if($data['old']['path'] != $data['new']['path']) { + + + //* move .htpasswd file + if(is_file($old_folder_path.'.htpasswd')) { + $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); + $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + if($server_type === 'apache') { + //* delete old .htaccess file + if(is_file($old_folder_path.'.htaccess')) { + $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess'); + + $matches = array(); + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + + if(trim($ht_file) == '') { + $app->system->unlink($old_folder_path.'.htaccess'); + $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } + } + + } + + if($server_type === 'apache') { + //* Create the .htaccess file + if($data['new']['active'] == 'y') { + $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + + if(file_exists($new_folder_path.'.htaccess')) { + $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess'); + + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { + $ht_file = str_replace($matches[0], $ht_file, $old_content); + } else { + $ht_file .= $old_content; + } + } + + $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); + $app->system->chmod($new_folder_path.'.htaccess', 0751); + $app->system->chown($new_folder_path.'.htaccess', $website['system_user']); + $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']); + $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($new_folder_path.'.htpasswd')) { + $app->system->touch($new_folder_path.'.htpasswd'); + $app->system->chmod($new_folder_path.'.htpasswd', 0751); + $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']); + $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']); + $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + } + + //* Remove .htaccess file + if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) { + $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess'); + + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + + if(trim($ht_file) == '') { + $app->system->unlink($new_folder_path.'.htaccess'); + $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } + } else { + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + } + + + //* Update the PHP-FPM pool configuration file + private function php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type = 'apache') { + global $app, $conf; + $pool_dir = trim($pool_dir); + $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); + + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + if($data['new']['php'] != 'php-fpm'){ + if(@is_file($pool_dir.$pool_name.'.conf')){ + $app->system->unlink($pool_dir.$pool_name.'.conf'); + //$reload = true; + } + if($data['old']['php'] == 'php-fpm'){ + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + return; + } + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate('php_fpm_pool.conf.master'); + + if($data['new']['php_fpm_chroot'] == 'y'){ + $php_fpm_chroot = 1; + } else { + $php_fpm_chroot = 0; + } + if($server_type === 'apache') { + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + } + + $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); + + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_listen_mode', '0660'); + + $tpl->setVar('fpm_pool', $pool_name); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + $tpl->setVar('fpm_user', $data['new']['system_user']); + + //Red Hat workaround for group ownership of socket files + foreach($rh_releasefiles as $rh_file) { + if(file_exists($rh_file) && (filesize($rh_file) > 0)) { + $tmp = file_get_contents($rh_file); + if(preg_match('/[67]+\.[0-9]+/m', $tmp)) { + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('fpm_listen_group', $data['new']['system_group']); + } + unset($tmp); + } elseif(!file_exists($rh_file)) { + //OS seems to be not Red Hat'ish + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('fpm_listen_group', $web_config['group']); + } + break; + } + + $tpl->setVar('fpm_listen_user', $data['new']['system_user']); + $tpl->setVar('fpm_domain', $data['new']['domain']); + $tpl->setVar('pm', $data['new']['pm']); + $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); + $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); + $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); + $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); + $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); + $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); + $tpl->setVar('document_root', $data['new']['document_root']); + $tpl->setVar('security_level', $web_config['security_level']); + $tpl->setVar('domain', $data['new']['domain']); + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); + if($php_fpm_chroot){ + $document_root = $data['new']['document_root']; + $domain = $data['new']['domain']; + $php_open_basedir = str_replace(":/srv/www/$domain/web",'',$php_open_basedir); + $php_open_basedir = str_replace(":/var/www/$domain/web",'',$php_open_basedir); + $php_open_basedir = str_replace("$document_root",'',$php_open_basedir); + } + $tpl->setVar('php_open_basedir', $php_open_basedir); + if($php_open_basedir != ''){ + $tpl->setVar('enable_php_open_basedir', ''); + } else { + $tpl->setVar('enable_php_open_basedir', ';'); + } + + // Custom php.ini settings + $final_php_ini_settings = array(); + $custom_php_ini_settings = trim($data['new']['custom_php_ini']); + + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = ? AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']), $server_type); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $custom_php_ini_settings .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $custom_session_save_path = false; + if($custom_php_ini_settings != ''){ + // Make sure we only have Unix linebreaks + $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); + $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); + $ini_settings = explode("\n", $custom_php_ini_settings); + if(is_array($ini_settings) && !empty($ini_settings)){ + foreach($ini_settings as $ini_setting){ + $ini_setting = trim($ini_setting); + if(substr($ini_setting, 0, 1) == ';') continue; + if(substr($ini_setting, 0, 1) == '#') continue; + if(substr($ini_setting, 0, 2) == '//') continue; + list($key, $value) = explode('=', $ini_setting, 2); + $value = trim($value); + if($value != ''){ + $key = trim($key); + if($key == 'session.save_path') $custom_session_save_path = true; + switch (strtolower($value)) { + case '0': + // PHP-FPM might complain about invalid boolean value if you use 0 + $value = 'off'; + case '1': + case 'on': + case 'off': + case 'true': + case 'false': + case 'yes': + case 'no': + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); + break; + default: + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); + } + } + } + } + } + + $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); + + $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); + + $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); + $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + unset($tpl); + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $conf["server_id"]); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + //* Delete the PHP-FPM pool configuration file + private function php_fpm_pool_delete ($data, $web_config, $server_type = 'apache') { + global $app, $conf; + + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + // $custom_php_fpm_name + list(, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['old']['domain_id']; + + if ( @is_file($pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + } + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $data['old']['server_id']); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + public function eventClientDelete($event_name, $data, $server_type = 'apache') { + global $app, $conf; + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + $client_id = intval($data['old']['client_id']); + if($client_id > 0) { + + $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; + if(is_dir($client_dir) && !stristr($client_dir, '..')) { + // remove symlinks from $client_dir + $files = array_diff(scandir($client_dir), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_link($client_dir.'/'.$file)){ + unlink($client_dir.'/'.$file); + $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); + } + } + } + + @rmdir($client_dir); + $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); + } + + if($app->system->is_group('client'.$client_id)){ + $app->system->_exec('groupdel client'.$client_id); + $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); + } + } + + } + + private function get_seo_redirects($web, $prefix = '', $force_subdomain = false, $server_type = 'apache'){ + $seo_redirects = array(); + + if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; + + if($server_type === 'apache') { + if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){ + $domain = str_replace('.', '\.', $web['domain']); + if($web['seo_redirect'] == 'non_www_to_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = ''; + } + if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain.'|.*\.'.$domain.'(?db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); + if(is_array($webs) && !empty($webs)){ + foreach($webs as $web){ + // web domain doesn't match hostname + if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue; + // own vhost and therefore server {} container of its own + //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; + + if($web['subdomain'] == '*'){ + $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'none'){ + if($web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'www'){ + if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if(preg_match($pattern, $hostname)){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + } + } + + return false; + } + + private function nginx_replace($matches){ + $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; + if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; + if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; + $location .= "\n"; + $location .= $matches[5]."\n"; + $location .= $matches[6]; + return $location; + } + + private function nginx_merge_locations($vhost_conf) { + global $app, $conf; + + $subroot = array(); + if(preg_match('/##subroot (.+?)\s*##/', $vhost_conf, $subroot)) { + if(!preg_match('/^(?:[a-z0-9\/_-]|\.(?!\.))+$/iD', $subroot[1])) { + $app->log('Token ##subroot is unsecure (server ID: '.$conf['server_id'].').', LOGLEVEL_WARN); + } else { + $insert_pos = strpos($vhost_conf, ';', strpos($vhost_conf, 'root ')); + $vhost_conf = substr_replace($vhost_conf, ltrim($subroot[1], '/'), $insert_pos, 0); + } + } + + $lines = explode("\n", $vhost_conf); + + // if whole location block is in one line, split it up into multiple lines + if(is_array($lines) && !empty($lines)){ + $linecount = sizeof($lines); + for($h=0;$h<$linecount;$h++){ + // remove comments + if(substr(trim($lines[$h]), 0, 1) == '#'){ + unset($lines[$h]); + continue; + } + + $lines[$h] = rtrim($lines[$h]); + /* + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + $lines[$h] = str_replace(";", ";\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + */ + $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; + $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]); + } + } + $vhost_conf = implode("\n", $lines); + unset($lines); + unset($linecount); + + $lines = explode("\n", $vhost_conf); + + if(is_array($lines) && !empty($lines)){ + $locations = array(); + $locations_to_delete = array(); + $islocation = false; + $linecount = sizeof($lines); + $server_count = 0; + + for($i=0;$i<$linecount;$i++){ + $l = trim($lines[$i]); + if(substr($l, 0, 8) == 'server {') $server_count += 1; + if($server_count > 1) break; + if(substr($l, 0, 8) == 'location' && !$islocation){ + + $islocation = true; + $level = 0; + + // Remove unnecessary whitespace + $l = preg_replace('/\s\s+/', ' ', $l); + + $loc_parts = explode(' ', $l); + // see http://wiki.nginx.org/HttpCoreModule#location + if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ + $location = $loc_parts[1].' '.$loc_parts[2]; + } else { + $location = $loc_parts[1]; + } + unset($loc_parts); + + if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; + if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; + if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; + + if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; + if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; + if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; + if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; + if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; + + unset($lines[$i]); + + } else { + + if($islocation){ + $openingbracketpos = strrpos($l, '{'); + if($openingbracketpos !== false){ + $level += 1; + } + $closingbracketpos = strrpos($l, '}'); + if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){ + $level -= 1; + $locations[$location]['location'] .= $lines[$i]."\n"; + } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){ + $islocation = false; + } else { + $locations[$location]['location'] .= $lines[$i]."\n"; + } + unset($lines[$i]); + } + + } + } + + if(is_array($locations) && !empty($locations)){ + if(is_array($locations_to_delete) && !empty($locations_to_delete)){ + foreach($locations_to_delete as $location_to_delete){ + if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); + } + } + + foreach($locations as $val){ + $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; + $lines[$val['start_line']] = $new_location; + } + } + ksort($lines); + $vhost_conf = implode("\n", $lines); + } + + return trim($vhost_conf); + } + + + /** + * This function patches the vhost-file and adds all webdav - user. + * This function is written, because the creation of the vhost - file is sophisticated and + * i don't want to make it more "heavy" by also adding this code too... + * @author Oliver Vogel + * @param string $fileName The Name of the .vhost-File (path included) + * @param string $webdavRoot The root of the webdav-folder + */ + private function _patchVhostWebdav($fileName, $webdavRoot) { + global $app; + $in = fopen($fileName, 'r'); + $output = ''; + $inWebdavSection = false; + //* read line by line and search for the username and authname + while ($line = fgets($in)) { + //* is the "replace-comment" found... + if (trim($line) == '# WEBDAV BEGIN') { + //* The begin of the webdav - section is found, so ignore all lines til the end is found + $inWebdavSection = true; + $output .= "# WEBDAV BEGIN\n"; + //* add all the webdav-dirs to the webdav-section + $files = @scandir($webdavRoot); + if(is_array($files)) { + foreach($files as $file) { + if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) { + //* found a htdigest - file, so add it to webdav + $fn = substr($file, 0, strlen($file) - strlen('.htdigest')); + $output .= "\n"; + $output .= "Alias /webdav/$fn $webdavRoot/$fn\n"; + $output .= "\n"; + $output .= "DAV On\n"; + $output .= "BrowserMatch MSIE AuthDigestEnableQueryStringHack=On\n"; + $output .= "AuthType Digest\n"; + if($fn != '' && $fn != '/') { + $output .= "AuthName \"" . $fn . "\"\n"; + } else { + $output .= "AuthName \"Restricted Area\"\n"; + } + $output .= "AuthUserFile $webdavRoot/$file\n"; + $output .= "Require valid-user\n"; + $output .= "Options +Indexes\n"; + if($app->system->getapacheversion()<=2.2) + $output .= "Order allow,deny\nAllow from all\n"; + $output .= "\n"; + } + } + } + } + //* is the "replace-comment-end" found... + if (trim($line) == '# WEBDAV END') { + //* The end of the webdav - section is found, so stop ignoring + $inWebdavSection = false; + } + //* Write the line to the output, if it is not in the section + if (!$inWebdavSection) { + $output .= $line; + } + } + fclose($in); + //* Now lets write the new file + $app->system->file_put_contents($fileName, $output); + } + + public function getWebFolder(&$data, $type, $use_old = false) { + global $app; + + $folder = $type; + + if($type === 'web' && $data['new']['type'] == 'vhost'){ + if($use_old === true) { + if($data['old']['web_folder'] != ''){ + if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1); + if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1); + } + $folder .= '/'.$data['old']['web_folder']; + } else { + if($data['new']['web_folder'] != ''){ + if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); + if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); + } + $folder .= '/'.$data['new']['web_folder']; + } + } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + if($use_old === true) { + if(isset($data['old']['parent_domain_id'])) { + // old one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + if($type === 'web') { + $folder = $data['old']['web_folder']; + } else { + $folder .= '/' . $subdomain_host; + } + unset($tmp); + } + } else { + // new one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; + if($type === 'web') { + $folder = $data['new']['web_folder']; + } else { + $folder .= '/' . $subdomain_host; + } + unset($tmp); + } + } + } +} diff --git a/server/lib/classes/plugin_webserver_nginx.inc.php b/server/lib/classes/plugin_webserver_nginx.inc.php new file mode 100644 index 000000000..3002f4b0f --- /dev/null +++ b/server/lib/classes/plugin_webserver_nginx.inc.php @@ -0,0 +1,840 @@ +getconf->get_server_config($conf['server_id'], 'web'); + + // PHP-FPM + // Support for multiple PHP versions + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_chroot'] == 'y'){ + $php_fpm_chroot = 1; + $php_fpm_nochroot = 0; + } else { + $php_fpm_chroot = 0; + $php_fpm_nochroot = 1; + } + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); + $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); + $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; + + // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. + if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; + + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processRewriteRules(&$tpl, &$data, &$vhost_data) { + global $app, $conf; + + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + // Custom rewrite rules + $final_rewrite_rules = array(); + + if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { + $custom_rewrite_rules = trim($data['new']['rewrite_rules']); + $custom_rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + // ignore comments + if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // empty lines + if(trim($custom_rewrite_rule_line) == ''){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // closing curly bracket + if(trim($custom_rewrite_rule_line) == '}'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level -= 1; + continue; + } + $custom_rewrites_are_valid = false; + break; + } + } + if(!$custom_rewrites_are_valid || $if_level != 0){ + $final_rewrite_rules = array(); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + + // Rewrite rules + $own_rewrite_rules = array(); + $rewrite_rules = array(); + $local_rewrite_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ + if($data['new']['redirect_type'] != 'proxy'){ + $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); + } else { + $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); + } + } + + // Custom proxy directives + if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $data['new']['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + switch($data['new']['subdomain']) { + case 'www': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + case '*': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + + //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + default: + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + $exclude_own_hostname = ''; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + } + } + + $server_alias = array(); + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); + $alias_seo_redirects = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain']; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain']; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + switch($alias['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; + break; + case '*': + $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; + break; + default: + $server_alias[] .= $alias['domain']; + break; + } + $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); + + if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + } + + // Custom proxy directives + if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $alias['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + + // Local Rewriting (inside vhost server {} container) + if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + switch($alias['subdomain']) { + case 'www': + // example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + + // www.example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + case '*': + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', + 'local_redirect_operator' => '~*', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + default: + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + } + } + + // External Rewriting (extra server {} containers) + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ + if($alias['redirect_type'] != 'proxy'){ + $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); + } else { + $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); + } + } + + switch($alias['subdomain']) { + case 'www': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www', 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + case '*': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + default: + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); + else $domain_rule = $alias['domain']; + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + if(substr($alias['domain'], 0, 2) === '*.'){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + } else { + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); + } + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + } + } + } + } + + //* If we have some alias records + if(count($server_alias) > 0) { + $server_alias_str = ''; + foreach($server_alias as $tmp_alias) { + $server_alias_str .= $tmp_alias; + } + unset($tmp_alias); + + $tpl->setVar('alias', trim($server_alias_str)); + } else { + $tpl->setVar('alias', ''); + } + + if(count($rewrite_rules) > 0) { + $tpl->setLoop('redirects', $rewrite_rules); + } + if(count($own_rewrite_rules) > 0) { + $tpl->setLoop('own_redirects', $own_rewrite_rules); + } + if(count($local_rewrite_rules) > 0) { + $tpl->setLoop('local_redirects', $local_rewrite_rules); + } + if(count($alias_seo_redirects) > 0) { + $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); + } + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + * @param array $fpm_data + */ + public function processCustomDirectives(&$tpl, &$data, &$vhost_data, $fpm_data) { + global $app, $conf; + + // Custom nginx directives + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $nginx_directives = $snippet['snippet']; + } else { + $nginx_directives = $data['new']['nginx_directives']; + } + } else { + $nginx_directives = $data['new']['nginx_directives']; + } + + $final_nginx_directives = array(); + if($data['new']['enable_pagespeed'] == 'y'){ + // if PageSpeed is already enabled, don't add configuration again + if(stripos($nginx_directives, 'pagespeed') !== false){ + $vhost_data['enable_pagespeed'] = false; + } else { + $vhost_data['enable_pagespeed'] = true; + } + } else { + $vhost_data['enable_pagespeed'] = false; + } + + $web_folder = $app->plugin_webserver_base->getWebFolder($data, 'web'); + $username = escapeshellcmd($data['new']['system_user']); + $groupname = escapeshellcmd($data['new']['system_group']); + + // folder_directive_snippets + if(trim($data['new']['folder_directive_snippets']) != ''){ + $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); + $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); + + if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ + foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ + list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); + + $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); + $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); + + if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ + if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; + if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); + + $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); + if(isset($master_snippet['snippet'])){ + $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); + $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); + $nginx_directives .= "\n\n".$master_snippet['snippet']; + + // create folder it it does not exist + if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ + $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); + $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); + } + } + } + } + } + } + + // use vLib for template logic + if(trim($nginx_directives) != '') { + $nginx_directives_new = ''; + $ngx_conf_tpl = new tpl(); + $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); + file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); + $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); + $ngx_conf_tpl->setVar('use_tcp', $fpm_data['use_tcp']); + $ngx_conf_tpl->setVar('use_socket', $fpm_data['use_socket']); + $ngx_conf_tpl->setVar('fpm_socket', $fpm_data['fpm_socket']); + $ngx_conf_tpl->setVar($vhost_data); + $nginx_directives_new = $ngx_conf_tpl->grab(); + if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); + if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; + unset($nginx_directives_new); + } + + // Make sure we only have Unix linebreaks + $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); + $nginx_directives = str_replace("\r", "\n", $nginx_directives); + $nginx_directive_lines = explode("\n", $nginx_directives); + if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], + '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_data['fpm_socket'] : '127.0.0.1:'.$fpm_data['fpm_port']).';' + ); + foreach($nginx_directive_lines as $nginx_directive_line){ + $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); + } + } + $tpl->setLoop('nginx_directives', $final_nginx_directives); + + return; + } + + + public function getStatsFolder($data) { + $stats_web_folder = 'web'; + if($data['new']['type'] == 'vhost'){ + if($data['new']['web_folder'] != ''){ + if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); + if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); + } + $stats_web_folder .= '/'.$data['new']['web_folder']; + } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + $stats_web_folder = $data['new']['web_folder']; + } + return $stats_web_folder; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processStatsAuth(&$tpl, &$data, &$vhost_data) { + + $stats_web_folder = $this->getStatsFolder($data); + + //* Create basic http auth for website statistics + $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); + + // Create basic http auth for other directories + $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); + if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); + + return; + } + + private function _create_web_folder_auth_configuration($website){ + global $app; + + //* Create the domain.auth file which is included in the vhost configuration file + + $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); + $basic_auth_locations = array(); + if(is_array($website_auth_locations) && !empty($website_auth_locations)){ + foreach($website_auth_locations as $website_auth_location){ + if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); + if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); + if($website_auth_location['path'] != ''){ + $website_auth_location['path'] .= '/'; + } + $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], + 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); + } + } + return $basic_auth_locations; + } + + public function testWebserverConfig() { + global $app; + + // if no output is given, check again + $tmp_output = null; + $tmp_retval = 0; + exec('nginx -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } +} diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 5be47d050..73f6f9939 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -30,2548 +30,123 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class apache2_plugin { - var $plugin_name = 'apache2_plugin'; - var $class_name = 'apache2_plugin'; + var $plugin_name; + var $class_name; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; - //* This function is called during ispconfig installation to determine - // if a symlink shall be created for this plugin. - function onInstall() { - global $conf; - - if($conf['services']['web'] == true) { - return true; - } else { - return false; - } - - } - - - /* - This function is called when the plugin is loaded - */ - - function onLoad() { - global $app; - - /* - Register for the events - */ - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); - - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); - - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); - - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); - - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); - - $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); - - $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); - } - - private function get_master_php_ini_content($web_data) { - global $app, $conf; - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - $php_ini_content = ''; - $master_php_ini_path = ''; - - if($web_data['php'] == 'mod') { - $master_php_ini_path = $web_config['php_ini_path_apache']; - } else { - // check for custom php - if($web_data['fastcgi_php_version'] != '') { - $tmp = explode(':', $web_data['fastcgi_php_version']); - if(isset($tmp[2])) { - $tmppath = $tmp[2]; - if(substr($tmppath, -7) != 'php.ini') { - if(substr($tmppath, -1) != '/') $tmppath .= '/'; - $tmppath .= 'php.ini'; - } - if(file_exists($tmppath)) { - $master_php_ini_path = $tmppath; - } - unset($tmppath); - } - unset($tmp); - } - - if(!$master_php_ini_path) { - if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } else { - $master_php_ini_path = $web_config['php_ini_path_cgi']; - } - } - } - - // Resolve inconsistant path settings - if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) { - $master_php_ini_path .= '/php.ini'; - } - - // Load the custom php.ini content - if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) { - $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; - } - - return $php_ini_content; - } - - // Handle php.ini changes - function php_ini_changed($event_name, $data) { - global $app, $conf; - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - /* $data contains an array with these keys: - * file -> full path of changed php_ini - * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') - * php_version -> php ini path that changed (additional php versions) - */ - - $param = ''; - $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''"; - if($data['mode'] == 'mod') { - $qrystr .= " AND php = 'mod'"; - } elseif($data['mode'] == 'fast-cgi') { - $qrystr .= " AND php = 'fast-cgi'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version']; - } - } elseif($data['mode'] == 'php-fpm') { - $qrystr .= " AND php = 'php-fpm'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version'] . ':%'; - } - } else { - $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; - } - - - //** Get all the webs - $web_domains = $app->db->queryAllRecords($qrystr, $param); - foreach($web_domains as $web_data) { - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user']; - $web_folder = 'web'; - if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') { - $web_folder = $web_data['web_folder']; - $custom_php_ini_dir .= '_' . $web_folder; - } - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($web_data); - - if(intval($web_data['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini'])); - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG); - } - - if(count($web_domains) > 0) { - //* We do not check the apache config here - we only changed the php.ini - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); - } else { - $apache_chrooted = false; - } - - $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG); - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } else { - $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG); - } - } - - // Handle the creation of SSL certificates - function ssl($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Create a SSL Certificate, but only if this is not a mirror server. - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file, $key_file.'.bak'); - $app->system->chmod($key_file.'.bak', 0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2, $key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak', 0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_md = sha256 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " - " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." - " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." - " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - ";//challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file2 = escapeshellcmd($key_file2); - $openssl_cmd_key_file2 = $key_file2; - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $key_file = escapeshellcmd($key_file); - $openssl_cmd_key_file = $key_file; - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - $openssl_cmd_csr_file = $csr_file; - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - $openssl_cmd_crt_file = $crt_file; - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); - exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); - }; - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - - } - - $app->system->chmod($key_file2, 0400); - $app->system->chmod($key_file, 0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->system->file_get_contents($csr_file); - $ssl_cert = $app->system->file_get_contents($crt_file); - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - - //* Check that the SSL key is not password protected - if($data["new"]["ssl_action"] == 'save') { - if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* and check that SSL cert does not contain subdomain of domain acme.invalid - if($data["new"]["ssl_action"] == 'save') { - $tmp = array(); - $crt_data = ''; - exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); - $crt_data = implode("\n",$tmp); - if(stristr($crt_data,'.acme.invalid')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file, $key_file.'~'); - $app->system->chmod($key_file.'~', 0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2, $key_file2.'~'); - $app->system->chmod($key_file2.'~', 0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); - if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); - if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) { - // In apache 2.4.8 and newer, the ssl crt file contains the bundle, so we need no separate bundle file - $tmp_data = ''; - if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n"; - if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"]; - if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data); - } else { - // Write separate crt and bundle file - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); - if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]); - } - - //* Write the key file, if field is empty then import the key into the db - if(trim($data["new"]["ssl_key"]) != '') { - $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); - $app->system->chmod($key_file, 0400); - } else { - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - } - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); - $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - $app->system->unlink($bundle_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - } - - - function insert($event_name, $data) { - global $app, $conf; - - $this->action = 'insert'; - // just run the update function - $this->update($event_name, $data); - - - } - - - function update($event_name, $data) { - global $app, $conf; - - if($this->action != 'insert') $this->action = 'update'; - - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name, $data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); - } else { - $apache_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); - return 0; - } - if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false - || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { - $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty', LOGLEVEL_WARN); - return 0; - } - - $web_folder = 'web'; - $log_folder = 'log'; - $old_web_folder = 'web'; - $old_log_folder = 'log'; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - // new one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - $web_folder = $data['new']['web_folder']; - $log_folder .= '/' . $subdomain_host; - unset($tmp); - - if(isset($data['old']['parent_domain_id'])) { - // old one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $old_web_folder = $data['old']['web_folder']; - $old_log_folder .= '/' . $subdomain_host; - unset($tmp); - } - } - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - //* Remove protection of old folders - $app->system->web_folder_protection($data['old']['document_root'], false); - - if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { - //* Move the site data - $tmp_docroot = explode('/', $data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/', $tmp_docroot); - - $tmp_docroot = explode('/', $data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/', $tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); - } - - //* Unmount the old log directory bfore we move the log dir - //exec('fuser -km '.escapeshellcmd($old_dir.'/log')); - exec('umount -l '.escapeshellcmd($data['old']['document_root'].'/log')); - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'], false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - /* - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - */ - - $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - - if($web_config['network_filesystem'] == 'y') { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } - - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'], false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - - if(!is_dir($data['new']['document_root'].'/.ssh')) { - $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); - $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); - $app->system->chown($data['new']['document_root'].'/.ssh', $username); - $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); - } - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - } - - - // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - - //* Unmount log directory - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; - $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); - } - - $app->system->web_folder_protection($data['new']['document_root'], true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { - // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - //* Copy the web skeleton files only when there is no index.ph or index.html file yet - if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - //} - } else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } else { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - $mb_soft = $data['new']['hd_quota']; - $mb_hard = $mb_soft + 1; - } else { - $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; - } - - // get the primitive folder for document_root and the filesystem, will need it later. - $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); - $file_system = $df_output[0]; - $primitive_root = $df_output[1]; - - if($file_system == 'xfs') { - exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); - - // xfs only supports timers globally, not per user. - exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); - - unset($project_uid, $username_position, $xfs_projects); - unset($primitive_root, $df_output, $mb_hard, $mb_soft); - } else { - if($app->system->is_installed('setquota')) { - exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - } - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'], false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0711); - $app->system->chmod($data['new']['document_root'].'/webdav', 0710); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - - // make tmp directory writable for Apache and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $app->system->_exec($command); - } - - //* if we have a chrooted Apache environment - if($apache_chrooted) { - $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the apache user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0755); - $app->system->chmod($data['new']['document_root'].'/webdav', 0755); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); - - // make temp directory writable for Apache and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - } - } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && - (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { - - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'], true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - } - - //* Write the custom php.ini file, if custom_php_ini fieled is not empty - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - if(trim($data['new']['fastcgi_php_version']) != ''){ - list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); - if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); - } - - //* Create custom php.ini - if(trim($data['new']['custom_php_ini']) != '') { - $has_custom_php_ini = true; - if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($data['new']); - $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini'])); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $php_ini_content .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - } else { - $has_custom_php_ini = false; - if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); - } - - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('vhost.conf.master'); - - $vhost_data = $data['new']; - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - $vhost_data['security_level'] = $web_config['security_level']; - $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override']; - $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; - $vhost_data['has_custom_php_ini'] = $has_custom_php_ini; - $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir); - $vhost_data['logging'] = $web_config['logging']; - - // Custom Apache directives - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $vhost_data['apache_directives'] = $snippet['snippet']; - } - } - // Make sure we only have Unix linebreaks - $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); - $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] - ); - $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); - - $app->uses('letsencrypt'); - // Check if a SSL cert exists - $tmp = $app->letsencrypt->get_website_certificate_paths($data); - $domain = $tmp['domain']; - $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; - $crt_file = $tmp['crt']; - $bundle_file = $tmp['bundle']; - unset($tmp); - - $data['new']['ssl_domain'] = $domain; - $vhost_data['ssl_domain'] = $domain; - $vhost_data['ssl_crt_file'] = $crt_file; - $vhost_data['ssl_key_file'] = $key_file; - $vhost_data['ssl_bundle_file'] = $bundle_file; - - //* Generate Let's Encrypt SSL certificat - if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server - ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration - || ($data['old']['domain'] != $data['new']['domain']) // we have domain update - || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain - || $this->update_letsencrypt == true - )) { - - $success = $app->letsencrypt->request_certificates($data); - if($success) { - /* we don't need to store it. - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } else { - $data['new']['ssl_letsencrypt'] = 'n'; - if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); - } - } - - if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; - - // HTTP/2.0 ? - $vhost_data['enable_http2'] = 'n'; - if($vhost_data['enable_spdy'] == 'y'){ - // check if apache supports http_v2 - exec("2>&1 apachectl -M | grep http2_module", $tmp_output, $tmp_retval); - if($tmp_retval == 0){ - $vhost_data['enable_http2'] = 'y'; - } - unset($tmp_output, $tmp_retval); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new']); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - $tpl->setVar($vhost_data); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // Rewrite rules - $rewrite_rules = array(); - $rewrite_wildcard_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8); - } else { - $rewrite_target = $data['new']['redirect_path']; - $rewrite_target_ssl = $data['new']['redirect_path']; - } - /* Disabled path extension - if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { - $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; - } - */ - - switch($data['new']['subdomain']) { - case 'www': - $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_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')); - break; - case '*': - $rewrite_wildcard_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')); - break; - default: - $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')); - } - } - - $server_alias = array(); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain']; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain']; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - switch($alias['subdomain']) { - case 'www': - $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; - break; - case '*': - $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; - break; - default: - $server_alias[] .= $alias['domain']; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - - // Rewriting - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { - if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($alias['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8); - } else { - $rewrite_target = $alias['redirect_path']; - $rewrite_target_ssl = $alias['redirect_path']; - } - /* Disabled the path extension - if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { - $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; - } - */ - - switch($alias['subdomain']) { - case 'www': - $rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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.'.$alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - case '*': - $rewrite_wildcard_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - default: - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2)); - else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']); - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - } - } - } - } - - //* If we have some alias records - if($server_alias) { - //* begin a new ServerAlias line after 32 alias domains to avoid apache bugs - $server_alias_str = 'ServerAlias '.$server_alias[0]; - for($n=1;$nsetVar('alias', $server_alias_str); - unset($server_alias_str); - unset($n); - } else { - $tpl->setVar('alias', ''); - } - - if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules - - if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0 || $data['new']['rewrite_to_https'] == 'y') { - $tpl->setVar('rewrite_enabled', 1); - } else { - $tpl->setVar('rewrite_enabled', 0); - } - - //$tpl->setLoop('redirects',$rewrite_rules); - - /** - * install fast-cgi starter script and add script aliasd config - * first we create the script directory if not already created, then copy over the starter script - * settings are copied over from the server ini config for now - * TODO: Create form for fastcgi configs per site. - */ - - - if ($data['new']['php'] == 'fast-cgi') { - - $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - - if (!is_dir($fastcgi_starter_path)) { - $app->system->mkdirpath($fastcgi_starter_path); - //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); - - - $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG); - } - - //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); - $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); - $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); - if($web_config['security_level'] == 10) { - $app->system->chmod($fastcgi_starter_path, 0755); - } else { - $app->system->chmod($fastcgi_starter_path, 0550); - } - - $fcgi_tpl = new tpl(); - $fcgi_tpl->newTemplate('php-fcgi-starter.master'); - $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion()); - $fcgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // Support for multiple PHP versions (FastCGI) - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_fastcgi_php = false; - if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/'; - } else { - $default_fastcgi_php = true; - } - - if($has_custom_php_ini) { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); - } else { - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); - } else { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir)); - } - } - $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); - $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children'])); - $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests'])); - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin'])); - } else { - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable)); - } - $fcgi_tpl->setVar('security_level', intval($web_config['security_level'])); - $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain'])); - - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); - - $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab()); - unset($fcgi_tpl); - - $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); - - if($web_config['security_level'] == 10) { - $app->system->chmod($fcgi_starter_script, 0755); - } else { - $app->system->chmod($fcgi_starter_script, 0550); - } - $app->system->chown($fcgi_starter_script, $data['new']['system_user']); - $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); - - $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); - $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); - $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); - $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); - - } else { - //remove the php fastgi starter script if available - $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : ''); - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - if($data['old']['type'] == 'vhost') { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path); - } else { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - } - } - } - - - - /** - * PHP-FPM - */ - // Support for multiple PHP versions - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - - /** - * install cgi starter script and add script alias to config. - * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!) - * first we create the script directory if not already created, then copy over the starter script. - * TODO: we have to fetch the data from the server-settings. - */ - if ($data['new']['php'] == 'cgi') { - //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi'); - - $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''); - $cgi_config['cgi_bin'] = '/usr/bin/php-cgi'; - - $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']); - $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path); - - if (!is_dir($cgi_starter_path)) { - $app->system->mkdirpath($cgi_starter_path); - $app->system->chown($cgi_starter_path, $data['new']['system_user']); - $app->system->chgrp($cgi_starter_path, $data['new']['system_group']); - if($web_config['security_level'] == 10) { - $app->system->chmod($cgi_starter_path, 0755); - } else { - $app->system->chmod($cgi_starter_path, 0550); - } - - $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG); - } - - $cgi_tpl = new tpl(); - $cgi_tpl->newTemplate('php-cgi-starter.master'); - $cgi_tpl->setVar('apache_version', $app->system->getapacheversion()); - $cgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // This works because PHP "rewrites" a symlink to the physical path - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); - $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); - - // This will NOT work! - //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']); - $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']); - $cgi_tpl->setVar('security_level', $web_config['security_level']); - - $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini); - if($has_custom_php_ini) { - $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); - } else { - $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); - } - - $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab()); - unset($cgi_tpl); - - $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG); - - - if($web_config['security_level'] == 10) { - $app->system->chmod($cgi_starter_script, 0755); - } else { - $app->system->chmod($cgi_starter_script, 0550); - } - $app->system->chown($cgi_starter_script, $data['new']['system_user']); - $app->system->chgrp($cgi_starter_script, $data['new']['system_group']); - - $tpl->setVar('cgi_starter_path', $cgi_starter_path); - $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - - } - - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~'); - - //* create empty vhost array - $vhosts = array(); - - //* Add vhost for ipv4 IP - - //* use ip-mapping for web-mirror - if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { - $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; - $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); - $data['new']['ip_address'] = $newip['destination_ip']; - unset($newip); - } - - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv4 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects; - if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); - $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Add vhost for IPv6 IP - if($data['new']['ipv6_address'] != '') { - //* rewrite ipv6 on mirrors - /* chang $conf to $web_config */ - if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - } - } - if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::'; - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv6 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects; - if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); - $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG); - } - } - - //* Set the vhost loop - $tpl->setLoop('vhosts', $vhosts); - - //* Write vhost file - $app->system->file_put_contents($vhost_file, $tpl->grab()); - $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - /* - * maybe we have some webdav - user. If so, add them... - */ - $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav'); - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file, $vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); - } - - //* Create .htaccess and .htpasswd file for website statistics - //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) { - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats'); - $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user"; - $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file); - $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755); - unset($ht_file); - //} - - if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file); - $app->system->web_folder_protection($data['new']['document_root'], true); - $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - $this->awstats_update($data, $web_config); - } - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - - if($web_config['check_apache_config'] == 'y') { - //* Test if apache starts with the new configuration file - $apache_online_status_before_restart = $this->_checkTcp('localhost', 80); - $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the apache status again - $apache_online_status_after_restart = false; - sleep(2); - for($i = 0; $i < 5; $i++) { - $apache_online_status_after_restart = $this->_checkTcp('localhost', 80); - if($apache_online_status_after_restart) break; - sleep(1); - } - //* Check if apache restarted successfully if it was online before - $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) { - $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - // if no output is given, check again - $webserver_binary = ''; - exec('which apache2ctl apache2 httpd2 httpd apache 2>/dev/null', $webserver_check_output, $webserver_check_retval); - if($webserver_check_retval == 0){ - $webserver_binary = reset($webserver_check_output); - } - if($webserver_binary != ''){ - exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - } - $app->system->copy($vhost_file, $vhost_file.'.err'); - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~', $vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - if($this->ssl_certificate_changed === true) { - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file, $key_file.'.err'); - $app->system->chmod($key_file.'.err', 0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2, $key_file2.'.err'); - $app->system->chmod($key_file2.'.err', 0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); - if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); - if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file); - - $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); - } - - $app->services->restartService('httpd', 'restart'); - } - } else { - //* We do not check the apache config after changes (is faster) - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); - - //* Unset action to clean it for next processed vhost. - $this->action = ''; - } - - function delete($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - } else { - $apache_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // get log folder from /etc/fstab - /* - $bind_mounts = $app->system->file_get_contents('/etc/fstab'); - $bind_mount_lines = explode("\n", $bind_mounts); - if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ - foreach($bind_mount_lines as $bind_mount_line){ - $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); - $bind_mount_parts = explode(' ', $bind_mount_line); - if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ - if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ - $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); - } - } - } - } - */ - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - } - } else { - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - } - - // remove letsencrypt if it exists (renew will always fail otherwise) - - $old_domain = $data['old']['domain']; - if(substr($old_domain, 0, 2) === '*.') { - // wildcard domain not yet supported by letsencrypt! - $old_domain = substr($old_domain, 2); - } - $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; - @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - // just run the update function - $this->update($event_name, $data); - - } else { - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot, '..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains and alias with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data, $web_config); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // delete the symlink - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data, $web_config); - } - - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $app->system->web_folder_protection($parent_web_document_root, true); - } - - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - - //* Delete the web-backups - if($data['old']['type'] == 'vhost') { - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - $backup_dir = $server_config['backup_dir']; - $mount_backup = true; - if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { - //* mount backup directory, if necessary - if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; - - if($mount_backup){ - $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; - //** do not use rm -rf $web_backup_dir because database(s) may exits - exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); - //* cleanup database - $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; - $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - - $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); - } - } - } - } - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); - } - - //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered - function server_ip($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('apache_ispconfig.conf.master'); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('logging', $web_config['logging']); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']); - - $records_out= array(); - if(is_array($records)) { - foreach($records as $rec) { - if($rec['ip_type'] == 'IPv6') { - $ip_address = '['.$rec['ip_address'].']'; - } else { - $ip_address = $rec['ip_address']; - } - $ports = explode(',', $rec['virtualhost_port']); - if(is_array($ports)) { - foreach($ports as $port) { - $port = intval($port); - if($port > 0 && $port < 65536 && $ip_address != '') { - $records_out[] = array('ip_address' => $ip_address, 'port' => $port); - } - } - } - } - } - - - if(count($records_out) > 0) { - $tpl->setLoop('ip_adresses', $records_out); - } - - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf'); - $app->system->file_put_contents($vhost_file, $tpl->grab()); - $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - } - - //* Create or update the .htaccess folder protection - function web_folder_user($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); - } - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd', 0751); - $app->system->chown($folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } - - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); - $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); - } - } - - - //* Create the .htaccess file - //if(!is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker; - - if(file_exists($folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($folder_path.'.htaccess'); - - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } - unset($old_content); - - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->system->chmod($folder_path.'.htaccess', 0751); - $app->system->chown($folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - //} - + public function __construct() { + $this->plugin_name = get_class($this); + $this->class_name = get_class($this); } - //* Remove .htaccess and .htpasswd file, when folder protection is removed - function web_folder_delete($event_name, $data) { - global $app, $conf; - - $folder_id = $data['old']['web_folder_id']; - - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; + //* This function is called during ispconfig installation to determine + // if a symlink shall be created for this plugin. + function onInstall() { + global $conf; - //* Check if the resulting path is inside the docroot - if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); + if($conf['services']['web'] == true) { + return true; + } else { return false; } - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } + } - //* Remove .htaccess file - if(is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - $ht_file = $app->system->file_get_contents($folder_path.'.htaccess'); + /* + This function is called when the plugin is loaded + */ - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } + function onLoad() { + global $app; - if(trim($ht_file) == '') { - $app->system->unlink($folder_path.'.htaccess'); - $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + /* + Register for the events + */ + $app->plugin_webserver_base->registerEvents('apache'); } - //* Update folder protection, when path has been changed - function web_folder_update($event_name, $data) { - global $app, $conf; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } + // Handle php.ini changes + function php_ini_changed($event_name, $data) { + global $app; - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'apache'); - //* Get the folder path. - if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); - if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; + } - if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); - if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; + // Handle the creation of SSL certificates + function ssl($event_name, $data) { + global $app; - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } + $app->plugin_webserver_base->eventSsl($event_name, $data, 'apache'); + } - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); + function insert($event_name, $data) { + $this->action = 'insert'; + // just run the update function + $this->update($event_name, $data); + } - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - if($data['old']['path'] != $data['new']['path']) { + function update($event_name, $data) { + global $app; + if($this->action != 'insert') $this->action = 'update'; - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } + $app->plugins_webserver_base->eventUpdate($event_name, $data, 'apache'); - //* delete old .htaccess file - if(is_file($old_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess'); + //* Unset action to clean it for next processed vhost. + $this->action = ''; + } - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } + function delete($event_name, $data) { + global $app; - if(trim($ht_file) == '') { - $app->system->unlink($old_folder_path.'.htaccess'); - $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventDelete($event_name, $data, 'apache'); + } - } + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered + function server_ip($event_name, $data) { + global $app; - //* Create the .htaccess file - if($data['new']['active'] == 'y') { - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + $app->plugin_webserver_base->eventServerIp($event_name, $data, 'apache'); - if(file_exists($new_folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess'); + } - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } + //* Create or update the .htaccess folder protection + function web_folder_user($event_name, $data) { + global $app; - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->system->chmod($new_folder_path.'.htaccess', 0751); - $app->system->chown($new_folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($new_folder_path.'.htpasswd'); - $app->system->chmod($new_folder_path.'.htpasswd', 0751); - $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'apache'); - //* Remove .htaccess file - if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess'); + } - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } + //* Remove .htaccess and .htpasswd file, when folder protection is removed + function web_folder_delete($event_name, $data) { + global $app; - if(trim($ht_file) == '') { - $app->system->unlink($new_folder_path.'.htaccess'); - $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'apache'); + } + //* Update folder protection, when path has been changed + function web_folder_update($event_name, $data) { + global $app; + $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'apache'); } public function ftp_user_delete($event_name, $data) { - global $app, $conf; + global $app; $ftpquota_file = $data['old']['dir'].'/.ftpquota'; if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); - } - - /** * This function is called when a Webdav-User is inserted, updated or deleted. * @@ -2602,10 +177,10 @@ class apache2_plugin { /* Check if this is a chrooted setup */ if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; + $is_chrooted = true; $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); } else { - $apache_chrooted = false; + $is_chrooted = false; } //* We dont want to have relative paths here @@ -2663,12 +238,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($apache_chrooted) { + if($is_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -2695,12 +270,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($apache_chrooted) { + if($is_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -2717,7 +292,7 @@ class apache2_plugin { * @param string $filename The name of the digest-file * @param string $username The name of the webdav-user * @param string $authname The name of the realm - * @param string $pwd The password-hash of the user + * @param string $pwdhash The password-hash of the user */ private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) { global $app; @@ -2765,475 +340,11 @@ class apache2_plugin { } } - /** - * This function patches the vhost-file and adds all webdav - user. - * This function is written, because the creation of the vhost - file is sophisticated and - * i don't want to make it more "heavy" by also adding this code too... - * @author Oliver Vogel - * @param string $fileName The Name of the .vhost-File (path included) - * @param string $webdavRoot The root of the webdav-folder - */ - private function _patchVhostWebdav($fileName, $webdavRoot) { - global $app; - $in = fopen($fileName, 'r'); - $output = ''; - $inWebdavSection = false; - //* read line by line and search for the username and authname - while ($line = fgets($in)) { - //* is the "replace-comment" found... - if (trim($line) == '# WEBDAV BEGIN') { - //* The begin of the webdav - section is found, so ignore all lines til the end is found - $inWebdavSection = true; - $output .= "# WEBDAV BEGIN\n"; - //* add all the webdav-dirs to the webdav-section - $files = @scandir($webdavRoot); - if(is_array($files)) { - foreach($files as $file) { - if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) { - //* found a htdigest - file, so add it to webdav - $fn = substr($file, 0, strlen($file) - strlen('.htdigest')); - $output .= "\n"; - $output .= "Alias /webdav/$fn $webdavRoot/$fn\n"; - $output .= "\n"; - $output .= "DAV On\n"; - $output .= "BrowserMatch MSIE AuthDigestEnableQueryStringHack=On\n"; - $output .= "AuthType Digest\n"; - if($fn != '' && $fn != '/') { - $output .= "AuthName \"" . $fn . "\"\n"; - } else { - $output .= "AuthName \"Restricted Area\"\n"; - } - $output .= "AuthUserFile $webdavRoot/$file\n"; - $output .= "Require valid-user\n"; - $output .= "Options +Indexes\n"; - if($app->system->getapacheversion()<=2.2) - $output .= "Order allow,deny\nAllow from all\n"; - $output .= "\n"; - } - } - } - } - //* is the "replace-comment-end" found... - if (trim($line) == '# WEBDAV END') { - //* The end of the webdav - section is found, so stop ignoring - $inWebdavSection = false; - } - //* Write the line to the output, if it is not in the section - if (!$inWebdavSection) { - $output .= $line; - } - } - fclose($in); - //* Now lets write the new file - $app->system->file_put_contents($fileName, $output); - } - - //* Update the awstats configuration file - private function awstats_update ($data, $web_config) { - global $app; - - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - if (is_file($awstats_conf_dir."/awstats.conf")) { - $include_file = $awstats_conf_dir."/awstats.conf"; - } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { - $include_file = $awstats_conf_dir."/awstats.model.conf"; - } - $content .= "Include \"".$include_file."\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - if (isset($include_file)) { - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); - } else { - $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); - } - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } - } - - //* Delete the awstats configuration file - private function awstats_delete ($data, $web_config) { - global $app; - - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); - } - } - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { - global $app, $conf; - $pool_dir = trim($pool_dir); - //$reload = false; - - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] != 'php-fpm'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] == 'php-fpm'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - //if($reload == true) $app->services->restartService('php-fpm','reload'); - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_listen_mode', '0660'); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_user', $data['new']['system_user']); - $tpl->setVar('fpm_listen_group', $web_config['group']); - $tpl->setVar('fpm_domain', $data['new']['domain']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level', $web_config['security_level']); - $tpl->setVar('domain', $data['new']['domain']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $custom_session_save_path = false; - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting, 0, 1) == ';') continue; - if(substr($ini_setting, 0, 1) == '#') continue; - if(substr($ini_setting, 0, 2) == '//') continue; - list($key, $value) = explode('=', $ini_setting, 2); - $value = trim($value); - if($value != ''){ - $key = trim($key); - if($key == 'session.save_path') $custom_session_save_path = true; - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - - //$reload = true; - - //if($reload == true) $app->services->restartService('php-fpm','reload'); - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data, $web_config) { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - - //$app->services->restartService('php-fpm','reload'); - } - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - function client_delete($event_name, $data) { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir, '..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $app->system->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); - } - } - - } - - private function _checkTcp ($host, $port) { - - $fp = @fsockopen($host, $port, $errno, $errstr, 2); - - if ($fp) { - fclose($fp); - return true; - } else { - return false; - } - } - - private function _rewrite_quote($string) { - return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); - } + global $app; - private function _is_url($string) { - return preg_match('/^(f|ht)tp(s)?:\/\//i', $string); + $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'apache'); } - private function get_seo_redirects($web, $prefix = ''){ - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){ - $domain = str_replace('.', '\.', $web['domain']); - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = ''; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain.'|.*\.'.$domain.'(? diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 5024a3bff..3a7f569c2 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -30,14 +30,19 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class nginx_plugin { - var $plugin_name = 'nginx_plugin'; - var $class_name = 'nginx_plugin'; + var $plugin_name; + var $class_name; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; + public function __construct() { + $this->plugin_name = get_class($this); + $this->class_name = get_class($this); + } + //* This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. function onInstall() { @@ -62,3096 +67,93 @@ class nginx_plugin { /* Register for the events */ - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); - - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); - - /* - $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav'); - */ + $app->plugin_webserver_base->registerEvents('nginx'); + } - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + // Handle php.ini changes + function php_ini_changed($event_name, $data) { + global $app; - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'nginx'); - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); } // Handle the creation of SSL certificates function ssl($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - - //* Create a SSL Certificate, but only if this is not a mirror server. - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file, $key_file.'.bak'); - $app->system->chmod($key_file.'.bak', 0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2, $key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak', 0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_md = sha256 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " - " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." - " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." - " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - ";//challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file2 = escapeshellcmd($key_file2); - $openssl_cmd_key_file2 = $key_file2; - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $key_file = escapeshellcmd($key_file); - $openssl_cmd_key_file = $key_file; - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - $openssl_cmd_csr_file = $csr_file; - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - $openssl_cmd_crt_file = $crt_file; - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); - exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); - }; - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - - } - - $app->system->chmod($key_file2, 0400); - $app->system->chmod($key_file, 0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->system->file_get_contents($csr_file); - $ssl_cert = $app->system->file_get_contents($crt_file); - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - - //* Check that the SSL key is not password protected - if($data["new"]["ssl_action"] == 'save') { - if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* and check that SSL cert does not contain subdomain of domain acme.invalid - if($data["new"]["ssl_action"] == 'save') { - $tmp = array(); - $crt_data = ''; - exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); - $crt_data = implode("\n",$tmp); - if(stristr($crt_data,'.acme.invalid')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file, $key_file.'~'); - $app->system->chmod($key_file.'~', 0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2, $key_file2.'~'); - $app->system->chmod($key_file2.'~', 0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); - if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); - $app->system->chmod($key_file, 0400); - - // for nginx, bundle files have to be appended to the certificate file - if(trim($data["new"]["ssl_bundle"]) != ''){ - if(file_exists($crt_file)){ - $crt_file_contents = trim($app->system->file_get_contents($crt_file)); - } else { - $crt_file_contents = ''; - } - if($crt_file_contents != '') $crt_file_contents .= "\n"; - $crt_file_contents .= $data["new"]["ssl_bundle"]; - $app->system->file_put_contents($crt_file, $app->file->unix_nl($crt_file_contents)); - unset($crt_file_contents); - } - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); - $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } + global $app; + $app->plugin_webserver_base->eventSsl($event_name, $data, 'nginx'); } function insert($event_name, $data) { - global $app, $conf; - $this->action = 'insert'; // just run the update function $this->update($event_name, $data); - - } function update($event_name, $data) { - global $app, $conf; - - //* Check if the apache plugin is enabled - if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { - $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN); - return 0; - } + global $app; if($this->action != 'insert') $this->action = 'update'; - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name, $data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - $app->log('Info: nginx is chrooted.', LOGLEVEL_DEBUG); - } else { - $nginx_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); - return 0; - } - if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false - || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { - $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty', LOGLEVEL_WARN); - return 0; - } - - $web_folder = 'web'; - $log_folder = 'log'; - $old_web_folder = 'web'; - $old_log_folder = 'log'; - if($data['new']['type'] == 'vhost'){ - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $web_folder .= '/'.$data['new']['web_folder']; - - if($data['old']['web_folder'] != ''){ - if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1); - if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1); - } - $old_web_folder .= '/'.$data['old']['web_folder']; - } - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - // new one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - $web_folder = $data['new']['web_folder']; - $log_folder .= '/' . $subdomain_host; - unset($tmp); - - if(isset($data['old']['parent_domain_id'])) { - // old one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $old_web_folder = $data['old']['web_folder']; - $old_log_folder .= '/' . $subdomain_host; - unset($tmp); - } - } - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { - //* Move the site data - $tmp_docroot = explode('/', $data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/', $tmp_docroot); - - $tmp_docroot = explode('/', $data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/', $tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); - } - - //* Unmount the old log directory bfore we move the log dir - exec('umount '.escapeshellcmd($old_dir.'/log')); - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'], false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - /* - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - */ - - $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - - if($web_config['network_filesystem'] == 'y') { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } - - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'], false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - - if(!is_dir($data['new']['document_root'].'/.ssh')) { - $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); - $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); - $app->system->chown($data['new']['document_root'].'/.ssh', $username); - $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); - } - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - } - - - // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - - //* Unmount log directory - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; - $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); - } - - $app->system->web_folder_protection($data['new']['document_root'], true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { - // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - //* Copy the web skeleton files only when there is no index.ph or index.html file yet - if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - //} - } else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } else { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - $mb_soft = $data['new']['hd_quota']; - $mb_hard = $mb_soft + 1; - } else { - $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; - } - - // get the primitive folder for document_root and the filesystem, will need it later. - $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); - $file_system = $df_output[0]; - $primitive_root = $df_output[1]; - - if($file_system == 'xfs') { - exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); - - // xfs only supports timers globally, not per user. - exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); - - unset($project_uid, $username_position, $xfs_projects); - unset($primitive_root, $df_output, $mb_hard, $mb_soft); - } else { - if($app->system->is_installed('setquota')) { - exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - } - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the nginx user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'], false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0751); - //$app->system->chmod($data['new']['document_root'].'/webdav',0710); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751); - - // make tmp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $app->system->_exec($command); - } - - //* if we have a chrooted nginx environment - if($nginx_chrooted) { - $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the nginx user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0755); - //$app->system->chmod($data['new']['document_root'].'/webdav',0755); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755); - - // make temp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - } - } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && - (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { - - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'], true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - } - - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('nginx_vhost.conf.master'); - - // IPv4 - if($data['new']['ip_address'] == '') $data['new']['ip_address'] = '*'; - - //* use ip-mapping for web-mirror - if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { - $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; - $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); - $data['new']['ip_address'] = $newip['destination_ip']; - unset($newip); - } - - $vhost_data = $data['new']; - - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - - // IPv6 - if($data['new']['ipv6_address'] != ''){ - $tpl->setVar('ipv6_enabled', 1); - if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; - } - } - } - - // PHP-FPM - // Support for multiple PHP versions - /* - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - */ - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - $php_fpm_nochroot = 0; - } else { - $php_fpm_chroot = 0; - $php_fpm_nochroot = 1; - } - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); - $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; - - // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. - if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; - - // Custom rewrite rules - /* - $final_rewrite_rules = array(); - $custom_rewrite_rules = $data['new']['rewrite_rules']; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - */ - - // Custom rewrite rules - $final_rewrite_rules = array(); - - if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { - $custom_rewrite_rules = trim($data['new']['rewrite_rules']); - $custom_rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - // ignore comments - if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // empty lines - if(trim($custom_rewrite_rule_line) == ''){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // closing curly bracket - if(trim($custom_rewrite_rule_line) == '}'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level -= 1; - continue; - } - $custom_rewrites_are_valid = false; - break; - } - } - if(!$custom_rewrites_are_valid || $if_level != 0){ - $final_rewrite_rules = array(); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - - // Custom nginx directives - $final_nginx_directives = array(); - if($data['new']['enable_pagespeed'] == 'y'){ - // if PageSpeed is already enabled, don't add configuration again - if(stripos($nginx_directives, 'pagespeed') !== false){ - $vhost_data['enable_pagespeed'] = false; - } else { - $vhost_data['enable_pagespeed'] = true; - } - } else { - $vhost_data['enable_pagespeed'] = false; - } - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $nginx_directives = $snippet['snippet']; - } else { - $nginx_directives = $data['new']['nginx_directives']; - } -/* - if($data['new']['enable_pagespeed'] == 'y'){ - // if PageSpeed is already enabled, don't add configuration again - if(stripos($nginx_directives, 'pagespeed') !== false){ - $vhost_data['enable_pagespeed'] = false; - } else { - $vhost_data['enable_pagespeed'] = true; - } - } else { - $vhost_data['enable_pagespeed'] = false; - } -*/ - } else { - $nginx_directives = $data['new']['nginx_directives']; -// $vhost_data['enable_pagespeed'] = false; - } - - // folder_directive_snippets - if(trim($data['new']['folder_directive_snippets']) != ''){ - $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); - $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); - - if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ - foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ - list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); - - $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); - $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); - - if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ - if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; - if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); - - $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); - if(isset($master_snippet['snippet'])){ - $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); - $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); - $nginx_directives .= "\n\n".$master_snippet['snippet']; - - // create folder it it does not exist - if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ - $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); - $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); - } - } - } - } - } - } - - // use vLib for template logic - if(trim($nginx_directives) != '') { - $nginx_directives_new = ''; - $ngx_conf_tpl = new tpl(); - $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); - file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); - $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); - $ngx_conf_tpl->setVar('use_tcp', $use_tcp); - $ngx_conf_tpl->setVar('use_socket', $use_socket); - $ngx_conf_tpl->setVar('fpm_socket', $fpm_socket); - $ngx_conf_tpl->setVar($vhost_data); - $nginx_directives_new = $ngx_conf_tpl->grab(); - if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); - if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; - unset($nginx_directives_new); - } - - // Make sure we only have Unix linebreaks - $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); - $nginx_directives = str_replace("\r", "\n", $nginx_directives); - $nginx_directive_lines = explode("\n", $nginx_directives); - if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], - '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';' - ); - foreach($nginx_directive_lines as $nginx_directive_line){ - $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); - } - } - $tpl->setLoop('nginx_directives', $final_nginx_directives); - - $app->uses('letsencrypt'); - // Check if a SSL cert exists - $tmp = $app->letsencrypt->get_website_certificate_paths($data); - $domain = $tmp['domain']; - $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; - $crt_file = $tmp['crt']; - $bundle_file = $tmp['bundle']; - unset($tmp); - - $data['new']['ssl_domain'] = $domain; - $vhost_data['ssl_domain'] = $domain; - $vhost_data['ssl_crt_file'] = $crt_file; - $vhost_data['ssl_key_file'] = $key_file; - $vhost_data['ssl_bundle_file'] = $bundle_file; - - //* Generate Let's Encrypt SSL certificat - if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server - ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration - || ($data['old']['domain'] != $data['new']['domain']) // we have domain update - || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain - || $this->update_letsencrypt == true - )) { - - $success = $app->letsencrypt->request_certificates($data, 'nginx'); - if($success) { - /* we don't need to store it. - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain_id = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } else { - $data['new']['ssl_letsencrypt'] = 'n'; - if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); - } - } - - if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $vhost_data['ssl_enabled'] = 1; - $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); - } else { - $vhost_data['ssl_enabled'] = 0; - $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new']); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - // Rewrite rules - $own_rewrite_rules = array(); - $rewrite_rules = array(); - $local_rewrite_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - if($data['new']['redirect_type'] != 'proxy'){ - $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); - } else { - $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); - } - } - - // Custom proxy directives - if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $data['new']['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - switch($data['new']['subdomain']) { - case 'www': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - case '*': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - - //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - default: - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - $exclude_own_hostname = ''; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - } - } - - // http2 or spdy? - $vhost_data['enable_http2'] = 'n'; - if($vhost_data['enable_spdy'] == 'y'){ - // check if nginx support http_v2; if so, use that instead of spdy - exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval); - if($tmp_retval == 0){ - $vhost_data['enable_http2'] = 'y'; - $vhost_data['enable_spdy'] = 'n'; - } - unset($tmp_output, $tmp_retval); - } - - // set logging variable - $vhost_data['logging'] = $web_config['logging']; - - $tpl->setVar($vhost_data); - - $server_alias = array(); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias.' '; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain'].' '; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - - // Custom proxy directives - if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $alias['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { - switch($alias['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' '; - break; - default: - $server_alias[] = $alias['domain'].' '; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - } - - // Local Rewriting (inside vhost server {} container) - if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - switch($alias['subdomain']) { - case 'www': - // example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - - // www.example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - case '*': - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', - 'local_redirect_operator' => '~*', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - default: - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - } - } - - // External Rewriting (extra server {} containers) - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - if($alias['redirect_type'] != 'proxy'){ - $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); - } else { - $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); - } - } - - switch($alias['subdomain']) { - case 'www': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - case '*': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - default: - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); - else $domain_rule = $alias['domain']; - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - if(substr($alias['domain'], 0, 2) === '*.'){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - } else { - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - } - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - } - } - } - } - - //* If we have some alias records - if(count($server_alias) > 0) { - $server_alias_str = ''; - $n = 0; - - foreach($server_alias as $tmp_alias) { - $server_alias_str .= $tmp_alias; - } - unset($tmp_alias); - - $tpl->setVar('alias', trim($server_alias_str)); - } else { - $tpl->setVar('alias', ''); - } - - if(count($rewrite_rules) > 0) { - $tpl->setLoop('redirects', $rewrite_rules); - } - if(count($own_rewrite_rules) > 0) { - $tpl->setLoop('own_redirects', $own_rewrite_rules); - } - if(count($local_rewrite_rules) > 0) { - $tpl->setLoop('local_redirects', $local_rewrite_rules); - } - if(count($alias_seo_redirects) > 0) { - $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); - } - - $stats_web_folder = 'web'; - if($data['new']['type'] == 'vhost'){ - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $stats_web_folder .= '/'.$data['new']['web_folder']; - } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - $stats_web_folder = $data['new']['web_folder']; - } - - //* Create basic http auth for website statistics - $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); - - // Create basic http auth for other directories - $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); - if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); - - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) copy($vhost_file, $vhost_file.'~'); - - //* Write vhost file - $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); - $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file, $vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); - } - - // create password file for stats directory - if(!is_file($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->file_put_contents($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', $htp_file); - $app->system->chmod($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - $this->awstats_update($data, $web_config); - } - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - - if($web_config['check_apache_config'] == 'y') { - //* Test if nginx starts with the new configuration file - $nginx_online_status_before_restart = $this->_checkTcp('localhost', 80); - $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('nginx restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the apache status again - sleep(2); - - //* Check if nginx restarted successfully if it was online before - $nginx_online_status_after_restart = $this->_checkTcp('localhost', 80); - $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) { - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - // if no output is given, check again - exec('nginx -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - $app->system->copy($vhost_file, $vhost_file.'.err'); - - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~', $vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file, "# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - - if($this->ssl_certificate_changed === true) { - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file, $key_file.'.err'); - $app->system->chmod($key_file.'.err', 0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2, $key_file2.'.err'); - $app->system->chmod($key_file2.'.err', 0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); - //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); - //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file); - - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); - } - - $app->services->restartService('httpd', 'restart'); - } - } else { - //* We do not check the nginx config after changes (is faster) - $app->services->restartServiceDelayed('httpd', 'reload'); - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); + $app->plugins_webserver_base->eventUpdate($event_name, $data, 'nginx'); //* Unset action to clean it for next processed vhost. $this->action = ''; } function delete($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - } else { - $nginx_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // get log folder from /etc/fstab - /* - $bind_mounts = $app->system->file_get_contents('/etc/fstab'); - $bind_mount_lines = explode("\n", $bind_mounts); - if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ - foreach($bind_mount_lines as $bind_mount_line){ - $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); - $bind_mount_parts = explode(' ', $bind_mount_line); - if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ - if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ - $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); - } - } - } - } - */ - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - } else { - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - - //try umount mysql - if(file_exists($data['old']['document_root'].'/var/run/mysqld')) { - $fstab_line = '/var/run/mysqld ' . $data['old']['document_root'] . '/var/run/mysqld none bind,nobootwait 0 0'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $command = 'umount ' . escapeshellarg($data['old']['document_root']) . '/var/run/mysqld/'; - exec($command); - } - // remove letsencrypt if it exists (renew will always fail otherwise) - - $old_domain = $data['old']['domain']; - if(substr($old_domain, 0, 2) === '*.') { - // wildcard domain not yet supported by letsencrypt! - $old_domain = substr($old_domain, 2); - } - $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; - @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - // just run the update function - $this->update($event_name, $data); - - } else { - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot, '..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains and alias with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $this->php_fpm_pool_delete($data, $web_config); - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data, $web_config); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // delete the symlink - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data, $web_config); - } - - //* Delete the web-backups - if($data['old']['type'] == 'vhost') { - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - $backup_dir = $server_config['backup_dir']; - $mount_backup = true; - if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { - //* mount backup directory, if necessary - if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; - - if($mount_backup){ - $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; - //** do not use rm -rf $web_backup_dir because database(s) may exits - exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); - //* cleanup database - $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; - $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - - $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); - } - } - } - - $app->services->restartServiceDelayed('httpd', 'reload'); - - } - + global $app; - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); + $app->plugin_webserver_base->eventDelete($event_name, $data, 'nginx'); } - //* This function is called when a IP on the server is inserted, updated or deleted + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered function server_ip($event_name, $data) { - return; + global $app; + + $app->plugin_webserver_base->eventServerIp($event_name, $data, 'nginx'); + } //* Create or update the .htaccess folder protection function web_folder_user($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); - } - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd', 0755); - $app->system->chown($folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } + global $app; - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); - $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'nginx'); - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); } //* Remove .htpasswd file, when folder protection is removed function web_folder_delete($event_name, $data) { - global $app, $conf; - - $folder_id = $data['old']['web_folder_id']; - - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } + global $app; - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); + $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'nginx'); } //* Update folder protection, when path has been changed function web_folder_update($event_name, $data) { - global $app, $conf; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); - if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; - - if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); - if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); - - if($data['old']['path'] != $data['new']['path']) { - - - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - } - - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - function _create_web_folder_auth_configuration($website){ - global $app, $conf; - //* Create the domain.auth file which is included in the vhost configuration file - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); - //$app->load('tpl'); - //$tpl = new tpl(); - //$tpl->newTemplate('nginx_http_authentication.auth.master'); - $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); - $basic_auth_locations = array(); - if(is_array($website_auth_locations) && !empty($website_auth_locations)){ - foreach($website_auth_locations as $website_auth_location){ - if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); - if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); - if($website_auth_location['path'] != ''){ - $website_auth_location['path'] .= '/'; - } - $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], - 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); - } - } - return $basic_auth_locations; - //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); - //file_put_contents($basic_auth_file,$tpl->grab()); - //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); - //unset($tpl); - //$app->services->restartServiceDelayed('httpd','reload'); - } - - //* Update the awstats configuration file - private function awstats_update ($data, $web_config) { global $app; - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - if (is_file($awstats_conf_dir."/awstats.conf")) { - $include_file = $awstats_conf_dir."/awstats.conf"; - } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { - $include_file = $awstats_conf_dir."/awstats.model.conf"; - } - $content .= "Include \"".$include_file."\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - if (isset($include_file)) { - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); - } else { - $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); - } - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } + $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'nginx'); } - //* Delete the awstats configuration file - private function awstats_delete ($data, $web_config) { + public function ftp_user_delete($event_name, $data) { global $app; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); - } - } - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { - global $app, $conf; - $pool_dir = trim($pool_dir); - $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); - - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] != 'php-fpm'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] != 'no'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - } else { - $php_fpm_chroot = 0; - } - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_listen_mode', '0660'); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - - //Red Hat workaround for group ownership of socket files - foreach($rh_releasefiles as $rh_file) { - if(file_exists($rh_file) && (filesize($rh_file) > 0)) { - $tmp = file_get_contents($rh_file); - if(preg_match('/[67]+\.[0-9]+/m', $tmp)) { - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $data['new']['system_group']); - } - unset($tmp); - } elseif(!file_exists($rh_file)) { - //OS seems to be not Red Hat'ish - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $web_config['group']); - } - break; - } - - $tpl->setVar('fpm_listen_user', $data['new']['system_user']); - $tpl->setVar('fpm_domain', $data['new']['domain']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level', $web_config['security_level']); - $tpl->setVar('domain', $data['new']['domain']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - if($php_fpm_chroot){ - $document_root = $data['new']['document_root']; - $domain = $data['new']['domain']; - $php_open_basedir = str_replace(":/srv/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace(":/var/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace("$document_root",'',$php_open_basedir); - } - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $custom_session_save_path = false; - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting, 0, 1) == ';') continue; - if(substr($ini_setting, 0, 1) == '#') continue; - if(substr($ini_setting, 0, 2) == '//') continue; - list($key, $value) = explode('=', $ini_setting, 2); - $value = trim($value); - if($value != ''){ - $key = trim($key); - if($key == 'session.save_path') $custom_session_save_path = true; - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data, $web_config) { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - } - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - private function nginx_replace($matches){ - $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; - if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; - if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; - $location .= "\n"; - $location .= $matches[5]."\n"; - $location .= $matches[6]; - return $location; - } - - private function nginx_merge_locations($vhost_conf) { - global $app, $conf; - - if(preg_match('/##subroot (.+?)\s*##/', $vhost_conf, $subroot)) { - if(!preg_match('/^(?:[a-z0-9\/_-]|\.(?!\.))+$/iD', $subroot[1])) { - $app->log('Token ##subroot is unsecure (server ID: '.$conf['server_id'].').', LOGLEVEL_WARN); - } else { - $insert_pos = strpos($vhost_conf, ';', strpos($vhost_conf, 'root ')); - $vhost_conf = substr_replace($vhost_conf, ltrim($subroot[1], '/'), $insert_pos, 0); - } - } - - $lines = explode("\n", $vhost_conf); - - // if whole location block is in one line, split it up into multiple lines - if(is_array($lines) && !empty($lines)){ - $linecount = sizeof($lines); - for($h=0;$h<$linecount;$h++){ - // remove comments - if(substr(trim($lines[$h]), 0, 1) == '#'){ - unset($lines[$h]); - continue; - } - - $lines[$h] = rtrim($lines[$h]); - /* - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - $lines[$h] = str_replace(";", ";\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - */ - $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; - $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]); - } - } - $vhost_conf = implode("\n", $lines); - unset($lines); - unset($linecount); - - $lines = explode("\n", $vhost_conf); - - if(is_array($lines) && !empty($lines)){ - $locations = array(); - $locations_to_delete = array(); - $islocation = false; - $linecount = sizeof($lines); - $server_count = 0; - - for($i=0;$i<$linecount;$i++){ - $l = trim($lines[$i]); - if(substr($l, 0, 8) == 'server {') $server_count += 1; - if($server_count > 1) break; - if(substr($l, 0, 8) == 'location' && !$islocation){ - - $islocation = true; - $level = 0; - - // Remove unnecessary whitespace - $l = preg_replace('/\s\s+/', ' ', $l); - - $loc_parts = explode(' ', $l); - // see http://wiki.nginx.org/HttpCoreModule#location - if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ - $location = $loc_parts[1].' '.$loc_parts[2]; - } else { - $location = $loc_parts[1]; - } - unset($loc_parts); - - if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; - if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; - if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; - - if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; - if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; - if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; - if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; - if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; - - unset($lines[$i]); - - } else { - - if($islocation){ - $openingbracketpos = strrpos($l, '{'); - if($openingbracketpos !== false){ - $level += 1; - } - $closingbracketpos = strrpos($l, '}'); - if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){ - $level -= 1; - $locations[$location]['location'] .= $lines[$i]."\n"; - } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){ - $islocation = false; - } else { - $locations[$location]['location'] .= $lines[$i]."\n"; - } - unset($lines[$i]); - } - - } - } + $ftpquota_file = $data['old']['dir'].'/.ftpquota'; + if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); - if(is_array($locations) && !empty($locations)){ - if(is_array($locations_to_delete) && !empty($locations_to_delete)){ - foreach($locations_to_delete as $location_to_delete){ - if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); - } - } - - foreach($locations as $key => $val){ - $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; - $lines[$val['start_line']] = $new_location; - } - } - ksort($lines); - $vhost_conf = implode("\n", $lines); - } - - return trim($vhost_conf); } function client_delete($event_name, $data) { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir, '..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $app->system->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); - } - } - - } - - private function _checkTcp ($host, $port) { - - $fp = @fsockopen($host, $port, $errno, $errstr, 2); - - if ($fp) { - fclose($fp); - return true; - } else { - return false; - } - } - - private function _rewrite_quote($string) { - return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); - } - - private function url_is_local($hostname, $domain_id){ global $app; - // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first - $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); - if(is_array($webs) && !empty($webs)){ - foreach($webs as $web){ - // web domain doesn't match hostname - if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue; - // own vhost and therefore server {} container of its own - //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; - - if($web['subdomain'] == '*'){ - $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'none'){ - if($web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'www'){ - if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if(preg_match($pattern, $hostname)){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - } - } - - return false; + $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'nginx'); } - private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){ - // $force_subdomain = 'none|www' - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){ - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - // ^(example\.com|(?!\bwww\b)\.example\.com)$ - // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - if($force_subdomain != 'none'){ - if($web['seo_redirect'] == 'www_to_non_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){ - // ^(.+)\.example\.com$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - return $seo_redirects; - } } // end class -?> -- GitLab From 397dc0ce96fa96b272a19c8efe6b78efccbe110c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 21:29:04 +0100 Subject: [PATCH 170/310] Revert "Merge branch 'merge-nginx-apache-plugins' into 'master'" This reverts merge request !841 --- .../classes/plugin_webserver_apache.inc.php | 501 --- .../lib/classes/plugin_webserver_base.inc.php | 3011 ---------------- .../classes/plugin_webserver_nginx.inc.php | 840 ----- .../plugins-available/apache2_plugin.inc.php | 3041 +++++++++++++++- server/plugins-available/nginx_plugin.inc.php | 3064 ++++++++++++++++- 5 files changed, 5996 insertions(+), 4461 deletions(-) delete mode 100644 server/lib/classes/plugin_webserver_apache.inc.php delete mode 100644 server/lib/classes/plugin_webserver_base.inc.php delete mode 100644 server/lib/classes/plugin_webserver_nginx.inc.php diff --git a/server/lib/classes/plugin_webserver_apache.inc.php b/server/lib/classes/plugin_webserver_apache.inc.php deleted file mode 100644 index 8393f529a..000000000 --- a/server/lib/classes/plugin_webserver_apache.inc.php +++ /dev/null @@ -1,501 +0,0 @@ -getconf->get_server_config($conf['server_id'], 'web'); - - // Rewrite rules - $rewrite_rules = array(); - $rewrite_wildcard_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8); - } else { - $rewrite_target = $data['new']['redirect_path']; - $rewrite_target_ssl = $data['new']['redirect_path']; - } - /* Disabled path extension - if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { - $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; - } - */ - - switch($data['new']['subdomain']) { - case 'www': - $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_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')); - break; - case '*': - $rewrite_wildcard_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')); - break; - default: - $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')); - } - } - - $server_alias = array(); - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain']; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain']; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - switch($alias['subdomain']) { - case 'www': - $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; - break; - case '*': - $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; - break; - default: - $server_alias[] .= $alias['domain']; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'apache'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - - // Rewriting - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { - if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($alias['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8); - } else { - $rewrite_target = $alias['redirect_path']; - $rewrite_target_ssl = $alias['redirect_path']; - } - - switch($alias['subdomain']) { - case 'www': - $rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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.'.$alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - case '*': - $rewrite_wildcard_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - default: - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2)); - else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']); - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - } - } - } - } - - //* If we have some alias records - if($server_alias) { - //* begin a new ServerAlias line after 32 alias domains to avoid apache bugs - $server_alias_str = 'ServerAlias '.$server_alias[0]; - for($n=1;$nsetVar('alias', $server_alias_str); - unset($server_alias_str); - unset($n); - } else { - $tpl->setVar('alias', ''); - } - - if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules - - if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0 || $data['new']['rewrite_to_https'] == 'y') { - $tpl->setVar('rewrite_enabled', 1); - } else { - $tpl->setVar('rewrite_enabled', 0); - } - - //$tpl->setLoop('redirects',$rewrite_rules); - $this->rewrite_rules = $rewrite_rules; - $this->alias_seo_redirects = $alias_seo_redirects; - - return; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - */ - public function processCustomDirectives(&$tpl, &$data, &$vhost_data) { - global $app; - - // Custom Apache directives - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $vhost_data['apache_directives'] = $snippet['snippet']; - } - } - // Make sure we only have Unix linebreaks - $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); - $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] - ); - $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); - - return; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - */ - public function processPhpStarters(&$tpl, &$data, &$vhost_data) { - global $app, $conf; - - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - /** - * install fast-cgi starter script and add script aliasd config - * first we create the script directory if not already created, then copy over the starter script - * settings are copied over from the server ini config for now - * TODO: Create form for fastcgi configs per site. - */ - - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - if ($data['new']['php'] == 'fast-cgi') { - - $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - - if (!is_dir($fastcgi_starter_path)) { - $app->system->mkdirpath($fastcgi_starter_path); - $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG); - } - - $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); - $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); - if($web_config['security_level'] == 10) { - $app->system->chmod($fastcgi_starter_path, 0755); - } else { - $app->system->chmod($fastcgi_starter_path, 0550); - } - - $fcgi_tpl = new tpl(); - $fcgi_tpl->newTemplate('php-fcgi-starter.master'); - $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion()); - $fcgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - if(trim($data['new']['fastcgi_php_version']) != ''){ - // $custom_fastcgi_php_name - list(, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); - if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); - } - - if(trim($data['new']['custom_php_ini']) != '') { - $has_custom_php_ini = true; - } else { - $has_custom_php_ini = false; - } - - $web_folder = $app->plugin_webserver_base->getWebFolder($data, 'web', false); - - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - // Support for multiple PHP versions (FastCGI) - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_fastcgi_php = false; - if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/'; - } else { - $default_fastcgi_php = true; - } - - if($has_custom_php_ini) { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); - } else { - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); - } else { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir)); - } - } - $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); - $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children'])); - $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests'])); - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin'])); - } else { - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable)); - } - $fcgi_tpl->setVar('security_level', intval($web_config['security_level'])); - $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain'])); - - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); - - $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab()); - unset($fcgi_tpl); - - $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); - - if($web_config['security_level'] == 10) { - $app->system->chmod($fcgi_starter_script, 0755); - } else { - $app->system->chmod($fcgi_starter_script, 0550); - } - $app->system->chown($fcgi_starter_script, $data['new']['system_user']); - $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); - - $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); - $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); - $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); - $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); - - } else { - //remove the php fastgi starter script if available - $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : ''); - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - if($data['old']['type'] == 'vhost') { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path); - } else { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - } - } - } - - return; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - */ - public function processVhosts(&$tpl, &$data, &$vhost_data, $ssl_data) { - global $app, $conf; - - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* create empty vhost array - $vhosts = array(); - - //* Add vhost for ipv4 IP - - //* use ip-mapping for web-mirror - if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { - $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; - $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); - $data['new']['ip_address'] = $newip['destination_ip']; - unset($newip); - } - - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80); - if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); - if(count($this->alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $this->alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv4 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); - if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); - $ipv4_ssl_alias_seo_redirects = $this->alias_seo_redirects; - if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); - } - - //* Add vhost for IPv6 IP - if($data['new']['ipv6_address'] != '') { - //* rewrite ipv6 on mirrors - /* chang $conf to $web_config */ - if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - } - } - if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::'; - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); - if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); - if(count($this->alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $this->alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv6 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); - if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); - $ipv6_ssl_alias_seo_redirects = $this->alias_seo_redirects; - if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); - } - } - - //* Set the vhost loop - $tpl->setLoop('vhosts', $vhosts); - return; - } - - public function testWebserverConfig() { - global $app; - // if no output is given, check again - $webserver_binary = ''; - $webserver_check_output = null; - $webserver_check_retval = 0; - exec('which apache2ctl apache2 httpd2 httpd apache 2>/dev/null', $webserver_check_output, $webserver_check_retval); - if($webserver_check_retval == 0){ - $webserver_binary = reset($webserver_check_output); - } - if($webserver_binary != ''){ - $tmp_output = null; - $tmp_retval = 0; - exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - } -} diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php deleted file mode 100644 index 715270cc5..000000000 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ /dev/null @@ -1,3011 +0,0 @@ -plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); - - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); - - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); - - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); - - $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); - - $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); - - if($server_type === 'apache') { - $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); - } - } - - private function get_master_php_ini_content($web_data) { - global $app, $conf; - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - $php_ini_content = ''; - $master_php_ini_path = ''; - - if($web_data['php'] == 'mod') { - $master_php_ini_path = $web_config['php_ini_path_apache']; - } else { - // check for custom php - if($web_data['fastcgi_php_version'] != '') { - $tmp = explode(':', $web_data['fastcgi_php_version']); - if(isset($tmp[2])) { - $tmppath = $tmp[2]; - if(substr($tmppath, -7) != 'php.ini') { - if(substr($tmppath, -1) != '/') $tmppath .= '/'; - $tmppath .= 'php.ini'; - } - if(file_exists($tmppath)) { - $master_php_ini_path = $tmppath; - } - unset($tmppath); - } - unset($tmp); - } - - if(!$master_php_ini_path) { - if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } else { - $master_php_ini_path = $web_config['php_ini_path_cgi']; - } - } - } - - // Resolve inconsistant path settings - if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) { - $master_php_ini_path .= '/php.ini'; - } - - // Load the custom php.ini content - if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) { - $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; - } - - return $php_ini_content; - } - - // Handle php.ini changes - /* TODO: change to be compatible to nginx, too */ - public function eventPhpIniChanged($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - if($server_type === 'nginx') { - // not yet implemented - return; - } - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - /* $data contains an array with these keys: - * file -> full path of changed php_ini - * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') - * php_version -> php ini path that changed (additional php versions) - */ - - $param = ''; - $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''"; - if($data['mode'] == 'mod') { - $qrystr .= " AND php = 'mod'"; - } elseif($data['mode'] == 'fast-cgi') { - $qrystr .= " AND php = 'fast-cgi'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version']; - } - } elseif($data['mode'] == 'php-fpm') { - $qrystr .= " AND php = 'php-fpm'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version'] . ':%'; - } - } else { - $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; - } - - - //** Get all the webs - $web_domains = $app->db->queryAllRecords($qrystr, $param); - foreach($web_domains as $web_data) { - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user']; - $web_folder = 'web'; - if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') { - $web_folder = $web_data['web_folder']; - $custom_php_ini_dir .= '_' . $web_folder; - } - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($web_data); - - if(intval($web_data['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini'])); - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG); - } - - if(count($web_domains) > 0) { - //* We do not check the apache config here - we only changed the php.ini - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $is_chrooted = true; - $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); - } else { - $is_chrooted = false; - } - - $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG); - if($is_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } else { - $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG); - } - } - - // Handle the creation of SSL certificates - public function eventSsl($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Create a SSL Certificate, but only if this is not a mirror server. - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file, $key_file.'.bak'); - $app->system->chmod($key_file.'.bak', 0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2, $key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak', 0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_md = sha256 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " - " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." - " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." - " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - ";//challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file2 = escapeshellcmd($key_file2); - $openssl_cmd_key_file2 = $key_file2; - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $key_file = escapeshellcmd($key_file); - $openssl_cmd_key_file = $key_file; - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - $openssl_cmd_csr_file = $csr_file; - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - $openssl_cmd_crt_file = $crt_file; - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); - exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); - } - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - } - - } - - $app->system->chmod($key_file2, 0400); - $app->system->chmod($key_file, 0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->system->file_get_contents($csr_file); - $ssl_cert = $app->system->file_get_contents($crt_file); - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - - //* Check that the SSL key is not password protected - if($data["new"]["ssl_action"] == 'save') { - if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* and check that SSL cert does not contain subdomain of domain acme.invalid - if($data["new"]["ssl_action"] == 'save') { - $tmp = array(); - $crt_data = ''; - exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); - $crt_data = implode("\n",$tmp); - if(stristr($crt_data,'.acme.invalid')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file, $key_file.'~'); - $app->system->chmod($key_file.'~', 0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2, $key_file2.'~'); - $app->system->chmod($key_file2.'~', 0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); - if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); - - if($server_type === 'nginx' || ($server_type === 'apache' && version_compare($app->system->getapacheversion(true), '2.4.8', '>='))) { - // In nginx and apache 2.4.8 and newer, the ssl crt file contains the bundle, so we need no separate bundle file - $tmp_data = ''; - if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n"; - if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"]; - if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $app->file->unix_nl($tmp_data)); - } else { - // Write separate crt and bundle file - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); - if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]); - } - - //* Write the key file, if field is empty then import the key into the db - if(trim($data["new"]["ssl_key"]) != '') { - $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); - $app->system->chmod($key_file, 0400); - } else { - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - } - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); - $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - } - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - $app->system->unlink($bundle_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - } - - - //* Update the awstats configuration file - public function awstats_update($data, $web_config) { - global $app; - - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - if (is_file($awstats_conf_dir."/awstats.conf")) { - $include_file = $awstats_conf_dir."/awstats.conf"; - } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { - $include_file = $awstats_conf_dir."/awstats.model.conf"; - } - $content .= "Include \"".$include_file."\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - if (isset($include_file)) { - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); - } else { - $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); - } - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } - } - - //* Delete the awstats configuration file - public function awstats_delete ($data, $web_config) { - global $app; - - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); - } - } - - public function eventUpdate($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - if($server_type === 'nginx') { - //* Check if the apache plugin is enabled - if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { - $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN); - return 0; - } - } - - if($this->action != 'insert') $this->action = 'update'; - - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name, $data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $is_chrooted = true; - $app->log('Info: Webserver is chrooted.', LOGLEVEL_DEBUG); - } else { - $is_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); - return 0; - } - if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false - || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { - $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty', LOGLEVEL_WARN); - return 0; - } - - $web_folder = $this->getWebFolder($data, 'web', false); - $log_folder = $this->getWebFolder($data, 'log', false); - $old_web_folder = $this->getWebFolder($data, 'web', true); - $old_log_folder = $this->getWebFolder($data, 'log', true); - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - //* Remove protection of old folders - $app->system->web_folder_protection($data['old']['document_root'], false); - - if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { - //* Move the site data - $tmp_docroot = explode('/', $data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/', $tmp_docroot); - - $tmp_docroot = explode('/', $data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/', $tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); - } - - //* Unmount the old log directory bfore we move the log dir - exec('umount -l '.escapeshellcmd($old_dir.'/log')); - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'], false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - /* - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - */ - - $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - - if($web_config['network_filesystem'] == 'y') { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } - - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'], false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - 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($server_type === 'apache') { - if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - } - - if(!is_dir($data['new']['document_root'].'/.ssh')) { - $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); - $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); - $app->system->chown($data['new']['document_root'].'/.ssh', $username); - $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); - } - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - } - - - // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - - //* Unmount log directory - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; - $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); - } - - $app->system->web_folder_protection($data['new']['document_root'], true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { - // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - //* Copy the web skeleton files only when there is no index.ph or index.html file yet - if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - //} - } else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } else { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - $mb_soft = $data['new']['hd_quota']; - $mb_hard = $mb_soft + 1; - } else { - $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; - } - - // get the primitive folder for document_root and the filesystem, will need it later. - $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); - $file_system = $df_output[0]; - $primitive_root = $df_output[1]; - - if($file_system == 'xfs') { - exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); - - // xfs only supports timers globally, not per user. - exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); - - unset($primitive_root, $df_output, $mb_hard, $mb_soft); - } else { - if($app->system->is_installed('setquota')) { - exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - } - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - $user_config_key = 'user'; - if($server_type === 'nginx') { - $user_config_key = 'nginx_user'; - } - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config[$user_config_key])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'], false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0711); - if($server_type === 'apache') { - $app->system->chmod($data['new']['document_root'].'/webdav', 0710); - } - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751); - - // make tmp directory writable for webserver and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $app->system->_exec($command); - } - - //* if we have a chrooted environment - if($is_chrooted) { - $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config[$user_config_key])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - if($server_type === 'apache') { - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - } - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0755); - if($server_type === 'apache') { - $app->system->chmod($data['new']['document_root'].'/webdav', 0755); - } - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755); - - // make temp directory writable for webserver and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - if($server_type === 'apache') { - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - } - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - } - } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && - (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { - - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'], true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - } - - //* Write the custom php.ini file, if custom_php_ini field is not empty - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - if(trim($data['new']['fastcgi_php_version']) != ''){ - // $custom_fastcgi_php_name, $custom_fastcgi_php_executable - list(,, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); - if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); - } - - //* Create custom php.ini - if(trim($data['new']['custom_php_ini']) != '') { - $has_custom_php_ini = true; - if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($data['new']); - $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini'])); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $php_ini_content .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - } else { - $has_custom_php_ini = false; - if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); - } - - $vhost_template_name = 'vhost.conf.master'; - if($server_type === 'nginx') { - $vhost_template_name = 'nginx_vhost.conf.master'; - } - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate($vhost_template_name); - - $vhost_data = $data['new']; - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - $vhost_data['security_level'] = $web_config['security_level']; - $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override']; - $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; - $vhost_data['has_custom_php_ini'] = $has_custom_php_ini; - $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir); - $vhost_data['logging'] = $web_config['logging']; - - // IPv6 - if($data['new']['ipv6_address'] != ''){ - $tpl->setVar('ipv6_enabled', 1); - if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; - } - } - } - - if($server_type === 'nginx') { - $app->plugin_webserver_nginx->processPhpFpm($tpl, $data, $vhost_data); - $app->plugin_webserver_nginx->processRewriteRules($tpl, $data, $vhost_data); - } else { - $app->plugin_webserver_apache->processCustomDirectives($tpl, $data, $vhost_data); - } - - // Custom Apache directives - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $vhost_data['apache_directives'] = $snippet['snippet']; - } - } - // Make sure we only have Unix linebreaks - $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); - $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] - ); - $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); - - $app->uses('letsencrypt'); - // Check if a SSL cert exists - $tmp = $app->letsencrypt->get_website_certificate_paths($data); - $domain = $tmp['domain']; - $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; - $crt_file = $tmp['crt']; - $bundle_file = $tmp['bundle']; - unset($tmp); - - $data['new']['ssl_domain'] = $domain; - $vhost_data['ssl_domain'] = $domain; - $vhost_data['ssl_crt_file'] = $crt_file; - $vhost_data['ssl_key_file'] = $key_file; - $vhost_data['ssl_bundle_file'] = $bundle_file; - - //* Generate Let's Encrypt SSL certificat - if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server - ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration - || ($data['old']['domain'] != $data['new']['domain']) // we have domain update - || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain - || $this->update_letsencrypt == true - )) { - - $success = $app->letsencrypt->request_certificates($data, $server_type); - if($success) { - /* we don't need to store it. - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } else { - $data['new']['ssl_letsencrypt'] = 'n'; - if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); - } - } - - if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; - - // HTTP/2.0 ? - $vhost_data['enable_http2'] = 'n'; - if($vhost_data['enable_spdy'] == 'y'){ - $tmp_output = null; - $tmp_retval = 0; - if($server_type === 'apache') { - // check if apache supports http_v2 - exec("2>&1 apachectl -M | grep http2_module", $tmp_output, $tmp_retval); - } else { - // check if nginx support http_v2; if so, use that instead of spdy - exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval); - } - if($tmp_retval == 0){ - $vhost_data['enable_http2'] = 'y'; - $vhost_data['enable_spdy'] = 'n'; - } - unset($tmp_output, $tmp_retval); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new'], '', false, $server_type); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - if($server_type === 'nginx') { - if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $vhost_data['ssl_enabled'] = 1; - $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); - } else { - $vhost_data['ssl_enabled'] = 0; - $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG); - } - } - - // set logging variable - $vhost_data['logging'] = $web_config['logging']; - - $tpl->setVar($vhost_data); - - $config_prefix = ''; - if($server_type === 'apache') { - $ssl_data = array( - 'crt_file' => $crt_file, - 'key_file' => $key_file, - ); - - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - $app->plugin_webserver_apache->processRewriteRules($tpl, $data, $vhost_data); - $app->plugin_webserver_apache->processPhpStarters($tpl, $data, $vhost_data); - $app->plugin_webserver_apache->processVhosts($tpl, $data, $vhost_data, $ssl_data); - } elseif($server_type === 'nginx') { - $app->plugin_webserver_nginx->processStatsAuth($tpl, $data, $vhost_data); - $config_prefix = 'nginx_'; - } - - - $vhost_file = escapeshellcmd($web_config[$config_prefix.'vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~'); - - //* Write vhost file - if($server_type === 'apache') { - $app->system->file_put_contents($vhost_file, $tpl->grab()); - } else { - $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); - } - $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - if($server_type === 'apache') { - /* - * maybe we have some webdav - user. If so, add them... - */ - $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav'); - } - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file, $vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config[$config_prefix.'vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config[$config_prefix.'vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); - } - - if($server_type === 'apache') { - //* Create .htaccess and .htpasswd file for website statistics - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats'); - $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user"; - $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file); - $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755); - unset($ht_file); - - if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file); - $app->system->web_folder_protection($data['new']['document_root'], true); - $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - } else { - // create password file for stats directory - $stats_web_folder = $app->plugin_webserver_nginx->getStatsFolder($data); - - if(!is_file($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->file_put_contents($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', $htp_file); - $app->system->chmod($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - $app->plugin_webserver_base->awstats_update($data, $web_config); - } - - /** - * PHP-FPM - */ - // Support for multiple PHP versions - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type); - if($server_type === 'nginx') { - $fpm_data = array( - 'use_tcp' => $use_tcp, - 'use_socket' => $use_socket, - 'socket_dir' => $socket_dir, - 'fpm_socket' => $fpm_socket, - 'fpm_port' => $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1 - ); - $app->plugin_webserver_nginx->processCustomDirectives($tpl, $data, $vhost_data, $fpm_data); - } - - if($web_config['check_apache_config'] == 'y') { - //* Test if server starts with the new configuration file - $online_status_before_restart = $this->_checkTcp('localhost', 80); - $app->log('web server status is: '.($online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('web server restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the status again - $online_status_after_restart = false; - sleep(2); - for($i = 0; $i < 5; $i++) { - $online_status_after_restart = $this->_checkTcp('localhost', 80); - if($online_status_after_restart) break; - sleep(1); - } - //* Check if server restarted successfully if it was online before - $app->log('web server online status after restart is: '.($online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - if($online_status_before_restart && !$online_status_after_restart || $retval['retval'] > 0) { - $app->log('web server did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for web server restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - $app->plugin_webserver_apache->testWebserverConfig(); - } - $app->system->copy($vhost_file, $vhost_file.'.err'); - - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~', $vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file, "# web server did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - - if($this->ssl_certificate_changed === true) { - if($server_type === 'nginx') { - /* TODO: check if needed! */ - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - } - - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file, $key_file.'.err'); - $app->system->chmod($key_file.'.err', 0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2, $key_file2.'.err'); - $app->system->chmod($key_file2.'.err', 0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); - if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); - if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file); - - $app->log('web server did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); - } - - $app->services->restartService('httpd', 'restart'); - } - } else { - //* We do not check the web server config after changes (is faster) - if($is_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); - - //* Unset action to clean it for next processed vhost. - $this->action = ''; - } - - public function eventDelete($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $app->system->web_folder_protection($tmp['document_root'], false); - } - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $is_chrooted = true; - } else { - $is_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder) . ' 2>/dev/null'); - } - } else { - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder) . ' 2>/dev/null'); - } - - //try umount mysql - if(file_exists($data['old']['document_root'].'/var/run/mysqld')) { - $fstab_line = '/var/run/mysqld ' . $data['old']['document_root'] . '/var/run/mysqld none bind,nobootwait 0 0'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $command = 'umount ' . escapeshellarg($data['old']['document_root']) . '/var/run/mysqld/'; - exec($command); - } - - // remove letsencrypt if it exists (renew will always fail otherwise) - - $old_domain = $data['old']['domain']; - if(substr($old_domain, 0, 2) === '*.') { - // wildcard domain not yet supported by letsencrypt! - $old_domain = substr($old_domain, 2); - } - @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - // just run the update function - $this->update($event_name, $data); - - } else { - $conf_prefix = ''; - if($server_type === 'nginx') { - $conf_prefix = 'nginx_'; - } - - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config[$conf_prefix.'vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot, '..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains and alias with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data, $web_config, $server_type); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // delete the symlink - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($is_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data, $web_config); - } - - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); $app->system->web_folder_protection($tmp['document_root'], true); - } - - if($is_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - - //* Delete the web-backups - if($data['old']['type'] == 'vhost') { - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - $backup_dir = $server_config['backup_dir']; - $mount_backup = true; - if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { - //* mount backup directory, if necessary - if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; - - if($mount_backup){ - $web_backup_dir = $backup_dir.'/web'.$data['old']['domain_id']; - //** do not use rm -rf $web_backup_dir because database(s) may exits - exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data['old']['domain_id'].'_').'*'); - //* cleanup database - $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; - $app->db->query($sql, $conf['server_id'], $data['old']['domain_id'], "web".$data['old']['domain_id']."_%"); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data['old']['domain_id'], "web".$data['old']['domain_id']."_%"); - - $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); - } - } - } - } - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); - } - - //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered - function eventServerIp($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - if($server_type === 'nginx') { - // not yet implemented - return; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('apache_ispconfig.conf.master'); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('logging', $web_config['logging']); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']); - - $records_out= array(); - if(is_array($records)) { - foreach($records as $rec) { - if($rec['ip_type'] == 'IPv6') { - $ip_address = '['.$rec['ip_address'].']'; - } else { - $ip_address = $rec['ip_address']; - } - $ports = explode(',', $rec['virtualhost_port']); - if(is_array($ports)) { - foreach($ports as $port) { - $port = intval($port); - if($port > 0 && $port < 65536 && $ip_address != '') { - $records_out[] = array('ip_address' => $ip_address, 'port' => $port); - } - } - } - } - } - - - if(count($records_out) > 0) { - $tpl->setLoop('ip_adresses', $records_out); - } - - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf'); - $app->system->file_put_contents($vhost_file, $tpl->grab()); - $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - } - - //* Create or update the .htaccess folder protection - public function eventWebFolderUser($event_name, $data, $server_type = 'apache') { - global $app; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); - } - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd', 0751); - $app->system->chown($folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } - - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); - $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); - } - } - - if($server_type === 'apache') { - //* Create the .htaccess file - //if(!is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker; - - if(file_exists($folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($folder_path.'.htaccess'); - - $matches = array(); - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } - unset($old_content); - - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->system->chmod($folder_path.'.htaccess', 0751); - $app->system->chown($folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - } - - //* Remove .htaccess and .htpasswd file, when folder protection is removed - public function eventWebFolderDelete($event_name, $data, $server_type = 'apache') { - global $app; - - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if($server_type === 'apache') { - //* Remove .htaccess file - if(is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - - $ht_file = $app->system->file_get_contents($folder_path.'.htaccess'); - - $matches = array(); - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } - - if(trim($ht_file) == '') { - $app->system->unlink($folder_path.'.htaccess'); - $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } - } else { - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - } - - //* Update folder protection, when path has been changed - public function eventWebFolderUpdate($event_name, $data, $server_type = 'apache') { - global $app; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); - if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; - - if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); - if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); - - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - - if($data['old']['path'] != $data['new']['path']) { - - - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if($server_type === 'apache') { - //* delete old .htaccess file - if(is_file($old_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess'); - - $matches = array(); - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } - - if(trim($ht_file) == '') { - $app->system->unlink($old_folder_path.'.htaccess'); - $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } - } - - } - - if($server_type === 'apache') { - //* Create the .htaccess file - if($data['new']['active'] == 'y') { - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker; - - if(file_exists($new_folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess'); - - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } - - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->system->chmod($new_folder_path.'.htaccess', 0751); - $app->system->chown($new_folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($new_folder_path.'.htpasswd')) { - $app->system->touch($new_folder_path.'.htpasswd'); - $app->system->chmod($new_folder_path.'.htpasswd', 0751); - $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - } - - //* Remove .htaccess file - if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess'); - - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } - - if(trim($ht_file) == '') { - $app->system->unlink($new_folder_path.'.htaccess'); - $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } - } else { - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - } - - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type = 'apache') { - global $app, $conf; - $pool_dir = trim($pool_dir); - $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); - - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] != 'php-fpm'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] == 'php-fpm'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - } else { - $php_fpm_chroot = 0; - } - if($server_type === 'apache') { - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - } - - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_listen_mode', '0660'); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - - //Red Hat workaround for group ownership of socket files - foreach($rh_releasefiles as $rh_file) { - if(file_exists($rh_file) && (filesize($rh_file) > 0)) { - $tmp = file_get_contents($rh_file); - if(preg_match('/[67]+\.[0-9]+/m', $tmp)) { - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $data['new']['system_group']); - } - unset($tmp); - } elseif(!file_exists($rh_file)) { - //OS seems to be not Red Hat'ish - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $web_config['group']); - } - break; - } - - $tpl->setVar('fpm_listen_user', $data['new']['system_user']); - $tpl->setVar('fpm_domain', $data['new']['domain']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level', $web_config['security_level']); - $tpl->setVar('domain', $data['new']['domain']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - if($php_fpm_chroot){ - $document_root = $data['new']['document_root']; - $domain = $data['new']['domain']; - $php_open_basedir = str_replace(":/srv/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace(":/var/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace("$document_root",'',$php_open_basedir); - } - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = ? AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id']), $server_type); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $custom_session_save_path = false; - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting, 0, 1) == ';') continue; - if(substr($ini_setting, 0, 1) == '#') continue; - if(substr($ini_setting, 0, 2) == '//') continue; - list($key, $value) = explode('=', $ini_setting, 2); - $value = trim($value); - if($value != ''){ - $key = trim($key); - if($key == 'session.save_path') $custom_session_save_path = true; - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data, $web_config, $server_type = 'apache') { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - // $custom_php_fpm_name - list(, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - } - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - public function eventClientDelete($event_name, $data, $server_type = 'apache') { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir, '..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $app->system->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); - } - } - - } - - private function get_seo_redirects($web, $prefix = '', $force_subdomain = false, $server_type = 'apache'){ - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if($server_type === 'apache') { - if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){ - $domain = str_replace('.', '\.', $web['domain']); - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = ''; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain.'|.*\.'.$domain.'(?db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); - if(is_array($webs) && !empty($webs)){ - foreach($webs as $web){ - // web domain doesn't match hostname - if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue; - // own vhost and therefore server {} container of its own - //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; - - if($web['subdomain'] == '*'){ - $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'none'){ - if($web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'www'){ - if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if(preg_match($pattern, $hostname)){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - } - } - - return false; - } - - private function nginx_replace($matches){ - $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; - if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; - if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; - $location .= "\n"; - $location .= $matches[5]."\n"; - $location .= $matches[6]; - return $location; - } - - private function nginx_merge_locations($vhost_conf) { - global $app, $conf; - - $subroot = array(); - if(preg_match('/##subroot (.+?)\s*##/', $vhost_conf, $subroot)) { - if(!preg_match('/^(?:[a-z0-9\/_-]|\.(?!\.))+$/iD', $subroot[1])) { - $app->log('Token ##subroot is unsecure (server ID: '.$conf['server_id'].').', LOGLEVEL_WARN); - } else { - $insert_pos = strpos($vhost_conf, ';', strpos($vhost_conf, 'root ')); - $vhost_conf = substr_replace($vhost_conf, ltrim($subroot[1], '/'), $insert_pos, 0); - } - } - - $lines = explode("\n", $vhost_conf); - - // if whole location block is in one line, split it up into multiple lines - if(is_array($lines) && !empty($lines)){ - $linecount = sizeof($lines); - for($h=0;$h<$linecount;$h++){ - // remove comments - if(substr(trim($lines[$h]), 0, 1) == '#'){ - unset($lines[$h]); - continue; - } - - $lines[$h] = rtrim($lines[$h]); - /* - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - $lines[$h] = str_replace(";", ";\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - */ - $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; - $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]); - } - } - $vhost_conf = implode("\n", $lines); - unset($lines); - unset($linecount); - - $lines = explode("\n", $vhost_conf); - - if(is_array($lines) && !empty($lines)){ - $locations = array(); - $locations_to_delete = array(); - $islocation = false; - $linecount = sizeof($lines); - $server_count = 0; - - for($i=0;$i<$linecount;$i++){ - $l = trim($lines[$i]); - if(substr($l, 0, 8) == 'server {') $server_count += 1; - if($server_count > 1) break; - if(substr($l, 0, 8) == 'location' && !$islocation){ - - $islocation = true; - $level = 0; - - // Remove unnecessary whitespace - $l = preg_replace('/\s\s+/', ' ', $l); - - $loc_parts = explode(' ', $l); - // see http://wiki.nginx.org/HttpCoreModule#location - if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ - $location = $loc_parts[1].' '.$loc_parts[2]; - } else { - $location = $loc_parts[1]; - } - unset($loc_parts); - - if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; - if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; - if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; - - if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; - if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; - if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; - if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; - if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; - - unset($lines[$i]); - - } else { - - if($islocation){ - $openingbracketpos = strrpos($l, '{'); - if($openingbracketpos !== false){ - $level += 1; - } - $closingbracketpos = strrpos($l, '}'); - if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){ - $level -= 1; - $locations[$location]['location'] .= $lines[$i]."\n"; - } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){ - $islocation = false; - } else { - $locations[$location]['location'] .= $lines[$i]."\n"; - } - unset($lines[$i]); - } - - } - } - - if(is_array($locations) && !empty($locations)){ - if(is_array($locations_to_delete) && !empty($locations_to_delete)){ - foreach($locations_to_delete as $location_to_delete){ - if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); - } - } - - foreach($locations as $val){ - $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; - $lines[$val['start_line']] = $new_location; - } - } - ksort($lines); - $vhost_conf = implode("\n", $lines); - } - - return trim($vhost_conf); - } - - - /** - * This function patches the vhost-file and adds all webdav - user. - * This function is written, because the creation of the vhost - file is sophisticated and - * i don't want to make it more "heavy" by also adding this code too... - * @author Oliver Vogel - * @param string $fileName The Name of the .vhost-File (path included) - * @param string $webdavRoot The root of the webdav-folder - */ - private function _patchVhostWebdav($fileName, $webdavRoot) { - global $app; - $in = fopen($fileName, 'r'); - $output = ''; - $inWebdavSection = false; - //* read line by line and search for the username and authname - while ($line = fgets($in)) { - //* is the "replace-comment" found... - if (trim($line) == '# WEBDAV BEGIN') { - //* The begin of the webdav - section is found, so ignore all lines til the end is found - $inWebdavSection = true; - $output .= "# WEBDAV BEGIN\n"; - //* add all the webdav-dirs to the webdav-section - $files = @scandir($webdavRoot); - if(is_array($files)) { - foreach($files as $file) { - if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) { - //* found a htdigest - file, so add it to webdav - $fn = substr($file, 0, strlen($file) - strlen('.htdigest')); - $output .= "\n"; - $output .= "Alias /webdav/$fn $webdavRoot/$fn\n"; - $output .= "\n"; - $output .= "DAV On\n"; - $output .= "BrowserMatch MSIE AuthDigestEnableQueryStringHack=On\n"; - $output .= "AuthType Digest\n"; - if($fn != '' && $fn != '/') { - $output .= "AuthName \"" . $fn . "\"\n"; - } else { - $output .= "AuthName \"Restricted Area\"\n"; - } - $output .= "AuthUserFile $webdavRoot/$file\n"; - $output .= "Require valid-user\n"; - $output .= "Options +Indexes\n"; - if($app->system->getapacheversion()<=2.2) - $output .= "Order allow,deny\nAllow from all\n"; - $output .= "\n"; - } - } - } - } - //* is the "replace-comment-end" found... - if (trim($line) == '# WEBDAV END') { - //* The end of the webdav - section is found, so stop ignoring - $inWebdavSection = false; - } - //* Write the line to the output, if it is not in the section - if (!$inWebdavSection) { - $output .= $line; - } - } - fclose($in); - //* Now lets write the new file - $app->system->file_put_contents($fileName, $output); - } - - public function getWebFolder(&$data, $type, $use_old = false) { - global $app; - - $folder = $type; - - if($type === 'web' && $data['new']['type'] == 'vhost'){ - if($use_old === true) { - if($data['old']['web_folder'] != ''){ - if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1); - if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1); - } - $folder .= '/'.$data['old']['web_folder']; - } else { - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $folder .= '/'.$data['new']['web_folder']; - } - } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - if($use_old === true) { - if(isset($data['old']['parent_domain_id'])) { - // old one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - if($type === 'web') { - $folder = $data['old']['web_folder']; - } else { - $folder .= '/' . $subdomain_host; - } - unset($tmp); - } - } else { - // new one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - if($type === 'web') { - $folder = $data['new']['web_folder']; - } else { - $folder .= '/' . $subdomain_host; - } - unset($tmp); - } - } - } -} diff --git a/server/lib/classes/plugin_webserver_nginx.inc.php b/server/lib/classes/plugin_webserver_nginx.inc.php deleted file mode 100644 index 3002f4b0f..000000000 --- a/server/lib/classes/plugin_webserver_nginx.inc.php +++ /dev/null @@ -1,840 +0,0 @@ -getconf->get_server_config($conf['server_id'], 'web'); - - // PHP-FPM - // Support for multiple PHP versions - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - $php_fpm_nochroot = 0; - } else { - $php_fpm_chroot = 0; - $php_fpm_nochroot = 1; - } - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); - $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; - - // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. - if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; - - return; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - */ - public function processRewriteRules(&$tpl, &$data, &$vhost_data) { - global $app, $conf; - - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - // Custom rewrite rules - $final_rewrite_rules = array(); - - if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { - $custom_rewrite_rules = trim($data['new']['rewrite_rules']); - $custom_rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - // ignore comments - if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // empty lines - if(trim($custom_rewrite_rule_line) == ''){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // closing curly bracket - if(trim($custom_rewrite_rule_line) == '}'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level -= 1; - continue; - } - $custom_rewrites_are_valid = false; - break; - } - } - if(!$custom_rewrites_are_valid || $if_level != 0){ - $final_rewrite_rules = array(); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - - // Rewrite rules - $own_rewrite_rules = array(); - $rewrite_rules = array(); - $local_rewrite_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - if($data['new']['redirect_type'] != 'proxy'){ - $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); - } else { - $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); - } - } - - // Custom proxy directives - if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $data['new']['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - switch($data['new']['subdomain']) { - case 'www': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - case '*': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - - //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - default: - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - $exclude_own_hostname = ''; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - } - } - - $server_alias = array(); - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain']; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain']; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - switch($alias['subdomain']) { - case 'www': - $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; - break; - case '*': - $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; - break; - default: - $server_alias[] .= $alias['domain']; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - } - - // Custom proxy directives - if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $alias['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - - // Local Rewriting (inside vhost server {} container) - if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - switch($alias['subdomain']) { - case 'www': - // example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - - // www.example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - case '*': - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', - 'local_redirect_operator' => '~*', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - default: - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - } - } - - // External Rewriting (extra server {} containers) - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - if($alias['redirect_type'] != 'proxy'){ - $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); - } else { - $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); - } - } - - switch($alias['subdomain']) { - case 'www': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www', 'nginx'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - case '*': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - default: - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); - else $domain_rule = $alias['domain']; - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - if(substr($alias['domain'], 0, 2) === '*.'){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); - } else { - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); - } - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - } - } - } - } - - //* If we have some alias records - if(count($server_alias) > 0) { - $server_alias_str = ''; - foreach($server_alias as $tmp_alias) { - $server_alias_str .= $tmp_alias; - } - unset($tmp_alias); - - $tpl->setVar('alias', trim($server_alias_str)); - } else { - $tpl->setVar('alias', ''); - } - - if(count($rewrite_rules) > 0) { - $tpl->setLoop('redirects', $rewrite_rules); - } - if(count($own_rewrite_rules) > 0) { - $tpl->setLoop('own_redirects', $own_rewrite_rules); - } - if(count($local_rewrite_rules) > 0) { - $tpl->setLoop('local_redirects', $local_rewrite_rules); - } - if(count($alias_seo_redirects) > 0) { - $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); - } - return; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - * @param array $fpm_data - */ - public function processCustomDirectives(&$tpl, &$data, &$vhost_data, $fpm_data) { - global $app, $conf; - - // Custom nginx directives - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $nginx_directives = $snippet['snippet']; - } else { - $nginx_directives = $data['new']['nginx_directives']; - } - } else { - $nginx_directives = $data['new']['nginx_directives']; - } - - $final_nginx_directives = array(); - if($data['new']['enable_pagespeed'] == 'y'){ - // if PageSpeed is already enabled, don't add configuration again - if(stripos($nginx_directives, 'pagespeed') !== false){ - $vhost_data['enable_pagespeed'] = false; - } else { - $vhost_data['enable_pagespeed'] = true; - } - } else { - $vhost_data['enable_pagespeed'] = false; - } - - $web_folder = $app->plugin_webserver_base->getWebFolder($data, 'web'); - $username = escapeshellcmd($data['new']['system_user']); - $groupname = escapeshellcmd($data['new']['system_group']); - - // folder_directive_snippets - if(trim($data['new']['folder_directive_snippets']) != ''){ - $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); - $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); - - if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ - foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ - list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); - - $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); - $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); - - if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ - if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; - if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); - - $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); - if(isset($master_snippet['snippet'])){ - $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); - $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); - $nginx_directives .= "\n\n".$master_snippet['snippet']; - - // create folder it it does not exist - if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ - $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); - $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); - } - } - } - } - } - } - - // use vLib for template logic - if(trim($nginx_directives) != '') { - $nginx_directives_new = ''; - $ngx_conf_tpl = new tpl(); - $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); - file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); - $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); - $ngx_conf_tpl->setVar('use_tcp', $fpm_data['use_tcp']); - $ngx_conf_tpl->setVar('use_socket', $fpm_data['use_socket']); - $ngx_conf_tpl->setVar('fpm_socket', $fpm_data['fpm_socket']); - $ngx_conf_tpl->setVar($vhost_data); - $nginx_directives_new = $ngx_conf_tpl->grab(); - if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); - if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; - unset($nginx_directives_new); - } - - // Make sure we only have Unix linebreaks - $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); - $nginx_directives = str_replace("\r", "\n", $nginx_directives); - $nginx_directive_lines = explode("\n", $nginx_directives); - if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], - '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_data['fpm_socket'] : '127.0.0.1:'.$fpm_data['fpm_port']).';' - ); - foreach($nginx_directive_lines as $nginx_directive_line){ - $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); - } - } - $tpl->setLoop('nginx_directives', $final_nginx_directives); - - return; - } - - - public function getStatsFolder($data) { - $stats_web_folder = 'web'; - if($data['new']['type'] == 'vhost'){ - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $stats_web_folder .= '/'.$data['new']['web_folder']; - } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - $stats_web_folder = $data['new']['web_folder']; - } - return $stats_web_folder; - } - - /** - * This method may alter the $tpl template as well as $data and/or $vhost_data array! - * - * @param tpl $tpl - * @param array $data - * @param array $vhost_data - */ - public function processStatsAuth(&$tpl, &$data, &$vhost_data) { - - $stats_web_folder = $this->getStatsFolder($data); - - //* Create basic http auth for website statistics - $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); - - // Create basic http auth for other directories - $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); - if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); - - return; - } - - private function _create_web_folder_auth_configuration($website){ - global $app; - - //* Create the domain.auth file which is included in the vhost configuration file - - $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); - $basic_auth_locations = array(); - if(is_array($website_auth_locations) && !empty($website_auth_locations)){ - foreach($website_auth_locations as $website_auth_location){ - if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); - if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); - if($website_auth_location['path'] != ''){ - $website_auth_location['path'] .= '/'; - } - $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], - 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); - } - } - return $basic_auth_locations; - } - - public function testWebserverConfig() { - global $app; - - // if no output is given, check again - $tmp_output = null; - $tmp_retval = 0; - exec('nginx -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } -} diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 73f6f9939..5be47d050 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -30,123 +30,2548 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class apache2_plugin { - var $plugin_name; - var $class_name; + var $plugin_name = 'apache2_plugin'; + var $class_name = 'apache2_plugin'; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; - public function __construct() { - $this->plugin_name = get_class($this); - $this->class_name = get_class($this); + //* This function is called during ispconfig installation to determine + // if a symlink shall be created for this plugin. + function onInstall() { + global $conf; + + if($conf['services']['web'] == true) { + return true; + } else { + return false; + } + + } + + + /* + This function is called when the plugin is loaded + */ + + function onLoad() { + global $app; + + /* + Register for the events + */ + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); + + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); + + $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); + + $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); + + $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); + + $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + + $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + + $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); + + $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); + + $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); + } + + private function get_master_php_ini_content($web_data) { + global $app, $conf; + + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + $php_ini_content = ''; + $master_php_ini_path = ''; + + if($web_data['php'] == 'mod') { + $master_php_ini_path = $web_config['php_ini_path_apache']; + } else { + // check for custom php + if($web_data['fastcgi_php_version'] != '') { + $tmp = explode(':', $web_data['fastcgi_php_version']); + if(isset($tmp[2])) { + $tmppath = $tmp[2]; + if(substr($tmppath, -7) != 'php.ini') { + if(substr($tmppath, -1) != '/') $tmppath .= '/'; + $tmppath .= 'php.ini'; + } + if(file_exists($tmppath)) { + $master_php_ini_path = $tmppath; + } + unset($tmppath); + } + unset($tmp); + } + + if(!$master_php_ini_path) { + if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { + $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; + } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) { + $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; + } else { + $master_php_ini_path = $web_config['php_ini_path_cgi']; + } + } + } + + // Resolve inconsistant path settings + if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) { + $master_php_ini_path .= '/php.ini'; + } + + // Load the custom php.ini content + if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) { + $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; + } + + return $php_ini_content; + } + + // Handle php.ini changes + function php_ini_changed($event_name, $data) { + global $app, $conf; + + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + /* $data contains an array with these keys: + * file -> full path of changed php_ini + * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') + * php_version -> php ini path that changed (additional php versions) + */ + + $param = ''; + $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''"; + if($data['mode'] == 'mod') { + $qrystr .= " AND php = 'mod'"; + } elseif($data['mode'] == 'fast-cgi') { + $qrystr .= " AND php = 'fast-cgi'"; + if($data['php_version']) { + $qrystr .= " AND fastcgi_php_version LIKE ?"; + $param = '%:' . $data['php_version']; + } + } elseif($data['mode'] == 'php-fpm') { + $qrystr .= " AND php = 'php-fpm'"; + if($data['php_version']) { + $qrystr .= " AND fastcgi_php_version LIKE ?"; + $param = '%:' . $data['php_version'] . ':%'; + } + } else { + $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; + } + + + //** Get all the webs + $web_domains = $app->db->queryAllRecords($qrystr, $param); + foreach($web_domains as $web_data) { + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user']; + $web_folder = 'web'; + if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') { + $web_folder = $web_data['web_folder']; + $custom_php_ini_dir .= '_' . $web_folder; + } + if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); + + if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir); + + $php_ini_content = $this->get_master_php_ini_content($web_data); + + if(intval($web_data['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini'])); + $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); + $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG); + } + + if(count($web_domains) > 0) { + //* We do not check the apache config here - we only changed the php.ini + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $apache_chrooted = true; + $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); + } else { + $apache_chrooted = false; + } + + $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG); + if($apache_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + } else { + $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG); + } + } + + // Handle the creation of SSL certificates + function ssl($event_name, $data) { + global $app, $conf; + + $app->uses('system'); + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) + $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); + + //* Only vhosts can have a ssl cert + if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; + + // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); + if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + //* Create a SSL Certificate, but only if this is not a mirror server. + if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { + + $this->ssl_certificate_changed = true; + + //* Rename files if they exist + if(file_exists($key_file)){ + $app->system->rename($key_file, $key_file.'.bak'); + $app->system->chmod($key_file.'.bak', 0400); + } + if(file_exists($key_file2)){ + $app->system->rename($key_file2, $key_file2.'.bak'); + $app->system->chmod($key_file2.'.bak', 0400); + } + if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); + if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); + + $rand_file = $ssl_dir.'/random_file'; + $rand_data = md5(uniqid(microtime(), 1)); + for($i=0; $i<1000; $i++) { + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + } + $app->system->file_put_contents($rand_file, $rand_data); + + $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); + + $ssl_cnf = " RANDFILE = $rand_file + + [ req ] + default_bits = 2048 + default_md = sha256 + default_keyfile = keyfile.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + prompt = no + output_password = $ssl_password + + [ req_distinguished_name ] + C = ".trim($data['new']['ssl_country'])." + " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " + " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." + " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." + " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." + CN = $domain + emailAddress = webmaster@".$data['new']['domain']." + + [ req_attributes ] + ";//challengePassword = A challenge password"; + + $ssl_cnf_file = $ssl_dir.'/openssl.conf'; + $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); + + $rand_file = escapeshellcmd($rand_file); + $key_file2 = escapeshellcmd($key_file2); + $openssl_cmd_key_file2 = $key_file2; + if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate + $key_file = escapeshellcmd($key_file); + $openssl_cmd_key_file = $key_file; + if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate + $ssl_days = 3650; + $csr_file = escapeshellcmd($csr_file); + $openssl_cmd_csr_file = $csr_file; + if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate + $config_file = escapeshellcmd($ssl_cnf_file); + $crt_file = escapeshellcmd($crt_file); + $openssl_cmd_crt_file = $crt_file; + if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate + + if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { + + exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); + exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); + exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); + + if(file_exists($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); + $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); + }; + if (@filesize($crt_file)==0 || !file_exists($crt_file)){ + exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); + $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + }; + + } + + $app->system->chmod($key_file2, 0400); + $app->system->chmod($key_file, 0400); + @$app->system->unlink($config_file); + @$app->system->unlink($rand_file); + $ssl_request = $app->system->file_get_contents($csr_file); + $ssl_cert = $app->system->file_get_contents($crt_file); + $ssl_key = $app->system->file_get_contents($key_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + + //* Check that the SSL key is not password protected + if($data["new"]["ssl_action"] == 'save') { + if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* and check that SSL cert does not contain subdomain of domain acme.invalid + if($data["new"]["ssl_action"] == 'save') { + $tmp = array(); + $crt_data = ''; + exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); + $crt_data = implode("\n",$tmp); + if(stristr($crt_data,'.acme.invalid')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + $this->ssl_certificate_changed = true; + + //* Backup files + if(file_exists($key_file)){ + $app->system->copy($key_file, $key_file.'~'); + $app->system->chmod($key_file.'~', 0400); + } + if(file_exists($key_file2)){ + $app->system->copy($key_file2, $key_file2.'~'); + $app->system->chmod($key_file2.'~', 0400); + } + if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); + if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); + if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~'); + + //* Write new ssl files + if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); + if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) { + // In apache 2.4.8 and newer, the ssl crt file contains the bundle, so we need no separate bundle file + $tmp_data = ''; + if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n"; + if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"]; + if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data); + } else { + // Write separate crt and bundle file + if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); + if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]); + } + + //* Write the key file, if field is empty then import the key into the db + if(trim($data["new"]["ssl_key"]) != '') { + $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); + $app->system->chmod($key_file, 0400); + } else { + $ssl_key = $app->system->file_get_contents($key_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); + } + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } + + //* Delete a SSL certificate + if($data['new']['ssl_action'] == 'del') { + if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); + $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + }; + $app->system->unlink($csr_file); + $app->system->unlink($crt_file); + $app->system->unlink($bundle_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } + + } + + + function insert($event_name, $data) { + global $app, $conf; + + $this->action = 'insert'; + // just run the update function + $this->update($event_name, $data); + + + } + + + function update($event_name, $data) { + global $app, $conf; + + if($this->action != 'insert') $this->action = 'update'; + + if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { + + $old_parent_domain_id = intval($data['old']['parent_domain_id']); + $new_parent_domain_id = intval($data['new']['parent_domain_id']); + + // If the parent_domain_id has been changed, we will have to update the old site as well. + if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update($event_name, $data); + } + + // This is not a vhost, so we need to update the parent record instead. + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + } + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $apache_chrooted = true; + $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); + } else { + $apache_chrooted = false; + } + + if($data['new']['document_root'] == '') { + if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); + return 0; + } + if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false + || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { + $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); + return 0; + } + if(trim($data['new']['domain']) == '') { + $app->log('domain is empty', LOGLEVEL_WARN); + return 0; + } + + $web_folder = 'web'; + $log_folder = 'log'; + $old_web_folder = 'web'; + $old_log_folder = 'log'; + if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + // new one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; + $web_folder = $data['new']['web_folder']; + $log_folder .= '/' . $subdomain_host; + unset($tmp); + + if(isset($data['old']['parent_domain_id'])) { + // old one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $old_web_folder = $data['old']['web_folder']; + $old_log_folder .= '/' . $subdomain_host; + unset($tmp); + } + } + + // Create group and user, if not exist + $app->uses('system'); + + if($web_config['connect_userid_to_webid'] == 'y') { + //* Calculate the uid and gid + $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); + $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); + $fixed_uid_param = '--uid '.$fixed_uid_gid; + $fixed_gid_param = '--gid '.$fixed_uid_gid; + + //* Check if a ispconfigend user and group exists and create them + if(!$app->system->is_group('ispconfigend')) { + exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + if(!$app->system->is_user('ispconfigend')) { + exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + } else { + $fixed_uid_param = ''; + $fixed_gid_param = ''; + } + + $groupname = escapeshellcmd($data['new']['system_group']); + if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { + exec('groupadd '.$fixed_gid_param.' '.$groupname); + if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); + $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); + } + + $username = escapeshellcmd($data['new']['system_user']); + if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + } else { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + } + $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); + } + + //* If the client of the site has been changed, we have a change of the document root + if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { + + //* Get the old client ID + $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $old_client_id = intval($old_client['client_id']); + unset($old_client); + + //* Remove the old symlinks + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + //* Remove protection of old folders + $app->system->web_folder_protection($data['old']['document_root'], false); + + if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { + //* Move the site data + $tmp_docroot = explode('/', $data['new']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $new_dir = implode('/', $tmp_docroot); + + $tmp_docroot = explode('/', $data['old']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $old_dir = implode('/', $tmp_docroot); + + //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path + if(@is_dir($data['new']['document_root'])) { + $app->system->web_folder_protection($data['new']['document_root'], false); + $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); + $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); + } + + //* Unmount the old log directory bfore we move the log dir + //exec('fuser -km '.escapeshellcmd($old_dir.'/log')); + exec('umount -l '.escapeshellcmd($data['old']['document_root'].'/log')); + + //* Create new base directory, if it does not exist yet + if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); + $app->system->web_folder_protection($data['old']['document_root'], false); + exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); + //$app->system->rename($data['old']['document_root'],$new_dir); + $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); + + // Handle the change in php_open_basedir + $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); + + //* Change the owner of the website files to the new website owner + exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); + + //* Change the home directory and group of the website user + $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; + $command .= ' --home '.escapeshellcmd($data['new']['document_root']); + $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + exec($command); + } + + if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* Change the log mount + /* + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + */ + + $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + + if($web_config['network_filesystem'] == 'y') { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } + + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + + } + + //print_r($data); + + // Check if the directories are there and create them if necessary. + $app->system->web_folder_protection($data['new']['document_root'], false); + + if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); + 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); + 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); + + if(!is_dir($data['new']['document_root'].'/.ssh')) { + $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); + $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); + $app->system->chown($data['new']['document_root'].'/.ssh', $username); + $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); + } + + //* Create the new private directory + if(!is_dir($data['new']['document_root'].'/private')) { + $app->system->mkdirpath($data['new']['document_root'].'/private'); + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + } + + + // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); + if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); + + //* remove old log mount + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + + //* Unmount log directory + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + } + + //* Create the log dir if nescessary and mount it + if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { + if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); + if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); + $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + //* add mountpoint to fstab + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; + $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); + } + + $app->system->web_folder_protection($data['new']['document_root'], true); + + // Get the client ID + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // Remove old symlinks, if site is renamed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // remove the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + } + + // Create the symlinks for the sites + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + //* Remove symlink if target folder has been changed. + if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + } + // create the symlinks, if not exist + if(!is_link($tmp_symlink)) { + // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + if ($web_config["website_symlinks_rel"] == 'y') { + $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); + } else { + exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + } + + $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + + + // Install the Standard or Custom Error, Index and other related files + // /usr/local/ispconfig/server/conf is for the standard files + // /usr/local/ispconfig/server/conf-custom is for the custom files + // setting a local var here + + // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; + if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + + // Copy the error pages + if($data['new']['errordocs']) { + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + } + + //* Copy the web skeleton files only when there is no index.ph or index.html file yet + if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + + if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { + // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + //} + } else { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + } else { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + } + } + exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + + //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before + } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { + + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); + } // end copy error docs + + // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias + if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { + if($data['new']['hd_quota'] > 0) { + $blocks_soft = $data['new']['hd_quota'] * 1024; + $blocks_hard = $blocks_soft + 1024; + $mb_soft = $data['new']['hd_quota']; + $mb_hard = $mb_soft + 1; + } else { + $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; + } + + // get the primitive folder for document_root and the filesystem, will need it later. + $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); + $file_system = $df_output[0]; + $primitive_root = $df_output[1]; + + if($file_system == 'xfs') { + exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); + + // xfs only supports timers globally, not per user. + exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); + + unset($project_uid, $username_position, $xfs_projects); + unset($primitive_root, $df_output, $mb_hard, $mb_soft); + } else { + if($app->system->is_installed('setquota')) { + exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); + exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); + } + } + } + + if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { + // Chown and chmod the directories below the document root + $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + // The document root itself has to be owned by root in normal level and by the web owner in security level 20 + if($web_config['security_level'] == 20) { + $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } else { + $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } + } + + //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update + if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); + + //* If the security level is set to high + if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) { + + $app->system->web_folder_protection($data['new']['document_root'], false); + + //* Check if we have the new private folder and create it if nescessary + if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); + + if($web_config['security_level'] == 20) { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0711); + $app->system->chmod($data['new']['document_root'].'/webdav', 0710); + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + + // make tmp directory writable for Apache and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + $command = 'usermod'; + $command .= ' --groups sshusers'; + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + $app->system->_exec($command); + } + + //* if we have a chrooted Apache environment + if($apache_chrooted) { + $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* add the apache user to the client group in the chroot environment + $tmp_groupfile = $app->system->server_conf['group_datei']; + $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; + $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); + $app->system->server_conf['group_datei'] = $tmp_groupfile; + unset($tmp_groupfile); + } + + //* Chown all default directories + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + $app->system->chown($data['new']['document_root'].'/webdav', $username); + $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + + // If the security Level is set to medium + } else { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0755); + $app->system->chmod($data['new']['document_root'].'/webdav', 0755); + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); + + // make temp directory writable for Apache and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + $app->system->chown($data['new']['document_root'].'/webdav', $username); + $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); + } + } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && + (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { + + if($web_config['security_level'] == 20) { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } else { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } + } + + //* Protect web folders + $app->system->web_folder_protection($data['new']['document_root'], true); + + if($data['new']['type'] == 'vhost') { + // Change the ownership of the error log to the root user + if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); + $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + } + + //* Write the custom php.ini file, if custom_php_ini fieled is not empty + $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; + if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; + if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); + + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + if(trim($data['new']['fastcgi_php_version']) != ''){ + list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); + if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); + } + + //* Create custom php.ini + if(trim($data['new']['custom_php_ini']) != '') { + $has_custom_php_ini = true; + if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); + + $php_ini_content = $this->get_master_php_ini_content($data['new']); + $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini'])); + + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $php_ini_content .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); + } else { + $has_custom_php_ini = false; + if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); + } + + + //* Create the vhost config file + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('vhost.conf.master'); + + $vhost_data = $data['new']; + //unset($vhost_data['ip_address']); + $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; + $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; + $vhost_data['web_basedir'] = $web_config['website_basedir']; + $vhost_data['security_level'] = $web_config['security_level']; + $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override']; + $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; + $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; + $vhost_data['has_custom_php_ini'] = $has_custom_php_ini; + $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir); + $vhost_data['logging'] = $web_config['logging']; + + // Custom Apache directives + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $vhost_data['apache_directives'] = $snippet['snippet']; + } + } + // Make sure we only have Unix linebreaks + $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); + $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] + ); + $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); + + $app->uses('letsencrypt'); + // Check if a SSL cert exists + $tmp = $app->letsencrypt->get_website_certificate_paths($data); + $domain = $tmp['domain']; + $key_file = $tmp['key']; + $key_file2 = $tmp['key2']; + $csr_file = $tmp['csr']; + $crt_file = $tmp['crt']; + $bundle_file = $tmp['bundle']; + unset($tmp); + + $data['new']['ssl_domain'] = $domain; + $vhost_data['ssl_domain'] = $domain; + $vhost_data['ssl_crt_file'] = $crt_file; + $vhost_data['ssl_key_file'] = $key_file; + $vhost_data['ssl_bundle_file'] = $bundle_file; + + //* Generate Let's Encrypt SSL certificat + if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server + ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration + || ($data['old']['domain'] != $data['new']['domain']) // we have domain update + || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain + || $this->update_letsencrypt == true + )) { + + $success = $app->letsencrypt->request_certificates($data); + if($success) { + /* we don't need to store it. + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } else { + $data['new']['ssl_letsencrypt'] = 'n'; + if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); + } + } + + if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; + + // HTTP/2.0 ? + $vhost_data['enable_http2'] = 'n'; + if($vhost_data['enable_spdy'] == 'y'){ + // check if apache supports http_v2 + exec("2>&1 apachectl -M | grep http2_module", $tmp_output, $tmp_retval); + if($tmp_retval == 0){ + $vhost_data['enable_http2'] = 'y'; + } + unset($tmp_output, $tmp_retval); + } + + // Set SEO Redirect + if($data['new']['seo_redirect'] != ''){ + $vhost_data['seo_redirect_enabled'] = 1; + $tmp_seo_redirects = $this->get_seo_redirects($data['new']); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + foreach($tmp_seo_redirects as $key => $val){ + $vhost_data[$key] = $val; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + + $tpl->setVar($vhost_data); + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + + // Rewrite rules + $rewrite_rules = array(); + $rewrite_wildcard_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ + $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8); + $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8); + } else { + $rewrite_target = $data['new']['redirect_path']; + $rewrite_target_ssl = $data['new']['redirect_path']; + } + /* Disabled path extension + if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { + $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; + } + */ + + switch($data['new']['subdomain']) { + case 'www': + $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_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')); + break; + case '*': + $rewrite_wildcard_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')); + break; + default: + $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')); + } + } + + $server_alias = array(); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); + $alias_seo_redirects = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain']; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain']; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + switch($alias['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; + break; + case '*': + $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; + break; + default: + $server_alias[] .= $alias['domain']; + break; + } + $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); + + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + + // Rewriting + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { + if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ + $rewrite_target = 'http'.substr($alias['redirect_path'], 8); + $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8); + } else { + $rewrite_target = $alias['redirect_path']; + $rewrite_target_ssl = $alias['redirect_path']; + } + /* Disabled the path extension + if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { + $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; + } + */ + + switch($alias['subdomain']) { + case 'www': + $rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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.'.$alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + break; + case '*': + $rewrite_wildcard_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($alias['domain']), + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + break; + default: + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2)); + else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']); + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); + } + } + } + } + + //* If we have some alias records + if($server_alias) { + //* begin a new ServerAlias line after 32 alias domains to avoid apache bugs + $server_alias_str = 'ServerAlias '.$server_alias[0]; + for($n=1;$nsetVar('alias', $server_alias_str); + unset($server_alias_str); + unset($n); + } else { + $tpl->setVar('alias', ''); + } + + if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules + + if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0 || $data['new']['rewrite_to_https'] == 'y') { + $tpl->setVar('rewrite_enabled', 1); + } else { + $tpl->setVar('rewrite_enabled', 0); + } + + //$tpl->setLoop('redirects',$rewrite_rules); + + /** + * install fast-cgi starter script and add script aliasd config + * first we create the script directory if not already created, then copy over the starter script + * settings are copied over from the server ini config for now + * TODO: Create form for fastcgi configs per site. + */ + + + if ($data['new']['php'] == 'fast-cgi') { + + $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']); + $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); + + if (!is_dir($fastcgi_starter_path)) { + $app->system->mkdirpath($fastcgi_starter_path); + //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); + + + $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG); + } + + //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); + $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); + $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); + if($web_config['security_level'] == 10) { + $app->system->chmod($fastcgi_starter_path, 0755); + } else { + $app->system->chmod($fastcgi_starter_path, 0550); + } + + $fcgi_tpl = new tpl(); + $fcgi_tpl->newTemplate('php-fcgi-starter.master'); + $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion()); + $fcgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + + // Support for multiple PHP versions (FastCGI) + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_fastcgi_php = false; + if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/'; + } else { + $default_fastcgi_php = true; + } + + if($has_custom_php_ini) { + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); + } else { + if($default_fastcgi_php){ + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); + } else { + $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir)); + } + } + $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); + $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children'])); + $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests'])); + if($default_fastcgi_php){ + $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin'])); + } else { + $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable)); + } + $fcgi_tpl->setVar('security_level', intval($web_config['security_level'])); + $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain'])); + + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; + $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); + + $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab()); + unset($fcgi_tpl); + + $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); + + if($web_config['security_level'] == 10) { + $app->system->chmod($fcgi_starter_script, 0755); + } else { + $app->system->chmod($fcgi_starter_script, 0550); + } + $app->system->chown($fcgi_starter_script, $data['new']['system_user']); + $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); + + $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); + $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); + $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); + $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); + + } else { + //remove the php fastgi starter script if available + $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : ''); + if ($data['old']['php'] == 'fast-cgi') { + $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); + $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); + if($data['old']['type'] == 'vhost') { + if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); + if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path); + } else { + if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); + } + } + } + + + + /** + * PHP-FPM + */ + // Support for multiple PHP versions + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + + /** + * install cgi starter script and add script alias to config. + * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!) + * first we create the script directory if not already created, then copy over the starter script. + * TODO: we have to fetch the data from the server-settings. + */ + if ($data['new']['php'] == 'cgi') { + //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi'); + + $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; + $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''); + $cgi_config['cgi_bin'] = '/usr/bin/php-cgi'; + + $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']); + $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path); + + if (!is_dir($cgi_starter_path)) { + $app->system->mkdirpath($cgi_starter_path); + $app->system->chown($cgi_starter_path, $data['new']['system_user']); + $app->system->chgrp($cgi_starter_path, $data['new']['system_group']); + if($web_config['security_level'] == 10) { + $app->system->chmod($cgi_starter_path, 0755); + } else { + $app->system->chmod($cgi_starter_path, 0550); + } + + $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG); + } + + $cgi_tpl = new tpl(); + $cgi_tpl->newTemplate('php-cgi-starter.master'); + $cgi_tpl->setVar('apache_version', $app->system->getapacheversion()); + $cgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + + // This works because PHP "rewrites" a symlink to the physical path + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; + $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); + $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); + + // This will NOT work! + //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']); + $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']); + $cgi_tpl->setVar('security_level', $web_config['security_level']); + + $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini); + if($has_custom_php_ini) { + $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); + } else { + $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); + } + + $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab()); + unset($cgi_tpl); + + $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG); + + + if($web_config['security_level'] == 10) { + $app->system->chmod($cgi_starter_script, 0755); + } else { + $app->system->chmod($cgi_starter_script, 0550); + } + $app->system->chown($cgi_starter_script, $data['new']['system_user']); + $app->system->chgrp($cgi_starter_script, $data['new']['system_group']); + + $tpl->setVar('cgi_starter_path', $cgi_starter_path); + $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); + + } + + $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); + //* Make a backup copy of vhost file + if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~'); + + //* create empty vhost array + $vhosts = array(); + + //* Add vhost for ipv4 IP + + //* use ip-mapping for web-mirror + if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { + $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; + $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); + $data['new']['ip_address'] = $newip['destination_ip']; + unset($newip); + } + + $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80); + if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); + if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr); + + //* Add vhost for ipv4 IP with SSL + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); + if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); + $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects; + if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){ + for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); + $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); + } + + //* Add vhost for IPv6 IP + if($data['new']['ipv6_address'] != '') { + //* rewrite ipv6 on mirrors + /* chang $conf to $web_config */ + if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':', $data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':', $explode_v6); + } + } + if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::'; + $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); + if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); + if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr); + + //* Add vhost for ipv6 IP with SSL + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); + if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); + $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects; + if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){ + for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects); + $vhosts[] = $tmp_vhost_arr; + unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); + $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG); + } + } + + //* Set the vhost loop + $tpl->setLoop('vhosts', $vhosts); + + //* Write vhost file + $app->system->file_put_contents($vhost_file, $tpl->grab()); + $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + unset($tpl); + + /* + * maybe we have some webdav - user. If so, add them... + */ + $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav'); + + //* Set the symlink to enable the vhost + //* First we check if there is a old type of symlink and remove it + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); + + //* Remove old or changed symlinks + if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + } + + //* New symlink + if($data['new']['subdomain'] == '*') { + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + } else { + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + } + if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { + symlink($vhost_file, $vhost_symlink); + $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + // remove old symlink and vhost file, if domain name of the site has changed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + $app->system->unlink($vhost_file); + $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); + } + + //* Create .htaccess and .htpasswd file for website statistics + //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) { + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats'); + $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user"; + $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file); + $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755); + unset($ht_file); + //} + + if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { + if(trim($data['new']['stats_password']) != '') { + $htp_file = 'admin:'.trim($data['new']['stats_password']); + $app->system->web_folder_protection($data['new']['document_root'], false); + $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file); + $app->system->web_folder_protection($data['new']['document_root'], true); + $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755); + unset($htp_file); + } + } + + //* Create awstats configuration + if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + $this->awstats_update($data, $web_config); + } + + $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); + + if($web_config['check_apache_config'] == 'y') { + //* Test if apache starts with the new configuration file + $apache_online_status_before_restart = $this->_checkTcp('localhost', 80); + $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + + $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure + $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); + + // wait a few seconds, before we test the apache status again + $apache_online_status_after_restart = false; + sleep(2); + for($i = 0; $i < 5; $i++) { + $apache_online_status_after_restart = $this->_checkTcp('localhost', 80); + if($apache_online_status_after_restart) break; + sleep(1); + } + //* Check if apache restarted successfully if it was online before + $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) { + $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); + if(is_array($retval['output']) && !empty($retval['output'])){ + $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $retval['output'])); + } else { + // if no output is given, check again + $webserver_binary = ''; + exec('which apache2ctl apache2 httpd2 httpd apache 2>/dev/null', $webserver_check_output, $webserver_check_retval); + if($webserver_check_retval == 0){ + $webserver_binary = reset($webserver_check_output); + } + if($webserver_binary != ''){ + exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } + } + $app->system->copy($vhost_file, $vhost_file.'.err'); + if(is_file($vhost_file.'~')) { + //* Copy back the last backup file + $app->system->copy($vhost_file.'~', $vhost_file); + } else { + //* There is no backup file, so we create a empty vhost file with a warning message inside + $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); + } + if($this->ssl_certificate_changed === true) { + //* Backup the files that might have caused the error + if(is_file($key_file)){ + $app->system->copy($key_file, $key_file.'.err'); + $app->system->chmod($key_file.'.err', 0400); + } + if(is_file($key_file2)){ + $app->system->copy($key_file2, $key_file2.'.err'); + $app->system->chmod($key_file2.'.err', 0400); + } + if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); + if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); + if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err'); + + //* Restore the ~ backup files + if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); + if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); + if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); + if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); + if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file); + + $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); + } + + $app->services->restartService('httpd', 'restart'); + } + } else { + //* We do not check the apache config after changes (is faster) + if($apache_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + } + + //* The vhost is written and apache has been restarted, so we + // can reset the ssl changed var to false and cleanup some files + $this->ssl_certificate_changed = false; + + if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); + if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); + if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); + if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); + if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); + + // Remove the backup copy of the config file. + if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); + + //* Unset action to clean it for next processed vhost. + $this->action = ''; + } + + function delete($event_name, $data) { + global $app, $conf; + + // load the server configuration options + $app->uses('getconf'); + $app->uses('system'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $apache_chrooted = true; + } else { + $apache_chrooted = false; + } + + //* Remove the mounts + $log_folder = 'log'; + $web_folder = ''; + if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + if($tmp['domain'] != ''){ + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + } else { + // get log folder from /etc/fstab + /* + $bind_mounts = $app->system->file_get_contents('/etc/fstab'); + $bind_mount_lines = explode("\n", $bind_mounts); + if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ + foreach($bind_mount_lines as $bind_mount_line){ + $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); + $bind_mount_parts = explode(' ', $bind_mount_line); + if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ + if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ + $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); + } + } + } + } + */ + // we are deleting the parent domain, so we can delete everything in the log directory + $subdomain_hosts = array(); + $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ + $subdomain_hosts[] = $file; + } + } + } + } + if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ + $log_folders = array(); + foreach($subdomain_hosts as $subdomain_host){ + $log_folders[] = $log_folder.'/'.$subdomain_host; + } + } else { + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $log_folder .= '/' . $subdomain_host; + } + $web_folder = $data['old']['web_folder']; + unset($tmp); + unset($subdomain_hosts); + } + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + } + } else { + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + } + + // remove letsencrypt if it exists (renew will always fail otherwise) + + $old_domain = $data['old']['domain']; + if(substr($old_domain, 0, 2) === '*.') { + // wildcard domain not yet supported by letsencrypt! + $old_domain = substr($old_domain, 2); + } + $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; + @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); + } + + //* remove mountpoint from fstab + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + unset($log_folders); + + if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { + //* This is a alias domain or subdomain, so we have to update the website instead + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + // just run the update function + $this->update($event_name, $data); + + } else { + //* This is a website + // Deleting the vhost file, symlink and the data directory + $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + $app->system->unlink($vhost_file); + $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $docroot = escapeshellcmd($data['old']['document_root']); + if($docroot != '' && !stristr($docroot, '..')) { + if($data['old']['type'] == 'vhost') { + // this is a vhost - we delete everything in here. + exec('rm -rf '.$docroot); + } elseif(!stristr($data['old']['web_folder'], '..')) { + // this is a vhost subdomain + // IMPORTANT: do some folder checks before we delete this! + $do_delete = true; + $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times + if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); + if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); + + $path_elements = explode('/', $delete_folder); + + if($path_elements[0] == 'web' || $path_elements[0] === '') { + // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! + // we use strict check as otherwise directories named '0' may not be deleted + $do_delete = false; + } else { + // read all vhost subdomains and alias with same parent domain + $used_paths = array(); + $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); + foreach($tmp as $tmprec) { + // we normalize the folder entries because we need to compare them + $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times + if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); + if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); + + // add this path and it's parent paths to used_paths array + while(strpos($tmp_folder, '/') !== false) { + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); + } + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + } + unset($tmp); + + // loop and check if the path is still used and stop at first used one + // set do_delete to false so nothing gets deleted if the web_folder itself is still used + $do_delete = false; + while(count($path_elements) > 0) { + $tmp_folder = implode('/', $path_elements); + if(in_array($tmp_folder, $used_paths) == true) break; + + // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true + $delete_folder = $tmp_folder; + $do_delete = true; + array_pop($path_elements); + } + unset($tmp_folder); + unset($used_paths); + } + + if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); + + unset($delete_folder); + unset($path_elements); + } + } + + //remove the php fastgi starter script if available + if ($data['old']['php'] == 'fast-cgi') { + $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($fastcgi_starter_path)) { + exec('rm -rf '.$fastcgi_starter_path); + } + } else { + $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; + if (file_exists($fcgi_starter_script)) { + exec('rm -f '.$fcgi_starter_script); + } + } + } + + // remove PHP-FPM pool + if ($data['old']['php'] == 'php-fpm') { + $this->php_fpm_pool_delete($data, $web_config); + } + + //remove the php cgi starter script if available + if ($data['old']['php'] == 'cgi') { + // TODO: fetch the date from the server-settings + $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; + + $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($cgi_starter_path)) { + exec('rm -rf '.$cgi_starter_path); + } + } else { + $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; + if (file_exists($cgi_starter_script)) { + exec('rm -f '.$cgi_starter_script); + } + } + } + + $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); + + // Delete the symlinks for the sites + $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // delete the symlink + if(is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + // end removing symlinks + } + + // Delete the log file directory + $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); + if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); + $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost') { + //delete the web user + $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; + $command .= ' '.escapeshellcmd($data['old']['system_user']); + exec($command); + if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + } + + //* Remove the awstats configuration file + if($data['old']['stats_type'] == 'awstats') { + $this->awstats_delete($data, $web_config); + } + + if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $app->system->web_folder_protection($parent_web_document_root, true); + } + + if($apache_chrooted) { + $app->services->restartServiceDelayed('httpd', 'restart'); + } else { + // request a httpd reload when all records have been processed + $app->services->restartServiceDelayed('httpd', 'reload'); + } + + //* Delete the web-backups + if($data['old']['type'] == 'vhost') { + $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); + $backup_dir = $server_config['backup_dir']; + $mount_backup = true; + if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { + //* mount backup directory, if necessary + if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; + + if($mount_backup){ + $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; + //** do not use rm -rf $web_backup_dir because database(s) may exits + exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); + //* cleanup database + $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; + $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); + if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); + + $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); + } + } + } + } + if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); } - //* This function is called during ispconfig installation to determine - // if a symlink shall be created for this plugin. - function onInstall() { - global $conf; + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered + function server_ip($event_name, $data) { + global $app, $conf; + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('apache_ispconfig.conf.master'); + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('logging', $web_config['logging']); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']); + + $records_out= array(); + if(is_array($records)) { + foreach($records as $rec) { + if($rec['ip_type'] == 'IPv6') { + $ip_address = '['.$rec['ip_address'].']'; + } else { + $ip_address = $rec['ip_address']; + } + $ports = explode(',', $rec['virtualhost_port']); + if(is_array($ports)) { + foreach($ports as $port) { + $port = intval($port); + if($port > 0 && $port < 65536 && $ip_address != '') { + $records_out[] = array('ip_address' => $ip_address, 'port' => $port); + } + } + } + } + } + + + if(count($records_out) > 0) { + $tpl->setLoop('ip_adresses', $records_out); + } + + $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf'); + $app->system->file_put_contents($vhost_file, $tpl->grab()); + $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG); + unset($tpl); + + } + + //* Create or update the .htaccess folder protection + function web_folder_user($event_name, $data) { + global $app, $conf; + + $app->uses('system'); + + if($event_name == 'web_folder_user_delete') { + $folder_id = $data['old']['web_folder_id']; + } else { + $folder_id = $data['new']['web_folder_id']; + } + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; - if($conf['services']['web'] == true) { - return true; - } else { + //* Check if the resulting path is inside the docroot + if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { + $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); return false; } - } + //* Create the folder path, if it does not exist + if(!is_dir($folder_path)) { + $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); + } + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + $app->system->touch($folder_path.'.htpasswd'); + $app->system->chmod($folder_path.'.htpasswd', 0751); + $app->system->chown($folder_path.'.htpasswd', $website['system_user']); + $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); + $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } - /* - This function is called when the plugin is loaded - */ + if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } - function onLoad() { - global $app; + //* Add or remove the user from .htpasswd file + if($event_name == 'web_folder_user_delete') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } else { + if($data['new']['active'] == 'y') { + $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); + $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); + } + } - /* - Register for the events - */ - $app->plugin_webserver_base->registerEvents('apache'); - } - // Handle php.ini changes - function php_ini_changed($event_name, $data) { - global $app; + //* Create the .htaccess file + //if(!is_file($folder_path.'.htaccess')) { + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; + $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker; - $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'apache'); + if(file_exists($folder_path.'.htaccess')) { + $old_content = $app->system->file_get_contents($folder_path.'.htaccess'); - } + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { + $ht_file = str_replace($matches[0], $ht_file, $old_content); + } else { + $ht_file .= $old_content; + } + } + unset($old_content); - // Handle the creation of SSL certificates - function ssl($event_name, $data) { - global $app; + $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); + $app->system->chmod($folder_path.'.htaccess', 0751); + $app->system->chown($folder_path.'.htaccess', $website['system_user']); + $app->system->chgrp($folder_path.'.htaccess', $website['system_group']); + $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + //} - $app->plugin_webserver_base->eventSsl($event_name, $data, 'apache'); } + //* Remove .htaccess and .htpasswd file, when folder protection is removed + function web_folder_delete($event_name, $data) { + global $app, $conf; - function insert($event_name, $data) { - $this->action = 'insert'; - // just run the update function - $this->update($event_name, $data); - } + $folder_id = $data['old']['web_folder_id']; + $folder = $data['old']; + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - function update($event_name, $data) { - global $app; + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } - if($this->action != 'insert') $this->action = 'update'; + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - $app->plugins_webserver_base->eventUpdate($event_name, $data, 'apache'); + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; - //* Unset action to clean it for next processed vhost. - $this->action = ''; - } + //* Check if the resulting path is inside the docroot + if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } - function delete($event_name, $data) { - global $app; + //* Remove .htpasswd file + if(is_file($folder_path.'.htpasswd')) { + $app->system->unlink($folder_path.'.htpasswd'); + $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } - $app->plugin_webserver_base->eventDelete($event_name, $data, 'apache'); - } + //* Remove .htaccess file + if(is_file($folder_path.'.htaccess')) { + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; - //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered - function server_ip($event_name, $data) { - global $app; + $ht_file = $app->system->file_get_contents($folder_path.'.htaccess'); - $app->plugin_webserver_base->eventServerIp($event_name, $data, 'apache'); + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + if(trim($ht_file) == '') { + $app->system->unlink($folder_path.'.htaccess'); + $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } } - //* Create or update the .htaccess folder protection - function web_folder_user($event_name, $data) { - global $app; + //* Update folder protection, when path has been changed + function web_folder_update($event_name, $data) { + global $app, $conf; - $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'apache'); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - } + if(!is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } - //* Remove .htaccess and .htpasswd file, when folder protection is removed - function web_folder_delete($event_name, $data) { - global $app; + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'apache'); - } + //* Get the folder path. + if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); + if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); + $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); + if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; + + if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); + if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); + $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); + if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { + $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { + $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + + //* Check if the resulting path is inside the docroot + if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); + + $begin_marker = '### ISPConfig folder protection begin ###'; + $end_marker = "### ISPConfig folder protection end ###\n\n"; + + if($data['old']['path'] != $data['new']['path']) { + + + //* move .htpasswd file + if(is_file($old_folder_path.'.htpasswd')) { + $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); + $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + //* delete old .htaccess file + if(is_file($old_folder_path.'.htaccess')) { + $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess'); + + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + + if(trim($ht_file) == '') { + $app->system->unlink($old_folder_path.'.htaccess'); + $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } + + } + + //* Create the .htaccess file + if($data['new']['active'] == 'y') { + $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + + if(file_exists($new_folder_path.'.htaccess')) { + $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess'); + + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { + $ht_file = str_replace($matches[0], $ht_file, $old_content); + } else { + $ht_file .= $old_content; + } + } + + $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); + $app->system->chmod($new_folder_path.'.htaccess', 0751); + $app->system->chown($new_folder_path.'.htaccess', $website['system_user']); + $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']); + $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + $app->system->touch($new_folder_path.'.htpasswd'); + $app->system->chmod($new_folder_path.'.htpasswd', 0751); + $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']); + $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']); + $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + } + + //* Remove .htaccess file + if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) { + $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess'); + + if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { + $ht_file = str_replace($matches[0], '', $ht_file); + } else { + $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); + } + + if(trim($ht_file) == '') { + $app->system->unlink($new_folder_path.'.htaccess'); + $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } else { + $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); + $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); + } + } - //* Update folder protection, when path has been changed - function web_folder_update($event_name, $data) { - global $app; - $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'apache'); } public function ftp_user_delete($event_name, $data) { - global $app; + global $app, $conf; $ftpquota_file = $data['old']['dir'].'/.ftpquota'; if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); + } + + /** * This function is called when a Webdav-User is inserted, updated or deleted. * @@ -177,10 +2602,10 @@ class apache2_plugin { /* Check if this is a chrooted setup */ if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $is_chrooted = true; + $apache_chrooted = true; $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); } else { - $is_chrooted = false; + $apache_chrooted = false; } //* We dont want to have relative paths here @@ -238,12 +2663,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($is_chrooted) { + if($apache_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -270,12 +2695,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($is_chrooted) { + if($apache_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -292,7 +2717,7 @@ class apache2_plugin { * @param string $filename The name of the digest-file * @param string $username The name of the webdav-user * @param string $authname The name of the realm - * @param string $pwdhash The password-hash of the user + * @param string $pwd The password-hash of the user */ private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) { global $app; @@ -340,11 +2765,475 @@ class apache2_plugin { } } - function client_delete($event_name, $data) { + /** + * This function patches the vhost-file and adds all webdav - user. + * This function is written, because the creation of the vhost - file is sophisticated and + * i don't want to make it more "heavy" by also adding this code too... + * @author Oliver Vogel + * @param string $fileName The Name of the .vhost-File (path included) + * @param string $webdavRoot The root of the webdav-folder + */ + private function _patchVhostWebdav($fileName, $webdavRoot) { + global $app; + $in = fopen($fileName, 'r'); + $output = ''; + $inWebdavSection = false; + //* read line by line and search for the username and authname + while ($line = fgets($in)) { + //* is the "replace-comment" found... + if (trim($line) == '# WEBDAV BEGIN') { + //* The begin of the webdav - section is found, so ignore all lines til the end is found + $inWebdavSection = true; + $output .= "# WEBDAV BEGIN\n"; + //* add all the webdav-dirs to the webdav-section + $files = @scandir($webdavRoot); + if(is_array($files)) { + foreach($files as $file) { + if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) { + //* found a htdigest - file, so add it to webdav + $fn = substr($file, 0, strlen($file) - strlen('.htdigest')); + $output .= "\n"; + $output .= "Alias /webdav/$fn $webdavRoot/$fn\n"; + $output .= "\n"; + $output .= "DAV On\n"; + $output .= "BrowserMatch MSIE AuthDigestEnableQueryStringHack=On\n"; + $output .= "AuthType Digest\n"; + if($fn != '' && $fn != '/') { + $output .= "AuthName \"" . $fn . "\"\n"; + } else { + $output .= "AuthName \"Restricted Area\"\n"; + } + $output .= "AuthUserFile $webdavRoot/$file\n"; + $output .= "Require valid-user\n"; + $output .= "Options +Indexes\n"; + if($app->system->getapacheversion()<=2.2) + $output .= "Order allow,deny\nAllow from all\n"; + $output .= "\n"; + } + } + } + } + //* is the "replace-comment-end" found... + if (trim($line) == '# WEBDAV END') { + //* The end of the webdav - section is found, so stop ignoring + $inWebdavSection = false; + } + //* Write the line to the output, if it is not in the section + if (!$inWebdavSection) { + $output .= $line; + } + } + fclose($in); + //* Now lets write the new file + $app->system->file_put_contents($fileName, $output); + } + + //* Update the awstats configuration file + private function awstats_update ($data, $web_config) { + global $app; + + $web_folder = $data['new']['web_folder']; + if($data['new']['type'] == 'vhost') $web_folder = 'web'; + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); + if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + } + + $content = ''; + if (is_file($awstats_conf_dir."/awstats.conf")) { + $include_file = $awstats_conf_dir."/awstats.conf"; + } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { + $include_file = $awstats_conf_dir."/awstats.model.conf"; + } + $content .= "Include \"".$include_file."\"\n"; + $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; + $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; + $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; + + if (isset($include_file)) { + $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); + $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); + } else { + $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); + } + } + + if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); + if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { + $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } else { + $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } + } + + //* Delete the awstats configuration file + private function awstats_delete ($data, $web_config) { global $app; - $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'apache'); + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); + } + } + + //* Update the PHP-FPM pool configuration file + private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { + global $app, $conf; + $pool_dir = trim($pool_dir); + //$reload = false; + + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + if($data['new']['php'] != 'php-fpm'){ + if(@is_file($pool_dir.$pool_name.'.conf')){ + $app->system->unlink($pool_dir.$pool_name.'.conf'); + //$reload = true; + } + if($data['old']['php'] == 'php-fpm'){ + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + //if($reload == true) $app->services->restartService('php-fpm','reload'); + return; + } + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate('php_fpm_pool.conf.master'); + $tpl->setVar('apache_version', $app->system->getapacheversion()); + $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_listen_mode', '0660'); + + $tpl->setVar('fpm_pool', $pool_name); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + $tpl->setVar('fpm_user', $data['new']['system_user']); + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('fpm_listen_user', $data['new']['system_user']); + $tpl->setVar('fpm_listen_group', $web_config['group']); + $tpl->setVar('fpm_domain', $data['new']['domain']); + $tpl->setVar('pm', $data['new']['pm']); + $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); + $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); + $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); + $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); + $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); + $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); + $tpl->setVar('document_root', $data['new']['document_root']); + $tpl->setVar('security_level', $web_config['security_level']); + $tpl->setVar('domain', $data['new']['domain']); + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); + $tpl->setVar('php_open_basedir', $php_open_basedir); + if($php_open_basedir != ''){ + $tpl->setVar('enable_php_open_basedir', ''); + } else { + $tpl->setVar('enable_php_open_basedir', ';'); + } + + // Custom php.ini settings + $final_php_ini_settings = array(); + $custom_php_ini_settings = trim($data['new']['custom_php_ini']); + + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $custom_php_ini_settings .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $custom_session_save_path = false; + if($custom_php_ini_settings != ''){ + // Make sure we only have Unix linebreaks + $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); + $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); + $ini_settings = explode("\n", $custom_php_ini_settings); + if(is_array($ini_settings) && !empty($ini_settings)){ + foreach($ini_settings as $ini_setting){ + $ini_setting = trim($ini_setting); + if(substr($ini_setting, 0, 1) == ';') continue; + if(substr($ini_setting, 0, 1) == '#') continue; + if(substr($ini_setting, 0, 2) == '//') continue; + list($key, $value) = explode('=', $ini_setting, 2); + $value = trim($value); + if($value != ''){ + $key = trim($key); + if($key == 'session.save_path') $custom_session_save_path = true; + switch (strtolower($value)) { + case '0': + // PHP-FPM might complain about invalid boolean value if you use 0 + $value = 'off'; + case '1': + case 'on': + case 'off': + case 'true': + case 'false': + case 'yes': + case 'no': + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); + break; + default: + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); + } + } + } + } + } + + $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); + + $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); + + $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); + $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + unset($tpl); + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $conf["server_id"]); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + + //$reload = true; + + //if($reload == true) $app->services->restartService('php-fpm','reload'); + } + + //* Delete the PHP-FPM pool configuration file + private function php_fpm_pool_delete ($data, $web_config) { + global $app, $conf; + + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['old']['domain_id']; + + if ( @is_file($pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + + //$app->services->restartService('php-fpm','reload'); + } + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $data['old']['server_id']); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + function client_delete($event_name, $data) { + global $app, $conf; + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + $client_id = intval($data['old']['client_id']); + if($client_id > 0) { + + $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; + if(is_dir($client_dir) && !stristr($client_dir, '..')) { + // remove symlinks from $client_dir + $files = array_diff(scandir($client_dir), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_link($client_dir.'/'.$file)){ + unlink($client_dir.'/'.$file); + $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); + } + } + } + + @rmdir($client_dir); + $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); + } + + if($app->system->is_group('client'.$client_id)){ + $app->system->_exec('groupdel client'.$client_id); + $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); + } + } + + } + + private function _checkTcp ($host, $port) { + + $fp = @fsockopen($host, $port, $errno, $errstr, 2); + + if ($fp) { + fclose($fp); + return true; + } else { + return false; + } + } + + private function _rewrite_quote($string) { + return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); + } + + private function _is_url($string) { + return preg_match('/^(f|ht)tp(s)?:\/\//i', $string); } + private function get_seo_redirects($web, $prefix = ''){ + $seo_redirects = array(); + + if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; + + if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){ + $domain = str_replace('.', '\.', $web['domain']); + if($web['seo_redirect'] == 'non_www_to_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = ''; + } + if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain.'|.*\.'.$domain.'(? diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 3a7f569c2..5024a3bff 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -30,19 +30,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class nginx_plugin { - var $plugin_name; - var $class_name; + var $plugin_name = 'nginx_plugin'; + var $class_name = 'nginx_plugin'; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; - public function __construct() { - $this->plugin_name = get_class($this); - $this->class_name = get_class($this); - } - //* This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. function onInstall() { @@ -67,93 +62,3096 @@ class nginx_plugin { /* Register for the events */ - $app->plugin_webserver_base->registerEvents('nginx'); - } + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - // Handle php.ini changes - function php_ini_changed($event_name, $data) { - global $app; + $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); + $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); + $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); + + $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); + + /* + $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav'); + $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav'); + $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav'); + */ - $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'nginx'); + $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + + $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); } // Handle the creation of SSL certificates function ssl($event_name, $data) { - global $app; + global $app, $conf; + + $app->uses('system'); + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) + $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); + + //* Only vhosts can have a ssl cert + if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; + + // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); + if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; + $key_file = $ssl_dir.'/'.$domain.'.key'; + $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + + //* Create a SSL Certificate, but only if this is not a mirror server. + if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { + + $this->ssl_certificate_changed = true; + + //* Rename files if they exist + if(file_exists($key_file)){ + $app->system->rename($key_file, $key_file.'.bak'); + $app->system->chmod($key_file.'.bak', 0400); + } + if(file_exists($key_file2)){ + $app->system->rename($key_file2, $key_file2.'.bak'); + $app->system->chmod($key_file2.'.bak', 0400); + } + if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); + if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); + + $rand_file = $ssl_dir.'/random_file'; + $rand_data = md5(uniqid(microtime(), 1)); + for($i=0; $i<1000; $i++) { + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + $rand_data .= md5(uniqid(microtime(), 1)); + } + $app->system->file_put_contents($rand_file, $rand_data); + + $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); + + $ssl_cnf = " RANDFILE = $rand_file + + [ req ] + default_bits = 2048 + default_md = sha256 + default_keyfile = keyfile.pem + distinguished_name = req_distinguished_name + attributes = req_attributes + prompt = no + output_password = $ssl_password + + [ req_distinguished_name ] + C = ".trim($data['new']['ssl_country'])." + " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " + " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." + " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." + " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." + CN = $domain + emailAddress = webmaster@".$data['new']['domain']." + + [ req_attributes ] + ";//challengePassword = A challenge password"; + + $ssl_cnf_file = $ssl_dir.'/openssl.conf'; + $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); + + $rand_file = escapeshellcmd($rand_file); + $key_file2 = escapeshellcmd($key_file2); + $openssl_cmd_key_file2 = $key_file2; + if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate + $key_file = escapeshellcmd($key_file); + $openssl_cmd_key_file = $key_file; + if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate + $ssl_days = 3650; + $csr_file = escapeshellcmd($csr_file); + $openssl_cmd_csr_file = $csr_file; + if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate + $config_file = escapeshellcmd($ssl_cnf_file); + $crt_file = escapeshellcmd($crt_file); + $openssl_cmd_crt_file = $crt_file; + if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate + + if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { + + exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); + exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); + exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); + + if(file_exists($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); + $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); + }; + if (@filesize($crt_file)==0 || !file_exists($crt_file)){ + exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); + $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + }; + + } + + $app->system->chmod($key_file2, 0400); + $app->system->chmod($key_file, 0400); + @$app->system->unlink($config_file); + @$app->system->unlink($rand_file); + $ssl_request = $app->system->file_get_contents($csr_file); + $ssl_cert = $app->system->file_get_contents($crt_file); + $ssl_key = $app->system->file_get_contents($key_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + + //* Check that the SSL key is not password protected + if($data["new"]["ssl_action"] == 'save') { + if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* and check that SSL cert does not contain subdomain of domain acme.invalid + if($data["new"]["ssl_action"] == 'save') { + $tmp = array(); + $crt_data = ''; + exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); + $crt_data = implode("\n",$tmp); + if(stristr($crt_data,'.acme.invalid')) { + $data["new"]["ssl_action"] = ''; + + $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); + $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } + } + + //* Save a SSL certificate to disk + if($data["new"]["ssl_action"] == 'save') { + $this->ssl_certificate_changed = true; + + //* Backup files + if(file_exists($key_file)){ + $app->system->copy($key_file, $key_file.'~'); + $app->system->chmod($key_file.'~', 0400); + } + if(file_exists($key_file2)){ + $app->system->copy($key_file2, $key_file2.'~'); + $app->system->chmod($key_file2.'~', 0400); + } + if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); + if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); + + //* Write new ssl files + if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); + if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); + if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); + $app->system->chmod($key_file, 0400); + + // for nginx, bundle files have to be appended to the certificate file + if(trim($data["new"]["ssl_bundle"]) != ''){ + if(file_exists($crt_file)){ + $crt_file_contents = trim($app->system->file_get_contents($crt_file)); + } else { + $crt_file_contents = ''; + } + if($crt_file_contents != '') $crt_file_contents .= "\n"; + $crt_file_contents .= $data["new"]["ssl_bundle"]; + $app->system->file_put_contents($crt_file, $app->file->unix_nl($crt_file_contents)); + unset($crt_file_contents); + } + + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } + + //* Delete a SSL certificate + if($data['new']['ssl_action'] == 'del') { + if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) + { + exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); + $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); + }; + $app->system->unlink($csr_file); + $app->system->unlink($crt_file); + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); + $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); + } - $app->plugin_webserver_base->eventSsl($event_name, $data, 'nginx'); } function insert($event_name, $data) { + global $app, $conf; + $this->action = 'insert'; // just run the update function $this->update($event_name, $data); + + } function update($event_name, $data) { - global $app; + global $app, $conf; + + //* Check if the apache plugin is enabled + if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { + $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN); + return 0; + } if($this->action != 'insert') $this->action = 'update'; - $app->plugins_webserver_base->eventUpdate($event_name, $data, 'nginx'); + if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { + + $old_parent_domain_id = intval($data['old']['parent_domain_id']); + $new_parent_domain_id = intval($data['new']['parent_domain_id']); + + // If the parent_domain_id has been changed, we will have to update the old site as well. + if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update($event_name, $data); + } + + // This is not a vhost, so we need to update the parent record instead. + $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + } + + // load the server configuration options + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $nginx_chrooted = true; + $app->log('Info: nginx is chrooted.', LOGLEVEL_DEBUG); + } else { + $nginx_chrooted = false; + } + + if($data['new']['document_root'] == '') { + if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); + return 0; + } + if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false + || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { + $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); + return 0; + } + if(trim($data['new']['domain']) == '') { + $app->log('domain is empty', LOGLEVEL_WARN); + return 0; + } + + $web_folder = 'web'; + $log_folder = 'log'; + $old_web_folder = 'web'; + $old_log_folder = 'log'; + if($data['new']['type'] == 'vhost'){ + if($data['new']['web_folder'] != ''){ + if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); + if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); + } + $web_folder .= '/'.$data['new']['web_folder']; + + if($data['old']['web_folder'] != ''){ + if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1); + if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1); + } + $old_web_folder .= '/'.$data['old']['web_folder']; + } + if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + // new one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; + $web_folder = $data['new']['web_folder']; + $log_folder .= '/' . $subdomain_host; + unset($tmp); + + if(isset($data['old']['parent_domain_id'])) { + // old one + $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $old_web_folder = $data['old']['web_folder']; + $old_log_folder .= '/' . $subdomain_host; + unset($tmp); + } + } + + // Create group and user, if not exist + $app->uses('system'); + + if($web_config['connect_userid_to_webid'] == 'y') { + //* Calculate the uid and gid + $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); + $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); + $fixed_uid_param = '--uid '.$fixed_uid_gid; + $fixed_gid_param = '--gid '.$fixed_uid_gid; + + //* Check if a ispconfigend user and group exists and create them + if(!$app->system->is_group('ispconfigend')) { + exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + if(!$app->system->is_user('ispconfigend')) { + exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); + } + } else { + $fixed_uid_param = ''; + $fixed_gid_param = ''; + } + + $groupname = escapeshellcmd($data['new']['system_group']); + if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { + exec('groupadd '.$fixed_gid_param.' '.$groupname); + if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); + $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); + } + + $username = escapeshellcmd($data['new']['system_user']); + if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); + } else { + exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); + } + $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); + } + + //* If the client of the site has been changed, we have a change of the document root + if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { + + //* Get the old client ID + $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $old_client_id = intval($old_client['client_id']); + unset($old_client); + + //* Remove the old symlinks + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // create the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { + //* Move the site data + $tmp_docroot = explode('/', $data['new']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $new_dir = implode('/', $tmp_docroot); + + $tmp_docroot = explode('/', $data['old']['document_root']); + unset($tmp_docroot[count($tmp_docroot)-1]); + $old_dir = implode('/', $tmp_docroot); + + //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path + if(@is_dir($data['new']['document_root'])) { + $app->system->web_folder_protection($data['new']['document_root'], false); + $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); + $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); + } + + //* Unmount the old log directory bfore we move the log dir + exec('umount '.escapeshellcmd($old_dir.'/log')); + + //* Create new base directory, if it does not exist yet + if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); + $app->system->web_folder_protection($data['old']['document_root'], false); + exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); + //$app->system->rename($data['old']['document_root'],$new_dir); + $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); + + // Handle the change in php_open_basedir + $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); + + //* Change the owner of the website files to the new website owner + exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); + + //* Change the home directory and group of the website user + $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; + $command .= ' --home '.escapeshellcmd($data['new']['document_root']); + $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + exec($command); + } + + if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* Change the log mount + /* + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; + $app->system->removeLine('/etc/fstab', $fstab_line); + */ + + $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + + if($web_config['network_filesystem'] == 'y') { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); + } + + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + + } + + //print_r($data); + + // Check if the directories are there and create them if necessary. + $app->system->web_folder_protection($data['new']['document_root'], false); + + if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); + if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); + 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); + 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); + + if(!is_dir($data['new']['document_root'].'/.ssh')) { + $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); + $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); + $app->system->chown($data['new']['document_root'].'/.ssh', $username); + $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); + } + + //* Create the new private directory + if(!is_dir($data['new']['document_root'].'/private')) { + $app->system->mkdirpath($data['new']['document_root'].'/private'); + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + } + + + // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); + if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); + + //* remove old log mount + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + + //* Unmount log directory + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); + } + + //* Create the log dir if nescessary and mount it + if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { + if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); + if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); + $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); + //* add mountpoint to fstab + $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; + $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; + $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); + } + + $app->system->web_folder_protection($data['new']['document_root'], true); + + // Get the client ID + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // Remove old symlinks, if site is renamed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // remove the symlinks, if not exist + if(is_link($tmp_symlink)) { + exec('rm -f '.escapeshellcmd($tmp_symlink)); + $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + } + + // Create the symlinks for the sites + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + //* Remove symlink if target folder has been changed. + if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + } + // create the symlinks, if not exist + if(!is_link($tmp_symlink)) { + // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + if ($web_config["website_symlinks_rel"] == 'y') { + $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); + } else { + exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); + } + + $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + + + + // Install the Standard or Custom Error, Index and other related files + // /usr/local/ispconfig/server/conf is for the standard files + // /usr/local/ispconfig/server/conf-custom is for the custom files + // setting a local var here + + // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; + if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + + // Copy the error pages + if($data['new']['errordocs']) { + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + } + + //* Copy the web skeleton files only when there is no index.ph or index.html file yet + if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + + if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { + // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + //} + } else { + if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + } else { + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); + if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ + if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + } + } + } + exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); + + //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before + } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { + + $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; + if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + else { + if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { + exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); + } + else { + exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); + } + } + exec('chmod -R a+r '.$error_page_path); + exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); + } // end copy error docs + + // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias + if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { + if($data['new']['hd_quota'] > 0) { + $blocks_soft = $data['new']['hd_quota'] * 1024; + $blocks_hard = $blocks_soft + 1024; + $mb_soft = $data['new']['hd_quota']; + $mb_hard = $mb_soft + 1; + } else { + $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; + } + + // get the primitive folder for document_root and the filesystem, will need it later. + $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); + $file_system = $df_output[0]; + $primitive_root = $df_output[1]; + + if($file_system == 'xfs') { + exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); + + // xfs only supports timers globally, not per user. + exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); + + unset($project_uid, $username_position, $xfs_projects); + unset($primitive_root, $df_output, $mb_hard, $mb_soft); + } else { + if($app->system->is_installed('setquota')) { + exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); + exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); + } + } + } + + if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { + // Chown and chmod the directories below the document root + $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + // The document root itself has to be owned by root in normal level and by the web owner in security level 20 + if($web_config['security_level'] == 20) { + $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } else { + $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); + } + } + + //* add the nginx user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update + if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); + + //* If the security level is set to high + if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) { + + $app->system->web_folder_protection($data['new']['document_root'], false); + + //* Check if we have the new private folder and create it if nescessary + if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); + + if($web_config['security_level'] == 20) { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0751); + //$app->system->chmod($data['new']['document_root'].'/webdav',0710); + $app->system->chmod($data['new']['document_root'].'/private', 0710); + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751); + + // make tmp directory writable for nginx and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + if($web_config['add_web_users_to_sshusers_group'] == 'y') { + $command = 'usermod'; + $command .= ' --groups sshusers'; + $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; + $app->system->_exec($command); + } + + //* if we have a chrooted nginx environment + if($nginx_chrooted) { + $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + + //* add the nginx user to the client group in the chroot environment + $tmp_groupfile = $app->system->server_conf['group_datei']; + $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; + $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); + $app->system->server_conf['group_datei'] = $tmp_groupfile; + unset($tmp_groupfile); + } + + //* Chown all default directories + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + //$app->system->chown($data['new']['document_root'].'/webdav',$username); + //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); + $app->system->chown($data['new']['document_root'].'/private', $username); + $app->system->chgrp($data['new']['document_root'].'/private', $groupname); + + if($web_folder != 'web'){ + $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); + } + + // If the security Level is set to medium + } else { + + $app->system->chmod($data['new']['document_root'], 0755); + $app->system->chmod($data['new']['document_root'].'/web', 0755); + //$app->system->chmod($data['new']['document_root'].'/webdav',0755); + $app->system->chmod($data['new']['document_root'].'/ssl', 0755); + $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); + if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755); + + // make temp directory writable for nginx and the website users + $app->system->chmod($data['new']['document_root'].'/tmp', 0770); + + // Set Log directory to 755 to make the logs accessible by the FTP user + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); + } + + $app->system->chown($data['new']['document_root'], 'root'); + $app->system->chgrp($data['new']['document_root'], 'root'); + $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); + $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); + if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { + $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); + $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); + } + + $app->system->chown($data['new']['document_root'].'/ssl', 'root'); + $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); + $app->system->chown($data['new']['document_root'].'/tmp', $username); + $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); + $app->system->chown($data['new']['document_root'].'/web', $username); + $app->system->chgrp($data['new']['document_root'].'/web', $groupname); + $app->system->chown($data['new']['document_root'].'/web/error', $username); + $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/web/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); + } + //$app->system->chown($data['new']['document_root'].'/webdav',$username); + //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); + + if($web_folder != 'web'){ + $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); + } + } + } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && + (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { + + if($web_config['security_level'] == 20) { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } else { + $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); + $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); + if($data['new']['stats_type'] != '') { + $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); + } + } + } + + //* Protect web folders + $app->system->web_folder_protection($data['new']['document_root'], true); + + if($data['new']['type'] == 'vhost') { + // Change the ownership of the error log to the root user + if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); + $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); + } + + + //* Create the vhost config file + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('nginx_vhost.conf.master'); + + // IPv4 + if($data['new']['ip_address'] == '') $data['new']['ip_address'] = '*'; + + //* use ip-mapping for web-mirror + if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { + $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; + $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); + $data['new']['ip_address'] = $newip['destination_ip']; + unset($newip); + } + + $vhost_data = $data['new']; + + //unset($vhost_data['ip_address']); + $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; + $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; + $vhost_data['web_basedir'] = $web_config['website_basedir']; + + // IPv6 + if($data['new']['ipv6_address'] != ''){ + $tpl->setVar('ipv6_enabled', 1); + if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { + if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { + $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']); + $explode_v6=explode(':', $data['new']['ipv6_address']); + + for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { + $explode_v6[$i] = $explode_v6prefix[$i]; + } + $data['new']['ipv6_address'] = implode(':', $explode_v6); + $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; + } + } + } + + // PHP-FPM + // Support for multiple PHP versions + /* + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + */ + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_chroot'] == 'y'){ + $php_fpm_chroot = 1; + $php_fpm_nochroot = 0; + } else { + $php_fpm_chroot = 0; + $php_fpm_nochroot = 1; + } + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); + $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); + $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; + + // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. + if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; + + // Custom rewrite rules + /* + $final_rewrite_rules = array(); + $custom_rewrite_rules = $data['new']['rewrite_rules']; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + */ + + // Custom rewrite rules + $final_rewrite_rules = array(); + + if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { + $custom_rewrite_rules = trim($data['new']['rewrite_rules']); + $custom_rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + // ignore comments + if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // empty lines + if(trim($custom_rewrite_rule_line) == ''){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // closing curly bracket + if(trim($custom_rewrite_rule_line) == '}'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level -= 1; + continue; + } + $custom_rewrites_are_valid = false; + break; + } + } + if(!$custom_rewrites_are_valid || $if_level != 0){ + $final_rewrite_rules = array(); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + + // Custom nginx directives + $final_nginx_directives = array(); + if($data['new']['enable_pagespeed'] == 'y'){ + // if PageSpeed is already enabled, don't add configuration again + if(stripos($nginx_directives, 'pagespeed') !== false){ + $vhost_data['enable_pagespeed'] = false; + } else { + $vhost_data['enable_pagespeed'] = true; + } + } else { + $vhost_data['enable_pagespeed'] = false; + } + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $nginx_directives = $snippet['snippet']; + } else { + $nginx_directives = $data['new']['nginx_directives']; + } +/* + if($data['new']['enable_pagespeed'] == 'y'){ + // if PageSpeed is already enabled, don't add configuration again + if(stripos($nginx_directives, 'pagespeed') !== false){ + $vhost_data['enable_pagespeed'] = false; + } else { + $vhost_data['enable_pagespeed'] = true; + } + } else { + $vhost_data['enable_pagespeed'] = false; + } +*/ + } else { + $nginx_directives = $data['new']['nginx_directives']; +// $vhost_data['enable_pagespeed'] = false; + } + + // folder_directive_snippets + if(trim($data['new']['folder_directive_snippets']) != ''){ + $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); + $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); + + if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ + foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ + list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); + + $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); + $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); + + if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ + if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; + if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); + + $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); + if(isset($master_snippet['snippet'])){ + $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); + $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); + $nginx_directives .= "\n\n".$master_snippet['snippet']; + + // create folder it it does not exist + if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ + $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); + $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); + } + } + } + } + } + } + + // use vLib for template logic + if(trim($nginx_directives) != '') { + $nginx_directives_new = ''; + $ngx_conf_tpl = new tpl(); + $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); + file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); + $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); + $ngx_conf_tpl->setVar('use_tcp', $use_tcp); + $ngx_conf_tpl->setVar('use_socket', $use_socket); + $ngx_conf_tpl->setVar('fpm_socket', $fpm_socket); + $ngx_conf_tpl->setVar($vhost_data); + $nginx_directives_new = $ngx_conf_tpl->grab(); + if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); + if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; + unset($nginx_directives_new); + } + + // Make sure we only have Unix linebreaks + $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); + $nginx_directives = str_replace("\r", "\n", $nginx_directives); + $nginx_directive_lines = explode("\n", $nginx_directives); + if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], + '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';' + ); + foreach($nginx_directive_lines as $nginx_directive_line){ + $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); + } + } + $tpl->setLoop('nginx_directives', $final_nginx_directives); + + $app->uses('letsencrypt'); + // Check if a SSL cert exists + $tmp = $app->letsencrypt->get_website_certificate_paths($data); + $domain = $tmp['domain']; + $key_file = $tmp['key']; + $key_file2 = $tmp['key2']; + $csr_file = $tmp['csr']; + $crt_file = $tmp['crt']; + $bundle_file = $tmp['bundle']; + unset($tmp); + + $data['new']['ssl_domain'] = $domain; + $vhost_data['ssl_domain'] = $domain; + $vhost_data['ssl_crt_file'] = $crt_file; + $vhost_data['ssl_key_file'] = $key_file; + $vhost_data['ssl_bundle_file'] = $bundle_file; + + //* Generate Let's Encrypt SSL certificat + if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server + ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration + || ($data['old']['domain'] != $data['new']['domain']) // we have domain update + || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain + || $this->update_letsencrypt == true + )) { + + $success = $app->letsencrypt->request_certificates($data, 'nginx'); + if($success) { + /* we don't need to store it. + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain_id = ?", $data['new']['domain']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); + $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); + } else { + $data['new']['ssl_letsencrypt'] = 'n'; + if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; + /* Update the DB of the (local) Server */ + $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); + /* Update also the master-DB of the Server-Farm */ + $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); + } + } + + if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { + $vhost_data['ssl_enabled'] = 1; + $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); + } else { + $vhost_data['ssl_enabled'] = 0; + $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG); + } + + // Set SEO Redirect + if($data['new']['seo_redirect'] != ''){ + $vhost_data['seo_redirect_enabled'] = 1; + $tmp_seo_redirects = $this->get_seo_redirects($data['new']); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + foreach($tmp_seo_redirects as $key => $val){ + $vhost_data[$key] = $val; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + } else { + $vhost_data['seo_redirect_enabled'] = 0; + } + + // Rewrite rules + $own_rewrite_rules = array(); + $rewrite_rules = array(); + $local_rewrite_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ + if($data['new']['redirect_type'] != 'proxy'){ + $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); + } else { + $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); + } + } + + // Custom proxy directives + if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $data['new']['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + switch($data['new']['subdomain']) { + case 'www': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + case '*': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + + //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + default: + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + $exclude_own_hostname = ''; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + } + } + + // http2 or spdy? + $vhost_data['enable_http2'] = 'n'; + if($vhost_data['enable_spdy'] == 'y'){ + // check if nginx support http_v2; if so, use that instead of spdy + exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval); + if($tmp_retval == 0){ + $vhost_data['enable_http2'] = 'y'; + $vhost_data['enable_spdy'] = 'n'; + } + unset($tmp_output, $tmp_retval); + } + + // set logging variable + $vhost_data['logging'] = $web_config['logging']; + + $tpl->setVar($vhost_data); + + $server_alias = array(); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias.' '; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); + $alias_seo_redirects = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain'].' '; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain'].' '; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + + // Custom proxy directives + if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $alias['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { + switch($alias['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; + break; + case '*': + $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' '; + break; + default: + $server_alias[] = $alias['domain'].' '; + break; + } + $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); + + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + } + + // Local Rewriting (inside vhost server {} container) + if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + switch($alias['subdomain']) { + case 'www': + // example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + + // www.example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + case '*': + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', + 'local_redirect_operator' => '~*', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + default: + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + } + } + + // External Rewriting (extra server {} containers) + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ + if($alias['redirect_type'] != 'proxy'){ + $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); + } else { + $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); + } + } + + switch($alias['subdomain']) { + case 'www': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + case '*': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + default: + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); + else $domain_rule = $alias['domain']; + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + if(substr($alias['domain'], 0, 2) === '*.'){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); + } else { + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); + } + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + } + } + } + } + + //* If we have some alias records + if(count($server_alias) > 0) { + $server_alias_str = ''; + $n = 0; + + foreach($server_alias as $tmp_alias) { + $server_alias_str .= $tmp_alias; + } + unset($tmp_alias); + + $tpl->setVar('alias', trim($server_alias_str)); + } else { + $tpl->setVar('alias', ''); + } + + if(count($rewrite_rules) > 0) { + $tpl->setLoop('redirects', $rewrite_rules); + } + if(count($own_rewrite_rules) > 0) { + $tpl->setLoop('own_redirects', $own_rewrite_rules); + } + if(count($local_rewrite_rules) > 0) { + $tpl->setLoop('local_redirects', $local_rewrite_rules); + } + if(count($alias_seo_redirects) > 0) { + $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); + } + + $stats_web_folder = 'web'; + if($data['new']['type'] == 'vhost'){ + if($data['new']['web_folder'] != ''){ + if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); + if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); + } + $stats_web_folder .= '/'.$data['new']['web_folder']; + } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + $stats_web_folder = $data['new']['web_folder']; + } + + //* Create basic http auth for website statistics + $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); + + // Create basic http auth for other directories + $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); + if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); + + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); + //* Make a backup copy of vhost file + if(file_exists($vhost_file)) copy($vhost_file, $vhost_file.'~'); + + //* Write vhost file + $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); + $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + unset($tpl); + + //* Set the symlink to enable the vhost + //* First we check if there is a old type of symlink and remove it + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); + + //* Remove old or changed symlinks + if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + } + + //* New symlink + if($data['new']['subdomain'] == '*') { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); + } else { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); + } + if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { + symlink($vhost_file, $vhost_symlink); + $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + // remove old symlink and vhost file, if domain name of the site has changed + if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)) { + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + $app->system->unlink($vhost_file); + $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); + } + + // create password file for stats directory + if(!is_file($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { + if(trim($data['new']['stats_password']) != '') { + $htp_file = 'admin:'.trim($data['new']['stats_password']); + $app->system->file_put_contents($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', $htp_file); + $app->system->chmod($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', 0755); + unset($htp_file); + } + } + + //* Create awstats configuration + if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { + $this->awstats_update($data, $web_config); + } + + $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); + + if($web_config['check_apache_config'] == 'y') { + //* Test if nginx starts with the new configuration file + $nginx_online_status_before_restart = $this->_checkTcp('localhost', 80); + $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + + $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure + $app->log('nginx restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); + + // wait a few seconds, before we test the apache status again + sleep(2); + + //* Check if nginx restarted successfully if it was online before + $nginx_online_status_after_restart = $this->_checkTcp('localhost', 80); + $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); + if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) { + $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); + if(is_array($retval['output']) && !empty($retval['output'])){ + $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $retval['output'])); + } else { + // if no output is given, check again + exec('nginx -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } + $app->system->copy($vhost_file, $vhost_file.'.err'); + + if(is_file($vhost_file.'~')) { + //* Copy back the last backup file + $app->system->copy($vhost_file.'~', $vhost_file); + } else { + //* There is no backup file, so we create a empty vhost file with a warning message inside + $app->system->file_put_contents($vhost_file, "# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); + } + + if($this->ssl_certificate_changed === true) { + + $ssl_dir = $data['new']['document_root'].'/ssl'; + $domain = $data['new']['ssl_domain']; + $key_file = $ssl_dir.'/'.$domain.'.key.org'; + $key_file2 = $ssl_dir.'/'.$domain.'.key'; + $csr_file = $ssl_dir.'/'.$domain.'.csr'; + $crt_file = $ssl_dir.'/'.$domain.'.crt'; + //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; + + //* Backup the files that might have caused the error + if(is_file($key_file)){ + $app->system->copy($key_file, $key_file.'.err'); + $app->system->chmod($key_file.'.err', 0400); + } + if(is_file($key_file2)){ + $app->system->copy($key_file2, $key_file2.'.err'); + $app->system->chmod($key_file2.'.err', 0400); + } + if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); + if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); + //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err'); + + //* Restore the ~ backup files + if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); + if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); + if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); + if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); + //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file); + + $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); + } + + $app->services->restartService('httpd', 'restart'); + } + } else { + //* We do not check the nginx config after changes (is faster) + $app->services->restartServiceDelayed('httpd', 'reload'); + } + + //* The vhost is written and apache has been restarted, so we + // can reset the ssl changed var to false and cleanup some files + $this->ssl_certificate_changed = false; + + if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); + if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); + if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); + if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); + //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); + + // Remove the backup copy of the config file. + if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); //* Unset action to clean it for next processed vhost. $this->action = ''; } function delete($event_name, $data) { - global $app; + global $app, $conf; - $app->plugin_webserver_base->eventDelete($event_name, $data, 'nginx'); - } + // load the server configuration options + $app->uses('getconf'); + $app->uses('system'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered - function server_ip($event_name, $data) { - global $app; + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); + + //* Check if this is a chrooted setup + if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { + $nginx_chrooted = true; + } else { + $nginx_chrooted = false; + } + + //* Remove the mounts + $log_folder = 'log'; + $web_folder = ''; + if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); + if($tmp['domain'] != ''){ + $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); + } else { + // get log folder from /etc/fstab + /* + $bind_mounts = $app->system->file_get_contents('/etc/fstab'); + $bind_mount_lines = explode("\n", $bind_mounts); + if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ + foreach($bind_mount_lines as $bind_mount_line){ + $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); + $bind_mount_parts = explode(' ', $bind_mount_line); + if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ + if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ + $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); + } + } + } + } + */ + // we are deleting the parent domain, so we can delete everything in the log directory + $subdomain_hosts = array(); + $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ + $subdomain_hosts[] = $file; + } + } + } + } + if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ + $log_folders = array(); + foreach($subdomain_hosts as $subdomain_host){ + $log_folders[] = $log_folder.'/'.$subdomain_host; + } + } else { + if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; + $log_folder .= '/' . $subdomain_host; + } + $web_folder = $data['old']['web_folder']; + unset($tmp); + unset($subdomain_hosts); + } + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + } + } else { + //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); + //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); + } + + //try umount mysql + if(file_exists($data['old']['document_root'].'/var/run/mysqld')) { + $fstab_line = '/var/run/mysqld ' . $data['old']['document_root'] . '/var/run/mysqld none bind,nobootwait 0 0'; + $app->system->removeLine('/etc/fstab', $fstab_line); + $command = 'umount ' . escapeshellarg($data['old']['document_root']) . '/var/run/mysqld/'; + exec($command); + } + // remove letsencrypt if it exists (renew will always fail otherwise) + + $old_domain = $data['old']['domain']; + if(substr($old_domain, 0, 2) === '*.') { + // wildcard domain not yet supported by letsencrypt! + $old_domain = substr($old_domain, 2); + } + $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; + @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); + } + + //* remove mountpoint from fstab + if(is_array($log_folders) && !empty($log_folders)){ + foreach($log_folders as $log_folder){ + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + } else { + $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; + $app->system->removeLine('/etc/fstab', $fstab_line); + } + unset($log_folders); + + if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { + //* This is a alias domain or subdomain, so we have to update the website instead + $parent_domain_id = intval($data['old']['parent_domain_id']); + $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); + $data['new'] = $tmp; + $data['old'] = $tmp; + $this->action = 'update'; + $this->update_letsencrypt = true; + // just run the update function + $this->update($event_name, $data); + + } else { + //* This is a website + // Deleting the vhost file, symlink and the data directory + $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); + + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); + if(is_link($vhost_symlink)){ + $app->system->unlink($vhost_symlink); + $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); + } + + $app->system->unlink($vhost_file); + $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); + + if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $docroot = escapeshellcmd($data['old']['document_root']); + if($docroot != '' && !stristr($docroot, '..')) { + if($data['old']['type'] == 'vhost') { + // this is a vhost - we delete everything in here. + exec('rm -rf '.$docroot); + } elseif(!stristr($data['old']['web_folder'], '..')) { + // this is a vhost subdomain + // IMPORTANT: do some folder checks before we delete this! + $do_delete = true; + $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times + if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); + if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); + + $path_elements = explode('/', $delete_folder); + + if($path_elements[0] == 'web' || $path_elements[0] === '') { + // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! + // we use strict check as otherwise directories named '0' may not be deleted + $do_delete = false; + } else { + // read all vhost subdomains and alias with same parent domain + $used_paths = array(); + $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); + foreach($tmp as $tmprec) { + // we normalize the folder entries because we need to compare them + $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times + if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); + if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); + + // add this path and it's parent paths to used_paths array + while(strpos($tmp_folder, '/') !== false) { + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); + } + if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; + } + unset($tmp); + + // loop and check if the path is still used and stop at first used one + // set do_delete to false so nothing gets deleted if the web_folder itself is still used + $do_delete = false; + while(count($path_elements) > 0) { + $tmp_folder = implode('/', $path_elements); + if(in_array($tmp_folder, $used_paths) == true) break; + + // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true + $delete_folder = $tmp_folder; + $do_delete = true; + array_pop($path_elements); + } + unset($tmp_folder); + unset($used_paths); + } + + if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); + + unset($delete_folder); + unset($path_elements); + } + } + + //remove the php fastgi starter script if available + if ($data['old']['php'] == 'fast-cgi') { + $this->php_fpm_pool_delete($data, $web_config); + $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['fastcgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($fastcgi_starter_path)) { + exec('rm -rf '.$fastcgi_starter_path); + } + } else { + $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; + if (file_exists($fcgi_starter_script)) { + exec('rm -f '.$fcgi_starter_script); + } + } + } + + // remove PHP-FPM pool + if ($data['old']['php'] == 'php-fpm') { + $this->php_fpm_pool_delete($data, $web_config); + } + + //remove the php cgi starter script if available + if ($data['old']['php'] == 'cgi') { + // TODO: fetch the date from the server-settings + $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; + + $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); + if($data['old']['type'] == 'vhost') { + if (is_dir($cgi_starter_path)) { + exec('rm -rf '.$cgi_starter_path); + } + } else { + $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; + if (file_exists($cgi_starter_script)) { + exec('rm -f '.$cgi_starter_script); + } + } + } + + $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); + + // Delete the symlinks for the sites + $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); + if(is_array($tmp_symlinks_array)) { + foreach($tmp_symlinks_array as $tmp_symlink) { + $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); + $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); + // Remove trailing slash + if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); + // delete the symlink + if(is_link($tmp_symlink)) { + $app->system->unlink($tmp_symlink); + $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); + } + } + } + // end removing symlinks + } + + // Delete the log file directory + $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); + if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); + $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - $app->plugin_webserver_base->eventServerIp($event_name, $data, 'nginx'); + if($data['old']['type'] == 'vhost') { + //delete the web user + $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; + $command .= ' '.escapeshellcmd($data['old']['system_user']); + exec($command); + if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); + } + + //* Remove the awstats configuration file + if($data['old']['stats_type'] == 'awstats') { + $this->awstats_delete($data, $web_config); + } + + //* Delete the web-backups + if($data['old']['type'] == 'vhost') { + $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); + $backup_dir = $server_config['backup_dir']; + $mount_backup = true; + if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { + //* mount backup directory, if necessary + if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; + + if($mount_backup){ + $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; + //** do not use rm -rf $web_backup_dir because database(s) may exits + exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); + //* cleanup database + $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; + $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); + if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); + + $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); + } + } + } + + $app->services->restartServiceDelayed('httpd', 'reload'); + + } + + + if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); + } + + //* This function is called when a IP on the server is inserted, updated or deleted + function server_ip($event_name, $data) { + return; } //* Create or update the .htaccess folder protection function web_folder_user($event_name, $data) { - global $app; + global $app, $conf; + + $app->uses('system'); + + if($event_name == 'web_folder_user_delete') { + $folder_id = $data['old']['web_folder_id']; + } else { + $folder_id = $data['new']['web_folder_id']; + } + + $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { + $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($folder_path)) { + $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); + } + + //* Create empty .htpasswd file, if it does not exist + if(!is_file($folder_path.'.htpasswd')) { + $app->system->touch($folder_path.'.htpasswd'); + $app->system->chmod($folder_path.'.htpasswd', 0755); + $app->system->chown($folder_path.'.htpasswd', $website['system_user']); + $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); + $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } - $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'nginx'); + if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } + + //* Add or remove the user from .htpasswd file + if($event_name == 'web_folder_user_delete') { + $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); + $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); + } else { + if($data['new']['active'] == 'y') { + $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); + $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); + } + } + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); } //* Remove .htpasswd file, when folder protection is removed function web_folder_delete($event_name, $data) { - global $app; + global $app, $conf; + + $folder_id = $data['old']['web_folder_id']; + + $folder = $data['old']; + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); + + if(!is_array($folder) or !is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); + if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); + $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); + if(substr($folder_path, -1) != '/') $folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } - $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'nginx'); + //* Remove .htpasswd file + if(is_file($folder_path.'.htpasswd')) { + $app->system->unlink($folder_path.'.htpasswd'); + $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); } //* Update folder protection, when path has been changed function web_folder_update($event_name, $data) { + global $app, $conf; + + $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); + + if(!is_array($website)) { + $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); + return false; + } + + $web_folder = 'web'; + if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + + //* Get the folder path. + if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); + if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); + $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); + if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; + + if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); + if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); + $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); + if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; + + //* Check if the resulting path is inside the docroot + if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { + $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { + $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + return false; + } + + //* Check if the resulting path is inside the docroot + if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { + $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); + return false; + } + + //* Create the folder path, if it does not exist + if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); + + if($data['old']['path'] != $data['new']['path']) { + + + //* move .htpasswd file + if(is_file($old_folder_path.'.htpasswd')) { + $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); + $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); + } + + } + + // write basic auth configuration to vhost file because nginx does not support .htaccess + $webdata['new'] = $webdata['old'] = $website; + $this->update('web_domain_update', $webdata); + } + + function _create_web_folder_auth_configuration($website){ + global $app, $conf; + //* Create the domain.auth file which is included in the vhost configuration file + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); + //$app->load('tpl'); + //$tpl = new tpl(); + //$tpl->newTemplate('nginx_http_authentication.auth.master'); + $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); + $basic_auth_locations = array(); + if(is_array($website_auth_locations) && !empty($website_auth_locations)){ + foreach($website_auth_locations as $website_auth_location){ + if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); + if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); + if($website_auth_location['path'] != ''){ + $website_auth_location['path'] .= '/'; + } + $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], + 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); + } + } + return $basic_auth_locations; + //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); + //file_put_contents($basic_auth_file,$tpl->grab()); + //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); + //unset($tpl); + //$app->services->restartServiceDelayed('httpd','reload'); + } + + //* Update the awstats configuration file + private function awstats_update ($data, $web_config) { global $app; - $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'nginx'); + $web_folder = $data['new']['web_folder']; + if($data['new']['type'] == 'vhost') $web_folder = 'web'; + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); + if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + } + + $content = ''; + if (is_file($awstats_conf_dir."/awstats.conf")) { + $include_file = $awstats_conf_dir."/awstats.conf"; + } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { + $include_file = $awstats_conf_dir."/awstats.model.conf"; + } + $content .= "Include \"".$include_file."\"\n"; + $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; + $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; + $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; + + if (isset($include_file)) { + $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); + $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); + } else { + $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); + } + } + + if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); + if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { + $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } else { + $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); + } } - public function ftp_user_delete($event_name, $data) { + //* Delete the awstats configuration file + private function awstats_delete ($data, $web_config) { global $app; - $ftpquota_file = $data['old']['dir'].'/.ftpquota'; - if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); + $awstats_conf_dir = $web_config['awstats_conf_dir']; + + if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { + $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); + $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); + } + } + + //* Update the PHP-FPM pool configuration file + private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { + global $app, $conf; + $pool_dir = trim($pool_dir); + $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); + + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + if($data['new']['php'] != 'php-fpm'){ + if(@is_file($pool_dir.$pool_name.'.conf')){ + $app->system->unlink($pool_dir.$pool_name.'.conf'); + //$reload = true; + } + if($data['old']['php'] != 'no'){ + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + return; + } + + $app->load('tpl'); + $tpl = new tpl(); + $tpl->newTemplate('php_fpm_pool.conf.master'); + + if($data['new']['php_fpm_chroot'] == 'y'){ + $php_fpm_chroot = 1; + } else { + $php_fpm_chroot = 0; + } + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); + + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_listen_mode', '0660'); + + $tpl->setVar('fpm_pool', $pool_name); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + $tpl->setVar('fpm_user', $data['new']['system_user']); + + //Red Hat workaround for group ownership of socket files + foreach($rh_releasefiles as $rh_file) { + if(file_exists($rh_file) && (filesize($rh_file) > 0)) { + $tmp = file_get_contents($rh_file); + if(preg_match('/[67]+\.[0-9]+/m', $tmp)) { + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('fpm_listen_group', $data['new']['system_group']); + } + unset($tmp); + } elseif(!file_exists($rh_file)) { + //OS seems to be not Red Hat'ish + $tpl->setVar('fpm_group', $data['new']['system_group']); + $tpl->setVar('fpm_listen_group', $web_config['group']); + } + break; + } + + $tpl->setVar('fpm_listen_user', $data['new']['system_user']); + $tpl->setVar('fpm_domain', $data['new']['domain']); + $tpl->setVar('pm', $data['new']['pm']); + $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); + $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); + $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); + $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); + $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); + $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); + $tpl->setVar('document_root', $data['new']['document_root']); + $tpl->setVar('security_level', $web_config['security_level']); + $tpl->setVar('domain', $data['new']['domain']); + $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); + if($php_fpm_chroot){ + $document_root = $data['new']['document_root']; + $domain = $data['new']['domain']; + $php_open_basedir = str_replace(":/srv/www/$domain/web",'',$php_open_basedir); + $php_open_basedir = str_replace(":/var/www/$domain/web",'',$php_open_basedir); + $php_open_basedir = str_replace("$document_root",'',$php_open_basedir); + } + $tpl->setVar('php_open_basedir', $php_open_basedir); + if($php_open_basedir != ''){ + $tpl->setVar('enable_php_open_basedir', ''); + } else { + $tpl->setVar('enable_php_open_basedir', ';'); + } + + // Custom php.ini settings + $final_php_ini_settings = array(); + $custom_php_ini_settings = trim($data['new']['custom_php_ini']); + + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); + if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ + $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); + if(is_array($required_php_snippets) && !empty($required_php_snippets)){ + foreach($required_php_snippets as $required_php_snippet){ + $required_php_snippet = intval($required_php_snippet); + if($required_php_snippet > 0){ + $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); + $php_snippet['snippet'] = trim($php_snippet['snippet']); + if($php_snippet['snippet'] != ''){ + $custom_php_ini_settings .= "\n".$php_snippet['snippet']; + } + } + } + } + } + } + + $custom_session_save_path = false; + if($custom_php_ini_settings != ''){ + // Make sure we only have Unix linebreaks + $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); + $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); + $ini_settings = explode("\n", $custom_php_ini_settings); + if(is_array($ini_settings) && !empty($ini_settings)){ + foreach($ini_settings as $ini_setting){ + $ini_setting = trim($ini_setting); + if(substr($ini_setting, 0, 1) == ';') continue; + if(substr($ini_setting, 0, 1) == '#') continue; + if(substr($ini_setting, 0, 2) == '//') continue; + list($key, $value) = explode('=', $ini_setting, 2); + $value = trim($value); + if($value != ''){ + $key = trim($key); + if($key == 'session.save_path') $custom_session_save_path = true; + switch (strtolower($value)) { + case '0': + // PHP-FPM might complain about invalid boolean value if you use 0 + $value = 'off'; + case '1': + case 'on': + case 'off': + case 'true': + case 'false': + case 'yes': + case 'no': + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); + break; + default: + $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); + } + } + } + } + } + + $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); + + $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); + + $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); + $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + unset($tpl); + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $conf["server_id"]); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + //* Delete the PHP-FPM pool configuration file + private function php_fpm_pool_delete ($data, $web_config) { + global $app, $conf; + + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['old']['domain_id']; + + if ( @is_file($pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + } + + // delete pool in all other PHP versions + $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); + if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; + if($default_pool_dir != $pool_dir){ + if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { + $app->system->unlink($default_pool_dir.$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + $php_versions = $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 = ?", $data['old']['server_id']); + if(is_array($php_versions) && !empty($php_versions)){ + foreach($php_versions as $php_version){ + $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); + if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; + if($php_version['php_fpm_pool_dir'] != $pool_dir){ + if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { + $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); + $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); + $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); + } + } + } + } + + // Reload current PHP-FPM after all others + sleep(1); + if(!$default_php_fpm){ + $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); + } else { + $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); + } + } + + private function nginx_replace($matches){ + $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; + if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; + if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; + $location .= "\n"; + $location .= $matches[5]."\n"; + $location .= $matches[6]; + return $location; + } + + private function nginx_merge_locations($vhost_conf) { + global $app, $conf; + + if(preg_match('/##subroot (.+?)\s*##/', $vhost_conf, $subroot)) { + if(!preg_match('/^(?:[a-z0-9\/_-]|\.(?!\.))+$/iD', $subroot[1])) { + $app->log('Token ##subroot is unsecure (server ID: '.$conf['server_id'].').', LOGLEVEL_WARN); + } else { + $insert_pos = strpos($vhost_conf, ';', strpos($vhost_conf, 'root ')); + $vhost_conf = substr_replace($vhost_conf, ltrim($subroot[1], '/'), $insert_pos, 0); + } + } + + $lines = explode("\n", $vhost_conf); + + // if whole location block is in one line, split it up into multiple lines + if(is_array($lines) && !empty($lines)){ + $linecount = sizeof($lines); + for($h=0;$h<$linecount;$h++){ + // remove comments + if(substr(trim($lines[$h]), 0, 1) == '#'){ + unset($lines[$h]); + continue; + } + + $lines[$h] = rtrim($lines[$h]); + /* + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + $lines[$h] = str_replace(";", ";\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ + $lines[$h] = str_replace("{", "{\n", $lines[$h]); + if(strpos($lines[$h], '##merge##') !== false){ + $lines[$h] = str_replace('##merge##', '', $lines[$h]); + $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); + } + } + */ + $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; + $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]); + } + } + $vhost_conf = implode("\n", $lines); + unset($lines); + unset($linecount); + + $lines = explode("\n", $vhost_conf); + + if(is_array($lines) && !empty($lines)){ + $locations = array(); + $locations_to_delete = array(); + $islocation = false; + $linecount = sizeof($lines); + $server_count = 0; + + for($i=0;$i<$linecount;$i++){ + $l = trim($lines[$i]); + if(substr($l, 0, 8) == 'server {') $server_count += 1; + if($server_count > 1) break; + if(substr($l, 0, 8) == 'location' && !$islocation){ + + $islocation = true; + $level = 0; + + // Remove unnecessary whitespace + $l = preg_replace('/\s\s+/', ' ', $l); + + $loc_parts = explode(' ', $l); + // see http://wiki.nginx.org/HttpCoreModule#location + if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ + $location = $loc_parts[1].' '.$loc_parts[2]; + } else { + $location = $loc_parts[1]; + } + unset($loc_parts); + + if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; + if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; + if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; + + if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; + if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; + if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; + if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; + if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; + + unset($lines[$i]); + + } else { + + if($islocation){ + $openingbracketpos = strrpos($l, '{'); + if($openingbracketpos !== false){ + $level += 1; + } + $closingbracketpos = strrpos($l, '}'); + if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){ + $level -= 1; + $locations[$location]['location'] .= $lines[$i]."\n"; + } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){ + $islocation = false; + } else { + $locations[$location]['location'] .= $lines[$i]."\n"; + } + unset($lines[$i]); + } + + } + } + if(is_array($locations) && !empty($locations)){ + if(is_array($locations_to_delete) && !empty($locations_to_delete)){ + foreach($locations_to_delete as $location_to_delete){ + if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); + } + } + + foreach($locations as $key => $val){ + $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; + $lines[$val['start_line']] = $new_location; + } + } + ksort($lines); + $vhost_conf = implode("\n", $lines); + } + + return trim($vhost_conf); } function client_delete($event_name, $data) { + global $app, $conf; + + $app->uses("getconf"); + $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); + + $client_id = intval($data['old']['client_id']); + if($client_id > 0) { + + $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; + if(is_dir($client_dir) && !stristr($client_dir, '..')) { + // remove symlinks from $client_dir + $files = array_diff(scandir($client_dir), array('.', '..')); + if(is_array($files) && !empty($files)){ + foreach($files as $file){ + if(is_link($client_dir.'/'.$file)){ + unlink($client_dir.'/'.$file); + $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); + } + } + } + + @rmdir($client_dir); + $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); + } + + if($app->system->is_group('client'.$client_id)){ + $app->system->_exec('groupdel client'.$client_id); + $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); + } + } + + } + + private function _checkTcp ($host, $port) { + + $fp = @fsockopen($host, $port, $errno, $errstr, 2); + + if ($fp) { + fclose($fp); + return true; + } else { + return false; + } + } + + private function _rewrite_quote($string) { + return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); + } + + private function url_is_local($hostname, $domain_id){ global $app; - $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'nginx'); + // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first + $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); + if(is_array($webs) && !empty($webs)){ + foreach($webs as $web){ + // web domain doesn't match hostname + if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue; + // own vhost and therefore server {} container of its own + //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; + + if($web['subdomain'] == '*'){ + $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'none'){ + if($web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if($web['subdomain'] == 'www'){ + if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; + } + if(preg_match($pattern, $hostname)){ + if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ + // own vhost and therefore server {} container of its own + if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; + // alias domains/subdomains using rewrites and therefore a server {} container of their own + if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; + return true; + } else { + return false; + } + } + } + } + + return false; } + private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){ + // $force_subdomain = 'none|www' + $seo_redirects = array(); + + if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; + + if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){ + if($web['seo_redirect'] == 'non_www_to_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '='; + } + if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ + // ^(example\.com|(?!\bwww\b)\.example\.com)$ + // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$'; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; + } + if($web['seo_redirect'] == '*_to_www_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; + } + } + if($force_subdomain != 'none'){ + if($web['seo_redirect'] == 'www_to_non_www'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '='; + } + if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){ + // ^(.+)\.example\.com$ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$'; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; + } + if($web['seo_redirect'] == '*_to_domain_tld'){ + $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; + $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; + } + } + return $seo_redirects; + } } // end class +?> -- GitLab From b0bdaede03faa64a725a261f42e4f7dc8dc4d529 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 21:39:45 +0100 Subject: [PATCH 171/310] - removed left code for php cgi --- .../lib/classes/plugin_webserver_base.inc.php | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 715270cc5..184f08ce4 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -1826,24 +1826,6 @@ class plugin_webserver_base { $this->php_fpm_pool_delete($data, $web_config, $server_type); } - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); // Delete the symlinks for the sites -- GitLab From 16e16fc9a32b94f00211d66c4aa8750507147857 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 21:59:12 +0100 Subject: [PATCH 172/310] - removed xmpp from core --- .../autoinstall.conf_sample.php | 1 - .../auth_prosody/authenticate_isp.sh | 38 -- .../apps/xmpp_libs/auth_prosody/db_auth.php | 48 -- .../xmpp_libs/auth_prosody/db_conf.inc.php | 6 - .../apps/xmpp_libs/auth_prosody/db_isuser.php | 43 -- .../apps/xmpp_libs/auth_prosody/prosody-purge | 62 -- .../mod_auth_external/authenticate_isp.sh | 38 -- .../xmpp_libs/mod_auth_external/db_auth.php | 48 -- .../mod_auth_external/db_conf.inc.php | 6 - .../xmpp_libs/mod_auth_external/db_isuser.php | 43 -- .../mod_auth_external/mod_auth_external.lua | 118 ---- install/apps/xmpp_libs/mod_discoitems.lua | 24 - .../mod_webpresence/icons/status_away.png | Bin 948 -> 0 bytes .../mod_webpresence/icons/status_chat.png | Bin 920 -> 0 bytes .../mod_webpresence/icons/status_dnd.png | Bin 822 -> 0 bytes .../mod_webpresence/icons/status_offline.png | Bin 905 -> 0 bytes .../mod_webpresence/icons/status_online.png | Bin 920 -> 0 bytes .../mod_webpresence/icons/status_xa.png | Bin 954 -> 0 bytes .../mod_webpresence/mod_webpresence.lua | 118 ---- install/dist/conf/debian60.conf.php | 13 - install/dist/conf/debian90.conf.php | 13 - install/dist/conf/debiantesting.conf.php | 13 - install/dist/conf/ubuntu1604.conf.php | 13 - install/dist/conf/ubuntu1710.conf.php | 14 - install/dist/conf/ubuntu1804.conf.php | 4 - install/install.php | 17 - install/lib/installer_base.lib.php | 215 +------ install/lib/update.lib.php | 2 - install/tpl/server.ini.master | 11 - install/tpl/xmpp_metronome_conf_global.master | 65 --- install/tpl/xmpp_metronome_conf_main.master | 3 - install/tpl/xmpp_metronome_conf_ssl.master | 48 -- install/tpl/xmpp_prosody_conf_global.master | 94 --- install/tpl/xmpp_prosody_conf_main.master | 3 - install/tpl/xmpp_prosody_conf_ssl.master | 48 -- install/tpl/xmpp_prosody_conf_storage.master | 9 - install/update.php | 24 +- .../lib/classes/custom_datasource.inc.php | 6 - interface/lib/classes/remote.d/mail.inc.php | 173 +----- interface/lib/classes/remote.d/server.inc.php | 2 +- interface/lib/classes/validate_client.inc.php | 3 - interface/web/admin/form/server.tform.php | 6 - .../web/admin/form/server_config.tform.php | 98 ---- interface/web/admin/list/server.list.php | 9 - .../templates/server_config_xmpp_edit.htm | 78 --- .../admin/templates/server_edit_services.htm | 8 +- interface/web/admin/templates/server_list.htm | 7 +- interface/web/client/form/client.tform.php | 113 +--- .../web/client/form/client_template.tform.php | 114 +--- interface/web/client/form/reseller.tform.php | 113 +--- .../client/templates/client_edit_limits.htm | 86 +-- .../templates/client_template_edit_limits.htm | 85 --- .../client/templates/reseller_edit_limits.htm | 86 +-- interface/web/mail/form/xmpp_domain.tform.php | 464 --------------- interface/web/mail/form/xmpp_user.tform.php | 127 ----- interface/web/mail/lib/module.conf.php | 25 - interface/web/mail/lib/remote.conf.php | 2 - interface/web/mail/list/xmpp_domain.list.php | 109 ---- interface/web/mail/list/xmpp_user.list.php | 62 -- .../mail/templates/xmpp_domain_admin_list.htm | 60 -- .../web/mail/templates/xmpp_domain_edit.htm | 130 ----- .../templates/xmpp_domain_edit_modules.htm | 78 --- .../mail/templates/xmpp_domain_edit_muc.htm | 91 --- .../mail/templates/xmpp_domain_edit_ssl.htm | 100 ---- .../web/mail/templates/xmpp_domain_list.htm | 74 --- .../web/mail/templates/xmpp_user_edit.htm | 57 -- .../web/mail/templates/xmpp_user_list.htm | 76 --- interface/web/mail/xmpp_domain_del.php | 93 --- interface/web/mail/xmpp_domain_edit.php | 536 ------------------ interface/web/mail/xmpp_domain_list.php | 28 - interface/web/mail/xmpp_user_del.php | 72 --- interface/web/mail/xmpp_user_edit.php | 172 ------ interface/web/mail/xmpp_user_list.php | 39 -- server/conf/xmpp_conf_ssl.master | 72 --- server/conf/xmpp_metronome_conf_global.master | 48 -- server/conf/xmpp_metronome_conf_host.master | 135 ----- server/conf/xmpp_metronome_conf_status.master | 12 - server/conf/xmpp_prosody_conf_global.master | 60 -- server/conf/xmpp_prosody_conf_host.master | 166 ------ server/conf/xmpp_prosody_conf_status.master | 20 - server/mods-available/xmpp_module.inc.php | 132 ----- .../server_services_plugin.inc.php | 7 +- server/plugins-available/xmpp_plugin.inc.php | 464 --------------- 83 files changed, 19 insertions(+), 5681 deletions(-) delete mode 100644 install/apps/xmpp_libs/auth_prosody/authenticate_isp.sh delete mode 100644 install/apps/xmpp_libs/auth_prosody/db_auth.php delete mode 100644 install/apps/xmpp_libs/auth_prosody/db_conf.inc.php delete mode 100644 install/apps/xmpp_libs/auth_prosody/db_isuser.php delete mode 100644 install/apps/xmpp_libs/auth_prosody/prosody-purge delete mode 100644 install/apps/xmpp_libs/mod_auth_external/authenticate_isp.sh delete mode 100644 install/apps/xmpp_libs/mod_auth_external/db_auth.php delete mode 100644 install/apps/xmpp_libs/mod_auth_external/db_conf.inc.php delete mode 100644 install/apps/xmpp_libs/mod_auth_external/db_isuser.php delete mode 100644 install/apps/xmpp_libs/mod_auth_external/mod_auth_external.lua delete mode 100644 install/apps/xmpp_libs/mod_discoitems.lua delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_away.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_chat.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_dnd.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_offline.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_online.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/icons/status_xa.png delete mode 100644 install/apps/xmpp_libs/mod_webpresence/mod_webpresence.lua delete mode 100644 install/tpl/xmpp_metronome_conf_global.master delete mode 100644 install/tpl/xmpp_metronome_conf_main.master delete mode 100644 install/tpl/xmpp_metronome_conf_ssl.master delete mode 100644 install/tpl/xmpp_prosody_conf_global.master delete mode 100644 install/tpl/xmpp_prosody_conf_main.master delete mode 100644 install/tpl/xmpp_prosody_conf_ssl.master delete mode 100644 install/tpl/xmpp_prosody_conf_storage.master delete mode 100644 interface/web/admin/templates/server_config_xmpp_edit.htm delete mode 100644 interface/web/mail/form/xmpp_domain.tform.php delete mode 100644 interface/web/mail/form/xmpp_user.tform.php delete mode 100644 interface/web/mail/list/xmpp_domain.list.php delete mode 100644 interface/web/mail/list/xmpp_user.list.php delete mode 100644 interface/web/mail/templates/xmpp_domain_admin_list.htm delete mode 100644 interface/web/mail/templates/xmpp_domain_edit.htm delete mode 100644 interface/web/mail/templates/xmpp_domain_edit_modules.htm delete mode 100644 interface/web/mail/templates/xmpp_domain_edit_muc.htm delete mode 100644 interface/web/mail/templates/xmpp_domain_edit_ssl.htm delete mode 100644 interface/web/mail/templates/xmpp_domain_list.htm delete mode 100644 interface/web/mail/templates/xmpp_user_edit.htm delete mode 100644 interface/web/mail/templates/xmpp_user_list.htm delete mode 100644 interface/web/mail/xmpp_domain_del.php delete mode 100644 interface/web/mail/xmpp_domain_edit.php delete mode 100644 interface/web/mail/xmpp_domain_list.php delete mode 100644 interface/web/mail/xmpp_user_del.php delete mode 100644 interface/web/mail/xmpp_user_edit.php delete mode 100644 interface/web/mail/xmpp_user_list.php delete mode 100644 server/conf/xmpp_conf_ssl.master delete mode 100644 server/conf/xmpp_metronome_conf_global.master delete mode 100644 server/conf/xmpp_metronome_conf_host.master delete mode 100644 server/conf/xmpp_metronome_conf_status.master delete mode 100644 server/conf/xmpp_prosody_conf_global.master delete mode 100644 server/conf/xmpp_prosody_conf_host.master delete mode 100644 server/conf/xmpp_prosody_conf_status.master delete mode 100644 server/mods-available/xmpp_module.inc.php delete mode 100644 server/plugins-available/xmpp_plugin.inc.php diff --git a/docs/autoinstall_samples/autoinstall.conf_sample.php b/docs/autoinstall_samples/autoinstall.conf_sample.php index b5f3a5773..c7b539375 100644 --- a/docs/autoinstall_samples/autoinstall.conf_sample.php +++ b/docs/autoinstall_samples/autoinstall.conf_sample.php @@ -57,7 +57,6 @@ $autoupdate['reconfigure_crontab'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_mail_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_web_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_dns_server'] = 'yes'; // yes (default), no -$autoupdate['svc_detect_change_xmpp_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_firewall_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_vserver_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_db_server'] = 'yes'; // yes (default), no diff --git a/install/apps/xmpp_libs/auth_prosody/authenticate_isp.sh b/install/apps/xmpp_libs/auth_prosody/authenticate_isp.sh deleted file mode 100644 index 1992fae0b..000000000 --- a/install/apps/xmpp_libs/auth_prosody/authenticate_isp.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -IFS=":" -AUTH_OK=1 -AUTH_FAILED=0 -LOGFILE="/var/log/prosody/auth.log" -USELOG=true - -while read ACTION USER HOST PASS ; do - - [ $USELOG == true ] && { echo "Date: $(date) Action: $ACTION User: $USER Host: $HOST" >> $LOGFILE; } - - case $ACTION in - "auth") - if [ `/usr/bin/php /usr/local/lib/prosody/auth/db_auth.php $USER $HOST $PASS 2>/dev/null` == 1 ] ; then - echo $AUTH_OK - [ $USELOG == true ] && { echo "AUTH OK" >> $LOGFILE; } - else - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "AUTH FAILED" >> $LOGFILE; } - fi - ;; - "isuser") - if [ `/usr/bin/php /usr/local/lib/prosody/auth/db_isuser.php $USER $HOST 2>/dev/null` == 1 ] ; then - echo $AUTH_OK - [ $USELOG == true ] && { echo "ISUSER OK" >> $LOGFILE; } - else - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "ISUSER FAILED" >> $LOGFILE; } - fi - ;; - *) - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "UNKNOWN ACTION GIVEN: $ACTION" >> $LOGFILE; } - ;; - esac - -done diff --git a/install/apps/xmpp_libs/auth_prosody/db_auth.php b/install/apps/xmpp_libs/auth_prosody/db_auth.php deleted file mode 100644 index 2d3faa337..000000000 --- a/install/apps/xmpp_libs/auth_prosody/db_auth.php +++ /dev/null @@ -1,48 +0,0 @@ -real_escape_string($arg_email); - $query = $db->prepare("SELECT jid, password FROM xmpp_user WHERE jid LIKE ? AND active='y' AND server_id=?"); - $query->bind_param('si', $arg_email, $isp_server_id); - $query->execute(); - $query->bind_result($jid, $password); - $query->fetch(); - $query->close(); - - result_false(is_null($jid)); - checkAuth($arg_password, $password); -}catch(Exception $ex){ - echo 0; - exit(); -} - -function result_false($cond = true){ - if(!$cond) return; - echo 0; - exit(); -} -function result_true(){ - echo 1; - exit(); -} -function checkAuth($pw_arg, $pw_db){ - if(crypt($pw_arg, $pw_db) == $pw_db) - result_true(); - result_false(); -} -?> \ No newline at end of file diff --git a/install/apps/xmpp_libs/auth_prosody/db_conf.inc.php b/install/apps/xmpp_libs/auth_prosody/db_conf.inc.php deleted file mode 100644 index 1aba63d6e..000000000 --- a/install/apps/xmpp_libs/auth_prosody/db_conf.inc.php +++ /dev/null @@ -1,6 +0,0 @@ -real_escape_string($arg_email); - $query = $db->prepare("SELECT count(*) AS usercount FROM xmpp_user WHERE jid LIKE ? AND active='y' AND server_id=?"); - $query->bind_param('si', $arg_email, $isp_server_id); - $query->execute(); - $query->bind_result($usercount); - $query->fetch(); - $query->close(); - - result_false($usercount != 1); - result_true(); - -}catch(Exception $ex){ - echo 0; - exit(); -} - -function result_false($cond = true){ - if(!$cond) return; - echo 0; - exit(); -} -function result_true(){ - echo 1; - exit(); -} - -?> diff --git a/install/apps/xmpp_libs/auth_prosody/prosody-purge b/install/apps/xmpp_libs/auth_prosody/prosody-purge deleted file mode 100644 index df50105da..000000000 --- a/install/apps/xmpp_libs/auth_prosody/prosody-purge +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/php - 4); - -$operation = $argv[1]; -$host = $argv[2]; - -$configFile = file_get_contents('/etc/prosody/storage.cfg.lua'); -preg_match_all('/(host|database|port|username|password) *= *"?([^"\n]*)"?;/', $configFile, $matches); -$config = array(); -foreach($matches[1] AS $ix => $key) { - $config[$key] = $matches[2][$ix]; -} - -try { - // Connect to database - $db = new mysqli($config['host'], $config['username'], $config['password'], $config['database']); - - switch($operation){ - case 'user': - usage(count($argv) != 4); - $user = $argv[3]; - do_query($db->prepare("DELETE FROM prosody WHERE user = ? AND host = ?"), $host, $user); - do_query($db->prepare("DELETE FROM prosodyarchive WHERE user = ? AND host = ?"), $host, $user); - break; - case 'domain': - do_query($db->prepare("DELETE FROM prosody WHERE host = ?"), $host); - do_query($db->prepare("DELETE FROM prosodyarchive WHERE host = ?"), $host); - do_query($db->prepare("DELETE FROM prosody WHERE host LIKE ?"), "%.$host"); - do_query($db->prepare("DELETE FROM prosodyarchive WHERE host LIKE ?"), "%.$host"); - break; - } - $db->close(); -} catch (Exception $ex) { - var_dump($ex); -} - - -function do_query($query, $host, $user = false){ - if($user !== false) - $query->bind_param('ss', $user, $host); - else - $query->bind_param('s', $host); - $query->execute(); - $entries = $query->affected_rows; - $query->close(); - if(DEBUG) echo "$entries deleted!\n"; - return $entries; -} - -function result_false($cond = true) { - if(!$cond) return; - exit(1); -} - -function usage($cond = false){ - if(!$cond) return; - echo "USAGE: \n prosody-purge domain my.domain.com \n prosody-purge user my.domain.com username \n"; - result_false(); -} diff --git a/install/apps/xmpp_libs/mod_auth_external/authenticate_isp.sh b/install/apps/xmpp_libs/mod_auth_external/authenticate_isp.sh deleted file mode 100644 index c5a0c8e68..000000000 --- a/install/apps/xmpp_libs/mod_auth_external/authenticate_isp.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -IFS=":" -AUTH_OK=1 -AUTH_FAILED=0 -LOGFILE="/var/log/metronome/auth.log" -USELOG=true - -while read ACTION USER HOST PASS ; do - - [ $USELOG == true ] && { echo "Date: $(date) Action: $ACTION User: $USER Host: $HOST" >> $LOGFILE; } - - case $ACTION in - "auth") - if [ `/usr/bin/php /usr/lib/metronome/isp-modules/mod_auth_external/db_auth.php $USER $HOST $PASS 2>/dev/null` == 1 ] ; then - echo $AUTH_OK - [ $USELOG == true ] && { echo "AUTH OK" >> $LOGFILE; } - else - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "AUTH FAILED" >> $LOGFILE; } - fi - ;; - "isuser") - if [ `/usr/bin/php /usr/lib/metronome/isp-modules/mod_auth_external/db_isuser.php $USER $HOST 2>/dev/null` == 1 ] ; then - echo $AUTH_OK - [ $USELOG == true ] && { echo "ISUSER OK" >> $LOGFILE; } - else - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "ISUSER FAILED" >> $LOGFILE; } - fi - ;; - *) - echo $AUTH_FAILED - [ $USELOG == true ] && { echo "UNKNOWN ACTION GIVEN: $ACTION" >> $LOGFILE; } - ;; - esac - -done diff --git a/install/apps/xmpp_libs/mod_auth_external/db_auth.php b/install/apps/xmpp_libs/mod_auth_external/db_auth.php deleted file mode 100644 index 2d3faa337..000000000 --- a/install/apps/xmpp_libs/mod_auth_external/db_auth.php +++ /dev/null @@ -1,48 +0,0 @@ -real_escape_string($arg_email); - $query = $db->prepare("SELECT jid, password FROM xmpp_user WHERE jid LIKE ? AND active='y' AND server_id=?"); - $query->bind_param('si', $arg_email, $isp_server_id); - $query->execute(); - $query->bind_result($jid, $password); - $query->fetch(); - $query->close(); - - result_false(is_null($jid)); - checkAuth($arg_password, $password); -}catch(Exception $ex){ - echo 0; - exit(); -} - -function result_false($cond = true){ - if(!$cond) return; - echo 0; - exit(); -} -function result_true(){ - echo 1; - exit(); -} -function checkAuth($pw_arg, $pw_db){ - if(crypt($pw_arg, $pw_db) == $pw_db) - result_true(); - result_false(); -} -?> \ No newline at end of file diff --git a/install/apps/xmpp_libs/mod_auth_external/db_conf.inc.php b/install/apps/xmpp_libs/mod_auth_external/db_conf.inc.php deleted file mode 100644 index 1aba63d6e..000000000 --- a/install/apps/xmpp_libs/mod_auth_external/db_conf.inc.php +++ /dev/null @@ -1,6 +0,0 @@ -real_escape_string($arg_email); - $query = $db->prepare("SELECT count(*) AS usercount FROM xmpp_user WHERE jid LIKE ? AND active='y' AND server_id=?"); - $query->bind_param('si', $arg_email, $isp_server_id); - $query->execute(); - $query->bind_result($usercount); - $query->fetch(); - $query->close(); - - result_false($usercount != 1); - result_true(); - -}catch(Exception $ex){ - echo 0; - exit(); -} - -function result_false($cond = true){ - if(!$cond) return; - echo 0; - exit(); -} -function result_true(){ - echo 1; - exit(); -} - -?> diff --git a/install/apps/xmpp_libs/mod_auth_external/mod_auth_external.lua b/install/apps/xmpp_libs/mod_auth_external/mod_auth_external.lua deleted file mode 100644 index c86400610..000000000 --- a/install/apps/xmpp_libs/mod_auth_external/mod_auth_external.lua +++ /dev/null @@ -1,118 +0,0 @@ -local nodeprep = require "util.encodings".stringprep.nodeprep; -local lpc = require "lpc"; - -local config = require "core.configmanager"; -local log = module._log; -local host = module.host; -local script_type = config.get(host, "external_auth_protocol") or "generic"; -assert(script_type == "ejabberd" or script_type == "generic"); -local command = config.get(host, "external_auth_command") or ""; -assert(type(command) == "string"); -assert(not host:find(":")); -local usermanager = require "core.usermanager"; -local jid_bare = require "util.jid".bare; -local new_sasl = require "util.sasl".new; - -local pid; -local readfile; -local writefile; - -local function send_query(text) - if pid and lpc.wait(pid,1) ~= nil then - log("debug","error, process died, force reopen"); - pid=nil; - end - if not pid then - log("debug", "Opening process " .. command); - pid, writefile, readfile = lpc.run(command); - end - if not pid then - log("debug", "Process failed to open"); - return nil; - end - - writefile:write(text); - writefile:flush(); - if script_type == "ejabberd" then - return readfile:read(4); - elseif script_type == "generic" then - return readfile:read(); - end -end - -function do_query(kind, username, password) - if not username then return nil, "not-acceptable"; end - username = nodeprep(username); - if not username then return nil, "jid-malformed"; end - - local query = (password and "%s:%s:%s:%s" or "%s:%s:%s"):format(kind, username, host, password); - local len = #query - if len > 1000 then return nil, "policy-violation"; end - - if script_type == "ejabberd" then - local lo = len % 256; - local hi = (len - lo) / 256; - query = string.char(hi, lo)..query; - end - if script_type == "generic" then - query = query..'\n'; - end - - local response = send_query(query); - if (script_type == "ejabberd" and response == "\0\2\0\0") or - (script_type == "generic" and response == "0") then - return nil, "not-authorized"; - elseif (script_type == "ejabberd" and response == "\0\2\0\1") or - (script_type == "generic" and response == "1") then - return true; - else - log("debug", "Nonsense back"); - return nil, "internal-server-error"; - end -end - -function new_external_provider(host) - local provider = { name = "external" }; - - function provider.test_password(username, password) - return do_query("auth", username, password); - end - - function provider.set_password(username, password) - return do_query("setpass", username, password); - end - - function provider.user_exists(username) - return do_query("isuser", username); - end - - function provider.create_user(username, password) return nil, "Account creation/modification not available."; end - - function provider.get_sasl_handler() - local testpass_authentication_profile = { - plain_test = function(sasl, username, password, realm) - return usermanager.test_password(username, realm, password), true; - end, - }; - return new_sasl(module.host, testpass_authentication_profile); - end - - function provider.is_admin(jid) - local admins = config.get(host, "admins"); - if admins ~= config.get("*", "admins") then - if type(admins) == "table" then - jid = jid_bare(jid); - for _,admin in ipairs(admins) do - if admin == jid then return true; end - end - elseif admins then - log("error", "Option 'admins' for host '%s' is not a table", host); - end - end - return usermanager.is_admin(jid); - end - - return provider; -end - -module:add_item("auth-provider", new_external_provider(host)); \ No newline at end of file diff --git a/install/apps/xmpp_libs/mod_discoitems.lua b/install/apps/xmpp_libs/mod_discoitems.lua deleted file mode 100644 index f05b90490..000000000 --- a/install/apps/xmpp_libs/mod_discoitems.lua +++ /dev/null @@ -1,24 +0,0 @@ --- * Metronome IM * --- --- This file is part of the Metronome XMPP server and is released under the --- ISC License, please see the LICENSE file in this source package for more --- information about copyright and licensing. --- --- As per the sublicensing clause, this file is also MIT/X11 Licensed. --- ** Copyright (c) 2009, Waqas Hussain - -local st = require "util.stanza"; - -local result_query = st.stanza("query", {xmlns = "http://jabber.org/protocol/disco#items"}); -for _, item in ipairs(module:get_option("disco_items") or {}) do - result_query:tag("item", {jid = item[1], name = item[2]}):up(); -end - -module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) - local stanza = event.stanza; - local query = stanza.tags[1]; - if stanza.attr.type == "get" and not query.attr.node then - event.origin.send(st.reply(stanza):add_child(result_query)); - return true; - end -end, 100); diff --git a/install/apps/xmpp_libs/mod_webpresence/icons/status_away.png b/install/apps/xmpp_libs/mod_webpresence/icons/status_away.png deleted file mode 100644 index 0de5c6ab3d35e958b2c2c9fa9ee6e5876312b54b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 948 zcmV;l155mgP)*sU#JepF9xjFpi<1dH&*($&0tPbjKK|H0#rd|Dym~9=~^ZBK- zbGzC-yt{5wxNLFa=+nzG+x(``0F-p`vJReOGa7fjv$t};?MarraO%VvcNXui+Z2Ab zc;a$-iMCXj7MgA_iya$jr;+Jt?!*%OIGopiF8Ofe)QK}n06Y?!`l`HGEfrP(JunY_ z-hA|64!S>xumT9vV)(9L$2UQWeX-IA18o4}z^<}w8;jE0HN%H6O@tM|2;`s#b7r8= zL}~^f{FF=A#VfSjSk9W9k)5wRU;d~tReD!A;0c646FQn$sd_VSuNx%j zgRqfWCh{z|P)SKD<KWE7c7kVzzXr!C3B<~Dx5(8b^{$JrjSQPKrq%GQK2KCMN^V(Eo_ z69sgBc#zhk&AfN=5T4Sg-+LI>b@`<6HI7sz@EivvB>=b6zNitieFOPsCi3F)5%$!- z%158J(5hf~=oafYJV{N}6YQ%PM|U$w#|A(ujS)LApodE$e};(HRTQN}bYzh4FaAw^ zLn9kDZf0-8>ud>LU_~g6m$Bi$H6Fi_uezgo^?L7LL!*bj{CdS>dE+Zr=GzSP_tAB2 zg7{>dp>qd#?x9Ik)&XYVU^2iL*9zKue!ae5Q%X@?vsEjyulLnPMoSm_GaS2`N6)au zk!Qx3S@}$Q<3T?AJv0;#7Og(t*&UlbMs>|rL);l?tGqw9qhiUFurwD#%%I7v$#?zp zRr}2ar~TpkYR`9e$Nu-Kds$nys?v{L`#_GpD%Z>wj!ye--@I#HmcrL@+$DHi3p2pKey{piC67(I&w7*W40lyU(UA}K6MAl4+&=mayV7(EwVeII`~vKc@F)NSI^K=n$$(jK%fMr$ux`_Q@w ztvrC6mKGZ=&2IMZjc+>e>c-Ci)aR|+cfYhRFZ_^awM}auHtj_z50J&OVp!IFPM^NP zh7Ipv7!D$lCj6DT^rderD|C5T?!}b_hD~9hZ~)8Dx)7xbP|8Jrf1GHviiU>0^!9e~ z>~m@AcO_lv*+jEpw`Xg?LdXGGAcJKkfh@`76sJzzrnB=$x_iE2b?I-^)L4jQC@sy@ z8Y`A(%0)7Cca2b7JWc&GPL#|87Dtc%z{!(m85l#>)q`(bi@lk^s^Gm)`U`9$H&3 z5R26j3U$!g*}+=>Ab~&%%Ss?J1;DML72KVmkKp@tzR0zrl$ls1hYwfE)vI9<5g8sH zlE%h$l1P?`nea&5R1!ClxQQHUD#`_F9^Q?J(DKpx(ESHmCS!T>+Uw;KiCmFAdmfR$ z#|tEGy8c6P6Y1(Mkag?Vek~#(B8UhdobdPE{>v`^M3H^_i{z)D^%4{}k)BI#*|OC) z`s7n}-X&N>c%!MR?cz6{`Fjs+OVGezo&?`5l&X#8;RPrn|G#RX&08M}EYF(_R#ePZ uFLPymqht2i$cXKxVRv2|?7#Kp;_bh*VwXTL_!Tn%0000`8bWHC5+ah88qqRn1%uG& zQcS>)O*AW4Ao#$6ck%vS9(bOkM1-CC@Ri0pd&=&tEz9Rq??+mg<*upy)XM9hfAsy2U+>&i z+wkexqr=ZOmp_|ougzo%B?uu1u8fpLU^&=$`-y#57AFs$xO#csKZZ}w937ro{^Rb8 z;n8@SX%eFW@GjCTBSpv4X$LxO&$oL=7k)eP+@Y(N=fwaVXs%v(!L`O~eTJ-_U~L7v zUPP%t41#xp>nW!Ge0XrJo?ilvC;sNOnU^;nelS>5Dz7KxeTI77VAJYAj6(2&_Yv;| z?;>`qeCCrIU(OrT-a0!Nz1G^I6NNFFTAmEG&1m_Fx5mtw+ua~GJNp2j(ca}MwQ ze`fDJpPoO@#@rkOJvVB$0wDw;#)!2RYc2n$4Cn_QD5cG&N>*y68$5URT|Uk;v;veu z0f-<1L_tJ|5!RaPoB>*?T`{dRTb%8=L$9tck=8WEYLY}DKn#NGRauwaK)2%&fv6Rm zefeUt|M1iIv*x2yL!Cm$P_?Scw1Rp?pezDK5!i0>cl-9r{o$eam56Y>G5N(C_ZE(2 zI+7S&S>KiMzx`jU=UjYh?Aon+zrU#g%E^fn*C)mo)|2!fd(|t8xC?yHU+2om@KQQ9 za%$JdcTCouZNV+~{U%S69;Xu4MMBpMUt};?CW_0VwBr-clcF`v3p{07*qoM6N<$g4nQ! A4FCWD diff --git a/install/apps/xmpp_libs/mod_webpresence/icons/status_offline.png b/install/apps/xmpp_libs/mod_webpresence/icons/status_offline.png deleted file mode 100644 index 12db2af7dd86308f5abed00e3930d7f961e1ecc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 905 zcmV;419tq0P)DbaPEbUMxW_&6gYBRGzO@B5fW zFg`H!@q0C%>wm55hMLJ_n4FwsaBz_J_I5@`N3m_2?(S~l@i?heist5KbX`YEsU04d zzEKsFn*gy`jQRO_rlzLo=;&Z&Wrd!e9;TW3iqqHf*4 z0Yys5M|VH?-j3WD_B@YVE{CeBw6(RNX&S!oBZT1m{2br+sjV}4@y}mBZmp+>RDf{Q zdUSYP_(M^krKJViwh=<$y6zPq%d!Xr3|{2^&P5vP6IbuK{Oq}Gc&q+a;qc$3*X0Xg zS;04!CWOz+!-D)Xn^}oOt)5?g{`KgMRaJH8{o9`iUpz64z-?8jX>#4l%X0bkmRh5( fq&N4zyPo|Isjz3R!I6nX00000NkvXXu0mjf4oJCl diff --git a/install/apps/xmpp_libs/mod_webpresence/icons/status_online.png b/install/apps/xmpp_libs/mod_webpresence/icons/status_online.png deleted file mode 100644 index fb257c3144736fd691d81ac82242f7d51f909679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 920 zcmV;J184k+P)vhH8 z7nhD)JG**T`48N8ct_-JduBA-GrtSJ*LNKkX-S-#gD>Ng8!xW^=Fz{}UK=}k#$EyU zy}cun>iPR>;fZ3i&;>#j07zRRmnC-9#xWi2tj)%2(LcLV+qRCKJmU(0+16ZQv8&Lm z8Y)^qL#um`K@HVVQFRq1uMi##GaJse-D*so01(^X@7|T|ntNGj0-+03zxohR=mLSD zd9<0ypC{=U?;ySD-mAT@Kl_v@iPB*!WD7+oC_+JK!ecX36wT|^e_l^wFo9thl&vyL zttEBN&3~X(0<|r;;JPljcp@!Jz^lc$VBeN~#Cl@%?dfBB_cRz#4w|jPsmMbs54XP*)KmE?U-*_*jCwG;dbga3l|qyyuZlsm0=3c6;{*-2+RkF{_wH0Cjj3Dz^v<@`LN&rag)ycKGH+!-`QHe2cY{REu1UALo4Y5@CG#uBi0|F0 z{ZUSxn0q|`O5w4Buv8mV4`i4+4Zk+Hk6a3Uzo~J<{)uzR{6nrnu(-ldf@P|izNq=lxIHpFLiWTEVPV4m}8 zntOR)j+04Pq>?7Nti#ytMR7T4W1BgLoMB^R9O`6)^u=kS(I^1HV34loc5sjYhUH+J z*Q?W#B)e*Zfu1#~R1gV-fKLq{kvHDqflUp(*wck!7<4`T41rK3@BVO-yBFekfXTvw zStYJ&Guez?0dU&!ptrTry0x9p4t_-5&)@UY$zdi&M%c6e0Cyh$k>>h(cFxCG)V(uO zb{CXi)%+(Ath; z8KdUG*(>GS&R-zG^+k+jCnyFk=V=@*TrsPb6m7rd7_IG%O7`5$;qcX1+xmsLteVzM zG3`+q59Eu90{^l6J63m}7(NxdMZS@m`@)YZnQV7aIve)p%;H7WJ$F@ACxzzzcIvl3 c`]].. - tostring( - stanza("html") - :tag("head") - :tag("title"):text("XMPP Status Page for "..jid):up():up() - :tag("body") - :tag("div", { id = jid_hash.."_status", class = "xmpp_status" }) - :tag("img", { id = jid_hash.."_img", class = "xmpp_status_image xmpp_status_"..status, - src = "data:image/png;base64,"..b64(require_resource("status_"..status..".png")) }):up() - :tag("span", { id = jid_hash.."_status_name", class = "xmpp_status_name" }) - :text("\194\160"..status):up() - :tag("span", { id = jid_hash.."_status_message", class = "xmpp_status_message" }) - :text(message and "\194\160"..message.."" or "") - ) - }; - end; - statuses[status].text = function() - return { status_code = 200, headers = { content_type = "text/plain" }, - body = status - }; - end; - statuses[status].message = function() - return { status_code = 200, headers = { content_type = "text/plain" }, - body = (message and message or "") - }; - end; - statuses[status].json = function() - return { status_code = 200, headers = { content_type = "application/json" }, - body = json({ - jid = jid, - show = status, - status = (message and message or "null") - }) - }; - end; - statuses[status].xml = function() - return { status_code = 200, headers = { content_type = "application/xml" }, - body = [[]].. - tostring( - stanza("result") - :tag("jid"):text(jid):up() - :tag("show"):text(status):up() - :tag("status"):text(message) - ) - }; - end - - if ((type == "") or (not statuses[status][type])) then - type = "image" - end; - - return statuses[status][type](); -end - -module:provides("http", { - default_path = "/status"; - route = { - ["GET /*"] = handle_request; - }; -}); diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index 01c275bd5..18b54cb4e 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -226,18 +226,5 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['metronome']['installed'] = false; -$conf['metronome']['init_script'] = 'metronome'; -$conf['metronome']['initial_modules'] = 'saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons'; - -//* Prosody XMPP -$conf['prosody']['installed'] = false; -$conf['prosody']['init_script'] = 'prosody'; -$conf['prosody']['storage_database'] = 'prosody'; -$conf['prosody']['storage_user'] = 'prosody'; -$conf['prosody']['storage_password'] = md5(uniqid(rand())); -$conf['prosody']['initial_modules'] = 'roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access'; - ?> diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index 58aeff243..68a47a04f 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -226,17 +226,4 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['metronome']['installed'] = false; -$conf['metronome']['init_script'] = 'metronome'; -$conf['metronome']['initial_modules'] = 'saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons'; - -//* Prosody XMPP -$conf['prosody']['installed'] = false; -$conf['prosody']['init_script'] = 'prosody'; -$conf['prosody']['storage_database'] = 'prosody'; -$conf['prosody']['storage_user'] = 'prosody'; -$conf['prosody']['storage_password'] = md5(uniqid(rand())); -$conf['prosody']['initial_modules'] = 'roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access'; - ?> diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index 4ad9b1732..2f911afdd 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -226,18 +226,5 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['metronome']['installed'] = false; -$conf['metronome']['init_script'] = 'metronome'; -$conf['metronome']['initial_modules'] = 'saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons'; - -//* Prosody XMPP -$conf['prosody']['installed'] = false; -$conf['prosody']['init_script'] = 'prosody'; -$conf['prosody']['storage_database'] = 'prosody'; -$conf['prosody']['storage_user'] = 'prosody'; -$conf['prosody']['storage_password'] = md5(uniqid(rand())); -$conf['prosody']['initial_modules'] = 'roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access'; - ?> diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index 6159638d0..ea07eb54e 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -226,18 +226,5 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['metronome']['installed'] = false; -$conf['metronome']['init_script'] = 'metronome'; -$conf['metronome']['initial_modules'] = 'saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons'; - -//* Prosody XMPP -$conf['prosody']['installed'] = false; -$conf['prosody']['init_script'] = 'prosody'; -$conf['prosody']['storage_database'] = 'prosody'; -$conf['prosody']['storage_user'] = 'prosody'; -$conf['prosody']['storage_password'] = md5(uniqid(rand())); -$conf['prosody']['initial_modules'] = 'roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access'; - ?> diff --git a/install/dist/conf/ubuntu1710.conf.php b/install/dist/conf/ubuntu1710.conf.php index e04f4116f..4f260b0ff 100644 --- a/install/dist/conf/ubuntu1710.conf.php +++ b/install/dist/conf/ubuntu1710.conf.php @@ -222,18 +222,4 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['metronome']['installed'] = false; -$conf['metronome']['init_script'] = 'metronome'; -$conf['metronome']['initial_modules'] = 'saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons'; - -//* Prosody XMPP -$conf['prosody']['installed'] = false; -$conf['prosody']['init_script'] = 'prosody'; -$conf['prosody']['storage_database'] = 'prosody'; -$conf['prosody']['storage_user'] = 'prosody'; -$conf['prosody']['storage_password'] = md5(uniqid(rand())); -$conf['prosody']['initial_modules'] = 'roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access'; - - ?> diff --git a/install/dist/conf/ubuntu1804.conf.php b/install/dist/conf/ubuntu1804.conf.php index 15cdb1c5e..c2c6021c9 100644 --- a/install/dist/conf/ubuntu1804.conf.php +++ b/install/dist/conf/ubuntu1804.conf.php @@ -222,9 +222,5 @@ $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; -//* Metronome XMPP -$conf['xmpp']['installed'] = false; -$conf['xmpp']['init_script'] = 'metronome'; - ?> \ No newline at end of file diff --git a/install/install.php b/install/install.php index 524918454..faa1463d7 100644 --- a/install/install.php +++ b/install/install.php @@ -255,7 +255,6 @@ $conf['services']['db'] = true; $conf['services']['vserver'] = false; $conf['services']['firewall'] = false; $conf['services']['proxy'] = false; -$conf['services']['xmpp'] = false; //** Get Server ID // $conf['server_id'] = $inst->free_query('Unique Numeric ID of the server','1'); @@ -520,22 +519,6 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Fire } } -if($install_mode == 'standard' || strtolower($inst->simple_query('Configure XMPP Server', array('y', 'n') , 'y','configure_xmpp') ) == 'y') { -//* Configure XMPP Metronome - if ($conf['metronome']['installed']) { - swriteln('Configuring Metronome XMPP Server'); - $inst->configure_metronome(); - $conf['services']['xmpp'] = true; - } - -//* Configure XMPP Prosody - if ($conf['prosody']['installed']) { - swriteln('Configuring Prosody XMPP Server'); - $inst->configure_prosody(); - $conf['services']['xmpp'] = true; - } -} - //* Configure Fail2ban $force = @($conf['fail2ban']['installed']) ? true : $inst->force_configure_app('Fail2ban', ($install_mode == 'expert')); if($force) { diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 6011a2c4a..b1b5dff70 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -341,9 +341,6 @@ class installer_base { $tpl_ini_array['web']['php_fpm_start_port'] = $conf['nginx']['php_fpm_start_port']; $tpl_ini_array['web']['php_fpm_socket_dir'] = $conf['nginx']['php_fpm_socket_dir']; - $tpl_ini_array['xmpp']['xmpp_daemon'] = ($conf['metronome']['installed'] == true)?'metronome':'prosody'; - $tpl_ini_array['xmpp']['xmpp_modules_enabled'] = $conf[$tpl_ini_array['xmpp']['xmpp_daemon']]['initial_modules']; - if ($conf['nginx']['installed'] == true) { $tpl_ini_array['web']['server_type'] = 'nginx'; $tpl_ini_array['global']['webserver'] = 'nginx'; @@ -1722,215 +1719,6 @@ class installer_base { $this->process_bind_file('named.conf.options', '/etc/bind/', true); //TODO replace hardcoded path } - - public function configure_metronome($options = '') { - global $conf; - - if($conf['metronome']['installed'] == false) return; - //* Create the logging directory for xmpp server - if(!@is_dir('/var/log/metronome')) mkdir('/var/log/metronome', 0755, true); - chown('/var/log/metronome', 'metronome'); - if(!@is_dir('/var/run/metronome')) mkdir('/var/run/metronome', 0755, true); - chown('/var/run/metronome', 'metronome'); - if(!@is_dir('/var/lib/metronome')) mkdir('/var/lib/metronome', 0755, true); - chown('/var/lib/metronome', 'metronome'); - if(!@is_dir('/etc/metronome/hosts')) mkdir('/etc/metronome/hosts', 0755, true); - if(!@is_dir('/etc/metronome/status')) mkdir('/etc/metronome/status', 0755, true); - unlink('/etc/metronome/metronome.cfg.lua'); - - $row = $this->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $conf["server_id"]); - $server_name = $row["server_name"]; - - $tpl = new tpl('xmpp_metronome_conf_main.master'); - wf('/etc/metronome/metronome.cfg.lua', $tpl->grab()); - unset($tpl); - - $tpl = new tpl('xmpp_metronome_conf_global.master'); - $tpl->setVar('xmpp_admins',''); - wf('/etc/metronome/global.cfg.lua', $tpl->grab()); - unset($tpl); - - // Copy isp libs - if(!@is_dir('/usr/lib/metronome/isp-modules')) mkdir('/usr/lib/metronome/isp-modules', 0755, true); - caselog('cp -rf apps/xmpp_libs/* /usr/lib/metronome/isp-modules/', __FILE__, __LINE__); - caselog('chmod 755 /usr/lib/metronome/isp-modules/mod_auth_external/authenticate_isp.sh', __FILE__, __LINE__); - // Process db config - $full_file_name = '/usr/lib/metronome/isp-modules/mod_auth_external/db_conf.inc.php'; - $content = rf($full_file_name); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - $content = str_replace('{server_id}', $conf['server_id'], $content); - wf($full_file_name, $content); - - if(!stristr($options, 'dont-create-certs')){ - // Create SSL Certificate for localhost - // Ensure no line is left blank - echo "writing new private key to 'localhost.key'\n-----\n"; - $ssl_country = $this->free_query('Country Name (2 letter code)', 'AU','ssl_cert_country'); - $ssl_locality = $this->free_query('Locality Name (eg, city)', 'City Name','ssl_cert_locality'); - $ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd','ssl_cert_organisation'); - $ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', 'Infrastructure','ssl_cert_organisation_unit'); - $ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname'],'ssl_cert_common_name'); - $ssl_email = $this->free_query('Email Address', 'hostmaster@'.$conf['hostname'],'ssl_cert_email'); - - $tpl = new tpl('xmpp_conf_ssl.master'); - $tpl->setVar('ssl_country',$ssl_country); - $tpl->setVar('ssl_locality',$ssl_locality); - $tpl->setVar('ssl_organisation',$ssl_organisation); - $tpl->setVar('ssl_organisation_unit',$ssl_organisation_unit); - $tpl->setVar('domain',$ssl_domain); - $tpl->setVar('ssl_email',$ssl_email); - wf('/etc/metronome/certs/localhost.cnf', $tpl->grab()); - unset($tpl); - // Generate new key, csr and cert - exec("(cd /etc/metronome/certs && make localhost.key)"); - exec("(cd /etc/metronome/certs && make localhost.csr)"); - exec("(cd /etc/metronome/certs && make localhost.cert)"); - exec('chmod 0400 /etc/metronome/certs/localhost.key'); - exec('chown metronome /etc/metronome/certs/localhost.key'); - - echo "IMPORTANT:\n"; - echo "Localhost Key, Csr and a self-signed Cert have been saved to /etc/metronome/certs\n"; - echo "In order to work with all clients, the server must have a trusted certificate, so use the Csr\n"; - echo "to get a trusted certificate from your CA or replace Key and Cert with already signed files for\n"; - echo "your domain. Clients like Pidgin dont allow to use untrusted self-signed certificates.\n"; - echo "\n"; - - }else{ - /* - echo "-----\n"; - echo "Metronome XMPP SSL server certificate is not renewed. Run the following command manual as root to recreate it:\n"; - echo "# (cd /etc/metronome/certs && make localhost.key && make localhost.csr && make localhost.cert && chmod 0400 localhost.key && chown metronome localhost.key)\n"; - echo "-----\n"; - */ - } - - // Copy init script - caselog('cp -f apps/metronome-init /etc/init.d/metronome', __FILE__, __LINE__); - caselog('chmod u+x /etc/init.d/metronome', __FILE__, __LINE__); - caselog('update-rc.d metronome defaults', __FILE__, __LINE__); - - exec($this->getinitcommand($conf['metronome']['init_script'], 'restart')); - } - - public function configure_prosody($options = '') { - global $conf; - - if($conf['prosody']['installed'] == false) return; - //* Create the logging directory for xmpp server - if(!@is_dir('/var/log/prosody')) mkdir('/var/log/prosody', 0755, true); - chown('/var/log/prosody', 'prosody'); - if(!@is_dir('/var/run/prosody')) mkdir('/var/run/prosody', 0755, true); - chown('/var/run/prosody', 'prosody'); - if(!@is_dir('/var/lib/prosody')) mkdir('/var/lib/prosody', 0755, true); - chown('/var/lib/prosody', 'prosody'); - if(!@is_dir('/etc/prosody/hosts')) mkdir('/etc/prosody/hosts', 0755, true); - if(!@is_dir('/etc/prosody/status')) mkdir('/etc/prosody/status', 0755, true); - unlink('/etc/prosody/prosody.cfg.lua'); - - $tpl = new tpl('xmpp_prosody_conf_main.master'); - wf('/etc/prosody/prosody.cfg.lua', $tpl->grab()); - unset($tpl); - - $tpl = new tpl('xmpp_prosody_conf_global.master'); - $tpl->setVar('main_host', $conf['hostname']); - $tpl->setVar('xmpp_admins',''); - wf('/etc/prosody/global.cfg.lua', $tpl->grab()); - unset($tpl); - - //** Create the database - if(!$this->db->query('CREATE DATABASE IF NOT EXISTS ?? DEFAULT CHARACTER SET ?', $conf['prosody']['storage_database'], $conf['mysql']['charset'])) { - $this->error('Unable to create MySQL database: '.$conf['prosody']['storage_database'].'.'); - } - if($conf['mysql']['host'] == 'localhost') { - $from_host = 'localhost'; - } else { - $from_host = $conf['hostname']; - } - $this->dbmaster->query("CREATE USER ?@? IDENTIFIED BY ?", $conf['prosody']['storage_user'], $from_host, $conf['prosody']['storage_password']); // ignore the error - $query = 'GRANT ALL PRIVILEGES ON ?? TO ?@? IDENTIFIED BY ?'; - if(!$this->db->query($query, $conf['prosody']['storage_database'] . ".*", $conf['prosody']['storage_user'], $from_host, $conf['prosody']['storage_password'])) { - $this->error('Unable to create database user: '.$conf['prosody']['storage_user'].' Error: '.$this->db->errorMessage); - } - - - - $tpl = new tpl('xmpp_prosody_conf_storage.master'); - $tpl->setVar('db_name', $conf['prosody']['storage_database']); - $tpl->setVar('db_host', $conf['mysql']['host']); - $tpl->setVar('db_port', $conf['mysql']['port']); - $tpl->setVar('db_username', $conf['prosody']['storage_user']); - $tpl->setVar('db_password', $conf['prosody']['storage_password']); - wf('/etc/prosody/storage.cfg.lua', $tpl->grab()); - unset($tpl); - - - // Copy isp libs - if(!@is_dir('/usr/local/lib/prosody/auth')) mkdir('/usr/local/lib/prosody/auth', 0755, true); - caselog('cp -rf apps/xmpp_libs/auth_prosody/* /usr/local/lib/prosody/auth/', __FILE__, __LINE__); - caselog('chmod 755 /usr/local/lib/prosody/auth/authenticate_isp.sh', __FILE__, __LINE__); - caselog('chown root:ispconfig /usr/local/lib/prosody/auth/prosody-purge', __FILE__, __LINE__); - caselog('chmod 750 /usr/local/lib/prosody/auth/prosody-purge', __FILE__, __LINE__); - - // Process db config - $full_file_name = '/usr/local/lib/prosody/auth/db_conf.inc.php'; - $content = rf($full_file_name); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - $content = str_replace('{server_id}', $conf['server_id'], $content); - wf($full_file_name, $content); - - if(!stristr($options, 'dont-create-certs')){ - // Create SSL Certificate for localhost - // Ensure no line is left blank - echo "writing new private key to 'localhost.key'\n-----\n"; - $ssl_country = $this->free_query('Country Name (2 letter code)', 'AU','ssl_cert_country'); - $ssl_locality = $this->free_query('Locality Name (eg, city)', 'City Name','ssl_cert_locality'); - $ssl_organisation = $this->free_query('Organization Name (eg, company)', 'Internet Widgits Pty Ltd','ssl_cert_organisation'); - $ssl_organisation_unit = $this->free_query('Organizational Unit Name (eg, section)', 'Infrastructure','ssl_cert_organisation_unit'); - $ssl_domain = $this->free_query('Common Name (e.g. server FQDN or YOUR name)', $conf['hostname'],'ssl_cert_common_name'); - $ssl_email = $this->free_query('Email Address', 'hostmaster@'.$conf['hostname'],'ssl_cert_email'); - - $tpl = new tpl('xmpp_prosody_conf_ssl.master'); - $tpl->setVar('ssl_country',$ssl_country); - $tpl->setVar('ssl_locality',$ssl_locality); - $tpl->setVar('ssl_organisation',$ssl_organisation); - $tpl->setVar('ssl_organisation_unit',$ssl_organisation_unit); - $tpl->setVar('domain',$ssl_domain); - $tpl->setVar('ssl_email',$ssl_email); - wf('/etc/prosody/certs/localhost.cnf', $tpl->grab()); - unset($tpl); - // Generate new key, csr and cert - exec("(cd /etc/prosody/certs && make localhost.key)"); - exec("(cd /etc/prosody/certs && make localhost.csr)"); - exec("(cd /etc/prosody/certs && make localhost.crt)"); - exec('chmod 0400 /etc/prosody/certs/localhost.key'); - exec('chown prosody /etc/prosody/certs/localhost.key'); - - echo "IMPORTANT:\n"; - echo "Localhost Key, Csr and a self-signed Cert have been saved to /etc/prosody/certs\n"; - echo "In order to work with all clients, the server must have a trusted certificate, so use the Csr\n"; - echo "to get a trusted certificate from your CA or replace Key and Cert with already signed files for\n"; - echo "your domain. Clients like Pidgin dont allow to use untrusted self-signed certificates.\n"; - echo "\n"; - - }else{ - /* - echo "-----\n"; - echo "Prosody XMPP SSL server certificate is not renewed. Run the following command manual as root to recreate it:\n"; - echo "# (cd /etc/prosody/certs && make localhost.key && make localhost.csr && make localhost.cert && chmod 0400 localhost.key && chown prosody localhost.key)\n"; - echo "-----\n"; - */ - } - - exec($this->getinitcommand($conf['prosody']['init_script'], 'restart')); - } - - public function configure_apache() { global $conf; @@ -2602,9 +2390,8 @@ class installer_base { $vserver_server_enabled = ($conf['openvz']['installed'])?1:0; $proxy_server_enabled = ($conf['services']['proxy'])?1:0; $firewall_server_enabled = ($conf['services']['firewall'])?1:0; - $xmpp_server_enabled = ($conf['services']['xmpp'])?1:0; - $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled', xmpp_server = '$xmpp_server_enabled' WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled WHERE server_id = ?"; $this->db->query($sql, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index f410722c4..3406b760b 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -352,8 +352,6 @@ function updateDbAndIni() { $tpl_ini_array['web']['php_fpm_start_port'] = $conf['nginx']['php_fpm_start_port']; $tpl_ini_array['web']['php_fpm_socket_dir'] = $conf['nginx']['php_fpm_socket_dir']; - $tpl_ini_array['xmpp']['xmpp_daemon'] = ($conf['metronome']['installed'] == true)?'metronome':'prosody'; - if ($conf['nginx']['installed'] == true) { $tpl_ini_array['web']['server_type'] = 'nginx'; $tpl_ini_array['global']['webserver'] = 'nginx'; diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index b6a8b8b42..e6c44613e 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -155,14 +155,3 @@ try_rescue=n do_not_try_rescue_httpd=n do_not_try_rescue_mysql=n do_not_try_rescue_mail=n - -[xmpp] -xmpp_daemon=prosody -xmpp_use_ispv6=n -xmpp_bosh_max_inactivity=30 -xmpp_server_admins= -xmpp_modules_enabled=roster, saslauth, tls, dialback, disco, carbons, pep, private, blocklist, vcard, version, uptime, time, ping, admin_adhoc, mam, bosh, websocket, http_files, announce, proxy65, offline, posix, webpresence, smacks, csi_battery_saver, pep_vcard_avatar, omemo_all_access -xmpp_port_http=5290 -xmpp_port_https=5291 -xmpp_port_pastebin=5292 -xmpp_port_bosh=5280 diff --git a/install/tpl/xmpp_metronome_conf_global.master b/install/tpl/xmpp_metronome_conf_global.master deleted file mode 100644 index 68f4c59b6..000000000 --- a/install/tpl/xmpp_metronome_conf_global.master +++ /dev/null @@ -1,65 +0,0 @@ -pidfile = "/var/run/metronome/metronome.pid"; -metronome_max_files_soft = 200000; -metronome_max_files_hard = 300000; -plugin_paths = { - "/usr/lib/metronome/isp-modules", -}; -use_libevent = true; -log = { - debug = "/var/log/metronome/metronome.dbg", - info = "/var/log/metronome/metronome.log", - error = "/var/log/metronome/metronome.err", -}; -use_ipv6 = true; -http_ports = { - 5290, -}; -https_ports = { - 5291, -}; -pastebin_ports = { - 5292, -}; -bosh_ports = { - 5280, -}; -admins = { - {tmpl_var xmpp_admins} -}; -modules_enabled = { - "saslauth", - "tls", - "dialback", - "disco", - "discoitems", - "version", - "uptime", - "time", - "ping", - "admin_adhoc", - "admin_telnet", - "bosh", - "posix", - "announce", - "offline", - "webpresence", - "mam", - "stream_management", - "message_carbons" -}; -modules_disabled = { -}; -bosh_max_inactivity = 30; -consider_bosh_secure = true; -cross_domain_bosh = true; -allow_registration = false; -ssl = { - key = "/etc/metronome/certs/localhost.key", - certificate = "/etc/metronome/certs/localhost.cert", -}; -c2s_require_encryption = false; -s2s_secure = true; -s2s_insecure_domains = { - "gmail.com", -}; -authentication = "internal_plain"; diff --git a/install/tpl/xmpp_metronome_conf_main.master b/install/tpl/xmpp_metronome_conf_main.master deleted file mode 100644 index f9c8fbdd6..000000000 --- a/install/tpl/xmpp_metronome_conf_main.master +++ /dev/null @@ -1,3 +0,0 @@ -Include "/etc/metronome/global.cfg.lua" -Include "/etc/metronome/hosts/*.lua" -Include "/etc/metronome/status/*.lua" diff --git a/install/tpl/xmpp_metronome_conf_ssl.master b/install/tpl/xmpp_metronome_conf_ssl.master deleted file mode 100644 index 922dfd22a..000000000 --- a/install/tpl/xmpp_metronome_conf_ssl.master +++ /dev/null @@ -1,48 +0,0 @@ -oid_section = new_oids - -[ new_oids ] - -# RFC 3920 section 5.1.1 defines this OID -xmppAddr = 1.3.6.1.5.5.7.8.5 - -# RFC 4985 defines this OID -SRVName = 1.3.6.1.5.5.7.8.7 - -[ req ] - -default_bits = 4096 -default_keyfile = {tmpl_var name='domain'}.key -distinguished_name = distinguished_name -req_extensions = v3_extensions -x509_extensions = v3_extensions - -# ask about the DN? -prompt = no - -[ distinguished_name ] - -commonName = {tmpl_var name='domain'} -countryName = {tmpl_var name='ssl_country'} -localityName = {tmpl_var name='ssl_locality'} -organizationName = {tmpl_var name='ssl_organisation'} -organizationalUnitName = {tmpl_var name='ssl_organisation_unit'} -emailAddress = {tmpl_var name='ssl_email'} - -[ v3_extensions ] - -# for certificate requests (req_extensions) -# and self-signed certificates (x509_extensions) - -basicConstraints = CA:FALSE -keyUsage = digitalSignature,keyEncipherment -extendedKeyUsage = serverAuth,clientAuth -subjectAltName = @subject_alternative_name - -[ subject_alternative_name ] - -# See http://tools.ietf.org/html/draft-ietf-xmpp-3920bis#section-13.7.1.2 for more info. - -DNS.0 = {tmpl_var name='domain'} -otherName.0 = xmppAddr;FORMAT:UTF8,UTF8:{tmpl_var name='domain'} -otherName.1 = SRVName;IA5STRING:_xmpp-client.{tmpl_var name='domain'} -otherName.2 = SRVName;IA5STRING:_xmpp-server.{tmpl_var name='domain'} \ No newline at end of file diff --git a/install/tpl/xmpp_prosody_conf_global.master b/install/tpl/xmpp_prosody_conf_global.master deleted file mode 100644 index 14a0ae970..000000000 --- a/install/tpl/xmpp_prosody_conf_global.master +++ /dev/null @@ -1,94 +0,0 @@ -plugin_paths = { - "/usr/local/lib/prosody/modules", -}; -use_libevent = true; -log = { - -- optional: uncomment debug log here - -- debug = "/var/log/prosody/prosody.dbg", - info = "/var/log/prosody/prosody.log", - error = "/var/log/prosody/prosody.err", - "syslog", -}; -use_ipv6 = true; -http_ports = { - 5290, -}; -https_ports = { - 5291, -}; -pastebin_ports = { - 5292, -}; -bosh_ports = { - 5280, -}; -admins = { - {tmpl_var xmpp_admins} -}; -modules_enabled = { - "roster", - "saslauth", - "tls", - "dialback", - "disco", - "carbons", - "pep", - "private", - "blocklist", - "vcard", - "version", - "uptime", - "time", - "ping", - "admin_adhoc", - "mam", - "bosh", - "websocket", - "http_files", - "announce", - "proxy65", - "offline", - "posix", - "websocket", - -- community modules - "webpresence", - "smacks", - "csi_battery_saver", - "pep_vcard_avatar", - "omemo_all_access", -}; -modules_disabled = { -}; - -allow_registration = false; -c2s_require_encryption = false; -s2s_require_encryption = true; -s2s_secure_auth = false; -s2s_insecure_domains = { - "gmail.com", -}; - -pidfile = "/var/run/prosody/prosody.pid"; - -authentication = "external"; - -archive_expires_after = "2w"; - -statistics = "internal"; - -certificates = "certs"; -bosh_max_inactivity = 60; -consider_bosh_secure = true; -cross_domain_bosh = true; -consider_websocket_secure = true; - -ssl = { - key = "/etc/prosody/certs/localhost.key", - certificate = "/etc/prosody/certs/localhost.crt", -}; - -Component "{tmpl_var main_host}" "http_upload" - ud_disco_name = "HTTP File Upload"; - http_upload_file_size_limit = 1024 * 1024 * 10; - http_upload_quota = 1024 * 1024 * 10; - http_upload_expire_after = 60 * 60 * 24 * 2; \ No newline at end of file diff --git a/install/tpl/xmpp_prosody_conf_main.master b/install/tpl/xmpp_prosody_conf_main.master deleted file mode 100644 index 9c57f3292..000000000 --- a/install/tpl/xmpp_prosody_conf_main.master +++ /dev/null @@ -1,3 +0,0 @@ -Include "/etc/prosody/storage.cfg.lua" -Include "/etc/prosody/global.cfg.lua" -Include "/etc/prosody/hosts/*.lua" diff --git a/install/tpl/xmpp_prosody_conf_ssl.master b/install/tpl/xmpp_prosody_conf_ssl.master deleted file mode 100644 index 97b088a6a..000000000 --- a/install/tpl/xmpp_prosody_conf_ssl.master +++ /dev/null @@ -1,48 +0,0 @@ -oid_section = new_oids - -[ new_oids ] - -# RFC 3920 section 5.1.1 defines this OID -xmppAddr = 1.3.6.1.5.5.7.8.5 - -# RFC 4985 defines this OID -SRVName = 1.3.6.1.5.5.7.8.7 - -[ req ] - -default_bits = 4096 -default_keyfile = {tmpl_var name='domain'}.key -distinguished_name = distinguished_name -req_extensions = v3_extensions -x509_extensions = v3_extensions - -# ask about the DN? -prompt = no - -[ distinguished_name ] - -commonName = {tmpl_var name='domain'} -countryName = {tmpl_var name='ssl_country'} -localityName = {tmpl_var name='ssl_locality'} -organizationName = {tmpl_var name='ssl_organisation'} -organizationalUnitName = {tmpl_var name='ssl_organisation_unit'} -emailAddress = {tmpl_var name='ssl_email'} - -[ v3_extensions ] - -# for certificate requests (req_extensions) -# and self-signed certificates (x509_extensions) - -basicConstraints = CA:TRUE -keyUsage = digitalSignature,keyEncipherment -extendedKeyUsage = serverAuth,clientAuth -subjectAltName = @subject_alternative_name - -[ subject_alternative_name ] - -# See http://tools.ietf.org/html/draft-ietf-xmpp-3920bis#section-13.7.1.2 for more info. - -DNS.0 = {tmpl_var name='domain'} -otherName.0 = xmppAddr;FORMAT:UTF8,UTF8:{tmpl_var name='domain'} -otherName.1 = SRVName;IA5STRING:_xmpp-client.{tmpl_var name='domain'} -otherName.2 = SRVName;IA5STRING:_xmpp-server.{tmpl_var name='domain'} \ No newline at end of file diff --git a/install/tpl/xmpp_prosody_conf_storage.master b/install/tpl/xmpp_prosody_conf_storage.master deleted file mode 100644 index 217e5163b..000000000 --- a/install/tpl/xmpp_prosody_conf_storage.master +++ /dev/null @@ -1,9 +0,0 @@ -storage = "sql" -sql = { - driver = "MySQL"; - database = "{tmpl_var db_name}"; - host = "{tmpl_var db_host}"; - port = {tmpl_var db_port}; - username = "{tmpl_var db_username}"; - password = "{tmpl_var db_password}"; -} \ No newline at end of file diff --git a/install/update.php b/install/update.php index 3361c3c19..68c5b76cf 100644 --- a/install/update.php +++ b/install/update.php @@ -323,19 +323,18 @@ if($reconfigure_master_database_rights_answer == 'yes') { $inst->find_installed_apps(); //** Check for current service config state and compare to our results -if ($conf['mysql']['master_slave_setup'] == 'y') $current_svc_config = $inst->dbmaster->queryOneRecord("SELECT mail_server,web_server,dns_server,xmpp_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf['mysql']['master_database'] . '.server', $conf['server_id']); -else $current_svc_config = $inst->db->queryOneRecord("SELECT mail_server,web_server,dns_server,xmpp_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf["mysql"]["database"] . '.server', $conf['server_id']); +if ($conf['mysql']['master_slave_setup'] == 'y') $current_svc_config = $inst->dbmaster->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf['mysql']['master_database'] . '.server', $conf['server_id']); +else $current_svc_config = $inst->db->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf["mysql"]["database"] . '.server', $conf['server_id']); $conf['services']['mail'] = check_service_config_state('mail_server', $conf['postfix']['installed']); $conf['services']['dns'] = check_service_config_state('dns_server', ($conf['powerdns']['installed'] || $conf['bind']['installed'] || $conf['mydns']['installed'])); $conf['services']['web'] = check_service_config_state('web_server', ($conf['apache']['installed'] || $conf['nginx']['installed'])); -$conf['services']['xmpp'] = check_service_config_state('xmpp_server', $conf['metronome']['installed']); $conf['services']['firewall'] = check_service_config_state('firewall_server', ($conf['ufw']['installed'] || $conf['firewall']['installed'])); $conf['services']['vserver'] = check_service_config_state('vserver_server', $conf['services']['vserver']); $conf['services']['db'] = check_service_config_state('db_server', true); /* Will always offer as MySQL is of course installed on this host as it's a requirement for ISPC to work... */ unset($current_svc_config); //** Write new decisions into DB -$sql = "UPDATE ?? SET mail_server = '{$conf['services']['mail']}', web_server = '{$conf['services']['web']}', dns_server = '{$conf['services']['dns']}', file_server = '{$conf['services']['file']}', db_server = '{$conf['services']['db']}', vserver_server = '{$conf['services']['vserver']}', proxy_server = '{$conf['services']['proxy']}', firewall_server = '$firewall_server_enabled', xmpp_server = '$xmpp_server_enabled' WHERE server_id = ?"; +$sql = "UPDATE ?? SET mail_server = '{$conf['services']['mail']}', web_server = '{$conf['services']['web']}', dns_server = '{$conf['services']['dns']}', file_server = '{$conf['services']['file']}', db_server = '{$conf['services']['db']}', vserver_server = '{$conf['services']['vserver']}', proxy_server = '{$conf['services']['proxy']}', firewall_server = '$firewall_server_enabled' WHERE server_id = ?"; $inst->db->query($sql, $conf['mysql']['database'].'.server', $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { $inst->dbmaster->query($sql, $conf['mysql']['master_database'].'.server', $conf['server_id']); @@ -465,17 +464,6 @@ if($reconfigure_services_answer == 'yes' || $reconfigure_services_answer == 'sel } - if($conf['services']['xmpp'] && $inst->reconfigure_app('XMPP', $reconfigure_services_answer)) { - //** Configure Metronome XMPP - if($conf['prosody']['installed'] == true) { - swriteln('Configuring Prosody XMPP'); - $inst->configure_prosody('dont-create-certs'); - } elseif ($conf['metronome']['installed'] == true) { - swriteln('Configuring Metronome XMPP'); - $inst->configure_metronome('dont-create-certs'); - } - } - if($conf['services']['firewall'] && $inst->reconfigure_app('Firewall', $reconfigure_services_answer)) { if($conf['ufw']['installed'] == true) { //* Configure Ubuntu Firewall @@ -570,11 +558,7 @@ if($reconfigure_services_answer == 'yes') { if($conf['bind']['installed'] == true && $conf['bind']['init_script'] != '') system($inst->getinitcommand($conf['bind']['init_script'], 'restart').' &> /dev/null'); } - if($conf['services']['xmpp']) { - if($conf['metronome']['installed'] == true && $conf['metronome']['init_script'] != '') system($inst->getinitcommand($conf['metronome']['init_script'], 'restart').' &> /dev/null'); - } - - if($conf['services']['proxy']) { + if($conf['services']['proxy']) { // if($conf['squid']['installed'] == true && $conf['squid']['init_script'] != '' && is_executable($conf['init_scripts'].'/'.$conf['squid']['init_script'])) system($conf['init_scripts'].'/'.$conf['squid']['init_script'].' restart &> /dev/null'); if($conf['nginx']['installed'] == true && $conf['nginx']['init_script'] != '') system($inst->getinitcommand($conf['nginx']['init_script'], 'restart').' &> /dev/null'); } diff --git a/interface/lib/classes/custom_datasource.inc.php b/interface/lib/classes/custom_datasource.inc.php index cb4426a2e..f31296882 100644 --- a/interface/lib/classes/custom_datasource.inc.php +++ b/interface/lib/classes/custom_datasource.inc.php @@ -136,9 +136,6 @@ class custom_datasource { case 'default_dbserver': $field = 'db_server'; break; - case 'default_xmppserver': - $field = 'xmpp_server'; - break; case 'default_vserverserver': $field = 'vserver_server'; break; @@ -154,9 +151,6 @@ class custom_datasource { case 'db_servers': $field = 'db_server'; break; - case 'xmpp_servers': - $field = 'xmpp_server'; - break; default: $field = 'web_server'; break; diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php index 0a1f890b9..ef4483bce 100644 --- a/interface/lib/classes/remote.d/mail.inc.php +++ b/interface/lib/classes/remote.d/mail.inc.php @@ -311,7 +311,7 @@ class remoting_mail extends remoting { return $affected_rows; } - // Mail backup list function by Dominik Mller, info@profi-webdesign.net + // Mail backup list function by Dominik M�ller, info@profi-webdesign.net public function mail_user_backup_list($session_id, $primary_id = null) { global $app; @@ -334,7 +334,7 @@ class remoting_mail extends remoting { return $result; } - // Mail backup restore/download functions by Dominik Mller, info@profi-webdesign.net + // Mail backup restore/download functions by Dominik M�ller, info@profi-webdesign.net public function mail_user_backup($session_id, $primary_id, $action_type) { global $app; @@ -1105,172 +1105,5 @@ class remoting_mail extends remoting { return $app->quota_lib->get_mailquota_data($client_id, false); } - //** xmpp functions ----------------------------------------------------------------------------------- - - public function xmpp_domain_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'xmpp_domain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../mail/form/xmpp_domain.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); - } - - public function xmpp_domain_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'xmpp_domain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $primary_id = $this->insertQuery('../mail/form/xmpp_domain.tform.php', $client_id, $params); - return $primary_id; - } - - public function xmpp_domain_update($session_id, $client_id, $primary_id, $params) - { - if(!$this->checkPerm($session_id, 'xmpp_domain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../mail/form/xmpp_domain.tform.php', $client_id, $primary_id, $params); - return $affected_rows; - } - - public function xmpp_domain_delete($session_id, $primary_id) - { - if(!$this->checkPerm($session_id, 'xmpp_domain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../mail/form/xmpp_domain.tform.php', $primary_id); - return $affected_rows; - } - - public function xmpp_user_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'xmpp_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../mail/form/xmpp_user.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); - } - - public function xmpp_user_add($session_id, $client_id, $params){ - global $app; - - if (!$this->checkPerm($session_id, 'xmpp_user_add')){ - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - $jid_parts = explode('@', $params['jid']); - $tmp = $app->db->queryOneRecord("SELECT domain FROM xmpp_domain WHERE domain = ?", $jid_parts[1]); - if($tmp['domain'] != $jid_parts[1]) { - throw new SoapFault('xmpp_domain_does_not_exist', 'XMPP domain - '.$jid_parts[1].' - does not exist.'); - return false; - } - - $affected_rows = $this->insertQuery('../mail/form/xmpp_user.tform.php', $client_id, $params); - return $affected_rows; - } - - public function xmpp_user_update($session_id, $client_id, $primary_id, $params) - { - global $app; - - if (!$this->checkPerm($session_id, 'xmpp_user_update')) - { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - $jid_parts = explode('@', $jid_parts['jid']); - $tmp = $app->db->queryOneRecord("SELECT domain FROM xmpp_domain WHERE domain = ?", $jid_parts[1]); - if($tmp['domain'] != $jid_parts[1]) { - throw new SoapFault('xmpp_domain_does_not_exist', 'Mail domain - '.$jid_parts[1].' - does not exist.'); - return false; - } - - $affected_rows = $this->updateQuery('../mail/form/xmpp_user.tform.php', $client_id, $primary_id, $params); - return $affected_rows; - } - - public function xmpp_user_delete($session_id, $primary_id) - { - if (!$this->checkPerm($session_id, 'xmpp_user_delete')) - { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../mail/form/xmpp_user.tform.php', $primary_id); - return $affected_rows; - } - - public function xmpp_domain_get_by_domain($session_id, $domain) { - global $app; - if(!$this->checkPerm($session_id, 'xmpp_domain_get_by_domain')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if (!empty($domain)) { - $sql = "SELECT * FROM xmpp_domain WHERE domain = ?"; - $result = $app->db->queryAllRecords($sql, $domain); - return $result; - } - return false; - } - - public function xmpp_domain_set_status($session_id, $primary_id, $status) { - global $app; - if(!$this->checkPerm($session_id, 'xmpp_domain_set_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if(in_array($status, array('active', 'inactive'))) { - if ($status == 'active') { - $status = 'y'; - } else { - $status = 'n'; - } - $sql = "UPDATE xmpp_domain SET active = ? WHERE domain_id = ?"; - $app->db->query($sql, $status, $primary_id); - $result = $app->db->affectedRows(); - return $result; - } else { - throw new SoapFault('status_undefined', 'The status is not available'); - return false; - } - } - - public function xmpp_user_set_status($session_id, $primary_id, $status) { - global $app; - if(!$this->checkPerm($session_id, 'xmpp_user_set_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if(in_array($status, array('active', 'inactive'))) { - if ($status == 'active') { - $status = 'y'; - } else { - $status = 'n'; - } - $sql = "UPDATE xmpp_user SET active = ? WHERE xmppuser_id = ?"; - $app->db->query($sql, $status, $primary_id); - $result = $app->db->affectedRows(); - return $result; - } else { - throw new SoapFault('status_undefined', 'The status is not available'); - return false; - } - } - } -?> + diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index 4e8179d06..4f612c69c 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -228,7 +228,7 @@ class remoting_server extends remoting { return false; } if (!empty($session_id) && !empty($server_id)) { - $sql = "SELECT mail_server, web_server, dns_server, file_server, db_server, vserver_server, proxy_server, firewall_server, xmpp_server, mirror_server_id FROM server WHERE server_id = ?"; + $sql = "SELECT mail_server, web_server, dns_server, file_server, db_server, vserver_server, proxy_server, firewall_server, mirror_server_id FROM server WHERE server_id = ?"; $all = $app->db->queryOneRecord($sql, $server_id); return $all; } else { diff --git a/interface/lib/classes/validate_client.inc.php b/interface/lib/classes/validate_client.inc.php index 4652e2a07..980e6ffbb 100644 --- a/interface/lib/classes/validate_client.inc.php +++ b/interface/lib/classes/validate_client.inc.php @@ -124,9 +124,6 @@ class validate_client { $used_servers = $app->db->queryAllRecords('SELECT domain_id FROM mail_domain INNER JOIN sys_user ON mail_domain.sys_userid = sys_user.userid WHERE client_id = ? AND server_id NOT IN ?', $client_id, $field_value); break; - case 'xmpp_servers': - $used_servers = $app->db->queryAllRecords('SELECT domain_id FROM xmpp_domain INNER JOIN sys_user ON xmpp_domain.sys_userid = sys_user.userid WHERE client_id = ? AND server_id NOT IN ?', $client_id, $field_value); - break; } if ($used_servers === null || count($used_servers)) diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php index 95dca6c33..2c74e6785 100644 --- a/interface/web/admin/form/server.tform.php +++ b/interface/web/admin/form/server.tform.php @@ -108,12 +108,6 @@ $form["tabs"]['services'] = array ( 'default' => '0', 'value' => array(0 => 0, 1 => 1) ), - 'xmpp_server' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'CHECKBOX', - 'default' => '0', - 'value' => array(0 => 0, 1 => 1) - ), 'mirror_server_id' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index aa0e1188a..b2009d96c 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1618,104 +1618,6 @@ $form["tabs"]['fastcgi'] = array( ); -$form["tabs"]['xmpp'] = array( - 'title' => "XMPP", - 'width' => 80, - 'template' => "templates/server_config_xmpp_edit.htm", - 'fields' => array( - //################################# - // Begin Datatable fields - //################################# - 'xmpp_daemon' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => '20', - 'value' => array('prosody' => 'Prosody', 'metronome' => 'Metronome') - ), - 'xmpp_use_ipv6' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'xmpp_bosh_max_inactivity' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '30', - 'validators' => array(0 => array('type' => 'ISINT', - 'errmsg' => 'ip_address_error_wrong'), - array('type'=>'RANGE', 'range'=>'15:360', 'errmsg' => 'xmpp_bosh_timeout_range_wrong') - ), - 'value' => '', - 'width' => '15' - ), - - 'xmpp_server_admins' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'filters' => array( - 0 => array( 'event' => 'SAVE', - 'type' => 'STRIPTAGS'), - 1 => array( 'event' => 'SAVE', - 'type' => 'STRIPNL') - ), - 'default' => 'admin@service.com, superuser@service.com', - 'value' => '', - 'width' => '15' - ), - - 'xmpp_modules_enabled' => array( - 'datatype' => 'TEXT', - 'formtype' => 'TEXT', - 'filters' => array( - 0 => array( 'event' => 'SAVE', - 'type' => 'STRIPTAGS'), - 1 => array( 'event' => 'SAVE', - 'type' => 'STRIPNL') - ), - 'default' => "saslauth, tls, dialback, disco, discoitems, version, uptime, time, ping, admin_adhoc, admin_telnet, bosh, posix, announce, offline, webpresence, mam, stream_management, message_carbons", - 'value' => '', - 'separator' => "," - ), - - 'xmpp_port_http' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '5290', - 'validators' => array(0 => array('type' => 'ISINT')), - 'value' => '5290', - 'width' => '15' - ), - 'xmpp_port_https' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '5291', - 'validators' => array(0 => array('type' => 'ISINT')), - 'value' => '5291', - 'width' => '15' - ), - 'xmpp_port_pastebin' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '5292', - 'validators' => array(0 => array('type' => 'ISINT')), - 'value' => '5292', - 'width' => '15' - ), - 'xmpp_port_bosh' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '5280', - 'validators' => array(0 => array('type' => 'ISINT')), - 'value' => '5280', - 'width' => '15' - ), - //################################# - // ENDE Datatable fields - //################################# - ) -); - $form["tabs"]['jailkit'] = array( 'title' => "Jailkit", 'width' => 80, diff --git a/interface/web/admin/list/server.list.php b/interface/web/admin/list/server.list.php index 58779eec9..5a44a7a2b 100644 --- a/interface/web/admin/list/server.list.php +++ b/interface/web/admin/list/server.list.php @@ -110,13 +110,4 @@ $liste['item'][] = array( 'field' => 'vserver_server', 'width' => '', 'value' => array('1' => $app->lng('yes_txt'), '0' => $app->lng('no_txt'))); -$liste['item'][] = array( 'field' => 'xmpp_server', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => 'like', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => array('1' => $app->lng('yes_txt'), '0' => $app->lng('no_txt'))); - ?> diff --git a/interface/web/admin/templates/server_config_xmpp_edit.htm b/interface/web/admin/templates/server_config_xmpp_edit.htm deleted file mode 100644 index 70dedd1d4..000000000 --- a/interface/web/admin/templates/server_config_xmpp_edit.htm +++ /dev/null @@ -1,78 +0,0 @@ - -

- - -
- -
-
-
- -
- {tmpl_var name='xmpp_use_ipv6'} -
-
-
- -
- -
-
- -
- -
- -
-
- -
- -
-
-
-

{tmpl_var name='xmpp_ports_txt'}

-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
-
- -
- -
-
-
-
- - - -
- - -
diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm index 2775e029d..0ee07d020 100644 --- a/interface/web/admin/templates/server_edit_services.htm +++ b/interface/web/admin/templates/server_edit_services.htm @@ -44,13 +44,7 @@ {tmpl_var name='vserver_server'} -
- -
- {tmpl_var name='xmpp_server'} -
-
- +
{tmpl_var name='search_file_server'} - @@ -43,7 +41,6 @@ {tmpl_var name="file_server"} {tmpl_var name="db_server"} {tmpl_var name="vserver_server"} - {tmpl_var name="xmpp_server"} @@ -51,13 +48,13 @@ - {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - + diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index 09db5c1ff..23745a69e 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -924,118 +924,7 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'default_xmppserver' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'value' => '', - 'name' => 'default_xmppserver' - ), - 'xmpp_servers' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'MULTIPLE', - 'separator' => ',', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'validators' => array ( - 0 => array ( 'type' => 'CUSTOM', - 'class' => 'validate_client', - 'function' => 'check_used_servers', - 'errmsg'=> 'xmpp_servers_used'), - ), - 'value' => '', - 'name' => 'xmpp_servers' - ), - 'limit_xmpp_domain' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_domain_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_user' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_user_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_muc' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_anon' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_vjud' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_proxy' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_status' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_webpresence' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_http_upload' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_pastebin' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_httparchive' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'default_webserver' => array ( + 'default_webserver' => array ( 'datatype' => 'INTEGER', 'formtype' => 'SELECT', 'default' => '1', diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php index 2196ad4d0..dee369b0a 100644 --- a/interface/web/client/form/client_template.tform.php +++ b/interface/web/client/form/client_template.tform.php @@ -339,118 +339,8 @@ $form["tabs"]['limits'] = array ( 'maxlength' => '10', 'rows' => '', 'cols' => '' - ),/* - 'default_xmppserver' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'value' => '', - 'name' => 'default_xmppserver' - ),*/ - 'xmpp_servers' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'MULTIPLE', - 'separator' => ',', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'validators' => array ( - 0 => array ( 'type' => 'CUSTOM', - 'class' => 'validate_client', - 'function' => 'check_used_servers', - 'errmsg'=> 'xmpp_servers_used'), - ), - 'value' => '', - 'name' => 'xmpp_servers' - ), - 'limit_xmpp_domain' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_domain_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_user' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_user_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_muc' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_anon' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_vjud' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_proxy' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_status' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_webpresence' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_http_upload' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_pastebin' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_httparchive' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ),/* + ), + /* 'default_webserver' => array ( 'datatype' => 'INTEGER', 'formtype' => 'SELECT', diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index d5c22e206..e2db8a0f9 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -922,118 +922,7 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'default_xmppserver' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'value' => '', - 'name' => 'default_xmppserver' - ), - 'xmpp_servers' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'MULTIPLE', - 'separator' => ',', - 'default' => '1', - 'datasource' => array ( 'type' => 'CUSTOM', - 'class'=> 'custom_datasource', - 'function'=> 'client_servers' - ), - 'validators' => array ( - 0 => array ( 'type' => 'CUSTOM', - 'class' => 'validate_client', - 'function' => 'check_used_servers', - 'errmsg'=> 'xmpp_servers_used'), - ), - 'value' => '', - 'name' => 'xmpp_servers' - ), - 'limit_xmpp_domain' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_domain_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_user' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_xmpp_user_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_xmpp_muc' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_anon' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_vjud' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_proxy' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_status' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_webpresence' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_http_upload' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_pastebin' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'limit_xmpp_httparchive' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'default_webserver' => array ( + 'default_webserver' => array ( 'datatype' => 'INTEGER', 'formtype' => 'SELECT', 'default' => '1', diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index 83ba88d12..4f4a8f9e1 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -242,91 +242,7 @@
-
- -
-
-
- -
-
-
- -
-
- -
- -
- -
- {tmpl_var name='limit_xmpp_muc'} -
-
-
- -
- {tmpl_var name='limit_xmpp_pastebin'} -
-
-
- -
- {tmpl_var name='limit_xmpp_httparchive'} -
-
-
- -
- {tmpl_var name='limit_xmpp_anon'} -
-
-
- -
- {tmpl_var name='limit_xmpp_vjud'} -
-
-
- -
- {tmpl_var name='limit_xmpp_proxy'} -
-
-
- -
- {tmpl_var name='limit_xmpp_status'} -
-
-
- -
- {tmpl_var name='limit_xmpp_webpresence'} -
-
-
- -
- {tmpl_var name='limit_xmpp_http_upload'} -
-
-
-
-
+
-
- -
-
-
- -
-
-
- -
-
- -
- -
- -
- {tmpl_var name='limit_xmpp_muc'} -
-
-
- -
- {tmpl_var name='limit_xmpp_pastebin'} -
-
-
- -
- {tmpl_var name='limit_xmpp_httparchive'} -
-
-
- -
- {tmpl_var name='limit_xmpp_anon'} -
-
-
- -
- {tmpl_var name='limit_xmpp_vjud'} -
-
-
- -
- {tmpl_var name='limit_xmpp_proxy'} -
-
-
- -
- {tmpl_var name='limit_xmpp_status'} -
-
-
- -
- {tmpl_var name='limit_xmpp_webpresence'} -
-
-
- -
- {tmpl_var name='limit_xmpp_http_upload'} -
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
- -
- -
- -
- {tmpl_var name='limit_xmpp_muc'} -
-
-
- -
- {tmpl_var name='limit_xmpp_pastebin'} -
-
-
- -
- {tmpl_var name='limit_xmpp_httparchive'} -
-
-
- -
- {tmpl_var name='limit_xmpp_anon'} -
-
-
- -
- {tmpl_var name='limit_xmpp_vjud'} -
-
-
- -
- {tmpl_var name='limit_xmpp_proxy'} -
-
-
- -
- {tmpl_var name='limit_xmpp_status'} -
-
-
- -
- {tmpl_var name='limit_xmpp_webpresence'} -
-
-
- -
- {tmpl_var name='limit_xmpp_http_upload'} -
-
-
-
-
+
-
diff --git a/interface/web/monitor/lib/module.conf.php b/interface/web/monitor/lib/module.conf.php index 5b35053dc..1f40d7b4d 100644 --- a/interface/web/monitor/lib/module.conf.php +++ b/interface/web/monitor/lib/module.conf.php @@ -201,12 +201,6 @@ $items[] = array( 'title' => "Show fail2ban-Log", 'link' => 'monitor/show_data.php?type=fail2ban', 'html_id' => 'fai2ban'); -/* -$items[] = array( 'title' => "Show MongoDB-Log", - 'target' => 'content', - 'link' => 'monitor/show_data.php?type=mongodb', - 'html_id' => 'mongodb'); -*/ $items[] = array( 'title' => "Show IPTables", 'target' => 'content', 'link' => 'monitor/show_data.php?type=iptables', diff --git a/interface/web/monitor/show_data.php b/interface/web/monitor/show_data.php index 80f246ee2..9a5cafea4 100644 --- a/interface/web/monitor/show_data.php +++ b/interface/web/monitor/show_data.php @@ -138,15 +138,6 @@ case 'fail2ban': $description = ''; $add_padding = true; break; -/* -case 'mongodb': - $template = 'templates/show_data.htm'; - $output .= $app->tools_monitor->showMongoDB(); - $time = $app->tools_monitor->getDataTime('log_mongodb'); - $title = $app->lng("monitor_title_mongodb_txt") . ' (' . $monTransSrv . ' : ' . $_SESSION['monitor']['server_name'] . ')'; - $description = ''; - break; -*/ case 'iptables': $template = 'templates/show_data.htm'; $output .= $app->tools_monitor->showIPTables(); diff --git a/interface/web/sites/database_user_edit.php b/interface/web/sites/database_user_edit.php index 07fa1315f..6d18893e7 100644 --- a/interface/web/sites/database_user_edit.php +++ b/interface/web/sites/database_user_edit.php @@ -168,14 +168,6 @@ class page_action extends tform_actions { $this->dataRecord['database_user'] = substr($dbuser_prefix . $this->dataRecord['database_user'], 0, 16); } - /* prepare password for MongoDB */ - // TODO: this still doens't work as when only the username changes we have no database_password. - // taking the one from oldData doesn't work as it's encrypted...shit! -/* - $this->dataRecord['database_password_mongo'] = $this->dataRecord['database_user'].":mongo:".$this->dataRecord['database_password']; - - $this->dataRecord['server_id'] = 0; // we need this on all servers -*/ parent::onBeforeUpdate(); } @@ -211,9 +203,6 @@ class page_action extends tform_actions { $this->dataRecord['server_id'] = 0; // we need this on all servers - /* prepare password for MongoDB */ -// $this->dataRecord['database_password_mongo'] = $this->dataRecord['database_user'].":mongo:".$this->dataRecord['database_password']; - parent::onBeforeInsert(); } diff --git a/interface/web/sites/form/database.tform.php b/interface/web/sites/form/database.tform.php index 400854783..32d069450 100644 --- a/interface/web/sites/form/database.tform.php +++ b/interface/web/sites/form/database.tform.php @@ -90,7 +90,6 @@ $form["tabs"]['database'] = array ( 'formtype' => 'SELECT', 'default' => 'mysql', 'value' => array( - /*'mongo' => 'MongoDB',*/ 'mysql' => 'MySQL' ) ), diff --git a/interface/web/sites/form/database_user.tform.php b/interface/web/sites/form/database_user.tform.php index 09d2c32b2..6fc02dbe1 100644 --- a/interface/web/sites/form/database_user.tform.php +++ b/interface/web/sites/form/database_user.tform.php @@ -115,15 +115,7 @@ $form["tabs"]['database_user'] = array ( 'value' => '', 'width' => '30', 'maxlength' => '255' - ), - 'database_password_mongo' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'PASSWORD', - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255' - ), + ) //################################# // ENDE Datatable fields //################################# diff --git a/interface/web/sites/list/database.list.php b/interface/web/sites/list/database.list.php index 25e1b8de7..9684b2ac8 100644 --- a/interface/web/sites/list/database.list.php +++ b/interface/web/sites/list/database.list.php @@ -78,7 +78,6 @@ $liste["item"][] = array( 'field' => "type", 'suffix' => "", 'width' => "", 'value' => array( - 'mongo' => "MongoDB", 'mysql' => "MySQL" ) ); diff --git a/server/lib/classes/monitor_tools.inc.php b/server/lib/classes/monitor_tools.inc.php index 04f654ccd..1921851e3 100644 --- a/server/lib/classes/monitor_tools.inc.php +++ b/server/lib/classes/monitor_tools.inc.php @@ -454,16 +454,6 @@ class monitor_tools { $state = 'error'; // because service is down } } -/* - $data['mongodbserver'] = -1; - if ($this->_checkTcp('localhost', 27017)) { - $data['mongodbserver'] = 1; - } else { - $data['mongodbserver'] = 0; -*/ - //$state = 'error'; // because service is down - /* TODO!!! check if this is a mongodbserver at all, otherwise it will always throw an error state!!! */ -// } /* * Return the Result @@ -598,9 +588,6 @@ class monitor_tools { $logfile = '/var/log/fail2ban.log'; } break; - case 'log_mongodb': - $logfile = '/var/log/mongodb/mongodb.log'; - break; case 'log_ispconfig': if ($dist == 'debian') { $logfile = $conf['ispconfig_log_dir'] . '/ispconfig.log'; diff --git a/server/mods-available/rescue_core_module.inc.php b/server/mods-available/rescue_core_module.inc.php index 5e8f3db9c..a434a63a6 100644 --- a/server/mods-available/rescue_core_module.inc.php +++ b/server/mods-available/rescue_core_module.inc.php @@ -94,11 +94,6 @@ class rescue_core_module { */ $this->_rescueData = $this->_getRescueData(); - /* - * rescue MongoDB if needed - */ -// $this->_rescueMongoDB(); - /* * rescue mysql if needed (maybe httpd depends on mysql, so try this first!) */ @@ -311,73 +306,6 @@ class rescue_core_module { $this->_rescueDaemon($daemon); } - - /** - * restarts MongoDB, if needed - */ -// private function _rescueMongoDB(){ -// global $app, $conf; - - /* - * do nothing, if it is not allowed to rescue mysql - */ -// if ((isset($conf['serverconfig']['rescue']['do_not_try_rescue_mongodb']) && ($conf['serverconfig']['rescue']['do_not_try_rescue_mongodb']) == 'y')){ -// return; -// } - - /* - * if the service is up and running, or the service is not installed there is nothing to do... - */ -// if ($this->_monitoringData[0][0]['data']['mongodbserver'] != 0){ -// /* Clear the try counter, because we do not have to try to rescue the service */ -// $this->_rescueData['mongodbserver']['try_counter'] = 0; -// return; -// } - - /* - * OK, the service is installed and down. - * Maybe this is because of a restart of the service by the admin. - * This means, we check the data 1 minute ago - */ -// if ((!isset($this->_monitoringData[1][0]['data']['mongodbserver'])) || -// ((isset($this->_monitoringData[1][0]['data']['mongodbserver'])) && ($this->_monitoringData[1][0]['data']['mongodbserver'] != 0))){ - /* - * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago. - * This means, it could be, that the admin is restarting the server. - * We wait one more minute... - */ -// return; -// } - - /*##### - * The service is down and it was down 1 minute ago. - * We try to rescue it - *#####*/ - - /* Get the try counter */ -// $tryCount = (!isset($this->_rescueData['mongodbserver']['try_counter']))? 1 : $this->_rescueData['mongodbserver']['try_counter'] + 1; - - /* Set the new try counter */ -// $this->_rescueData['mongodbserver']['try_counter'] = $tryCount; - - /* if 5 times will not work, we have to give up... */ -// if ($tryCount > 5){ -// $app->log('MongoDB is down! Rescue will not help!', LOGLEVEL_ERROR); -// return; -// } - - -// $app->log('MongoDB is down! Try rescue MongoDB (try:' . $tryCount . ')...', LOGLEVEL_WARN); - -// if(is_file($conf['init_scripts'] . '/' . 'mongodb')) { -// $daemon = 'mongodb'; -// } else { -// $daemon = 'mongodb'; -// } - -// $this->_rescueDaemon($daemon); -// } - /** * restarts mysql, if needed */ diff --git a/server/plugins-available/backup_plugin.inc.php b/server/plugins-available/backup_plugin.inc.php index 12f58c1f1..cba46b857 100644 --- a/server/plugins-available/backup_plugin.inc.php +++ b/server/plugins-available/backup_plugin.inc.php @@ -93,32 +93,6 @@ class backup_plugin { } } - //* Restore a MongoDB backup - if($action_name == 'backup_restore' && $backup['backup_type'] == 'mongodb') { - if(file_exists($backup_dir.'/'.$backup['filename'])) { - //$parts = explode('_',$backup['filename']); - //$db_name = $parts[1]; - preg_match('@^db_(.+)_\d{4}-\d{2}-\d{2}_\d{2}-\d{2}\.tar\.gz$@', $backup['filename'], $matches); - $db_name = $matches[1]; - - // extract tar.gz archive - $dump_directory = str_replace(".tar.gz", "", $backup['filename']); - $extracted = "/usr/local/ispconfig/server/temp"; - exec("tar -xzvf ".escapeshellarg($backup_dir.'/'.$backup['filename'])." --directory=".escapeshellarg($extracted)); - $restore_directory = $extracted."/".$dump_directory."/".$db_name; - - // mongorestore -h 127.0.0.1 -u root -p 123456 --authenticationDatabase admin -d c1debug --drop ./toRestore - $command = "mongorestore -h 127.0.0.1 --port 27017 -u root -p 123456 --authenticationDatabase admin -d ".$db_name." --drop ".escapeshellarg($restore_directory); - exec($command); - exec("rm -rf ".escapeshellarg($extracted."/".$dump_directory)); - } - - unset($clientdb_host); - unset($clientdb_user); - unset($clientdb_password); - $app->log('Restored MongoDB backup '.$backup_dir.'/'.$backup['filename'], LOGLEVEL_DEBUG); - } - //* Restore a mysql backup if($action_name == 'backup_restore' && $backup['backup_type'] == 'mysql') { //* Load sql dump into db -- GitLab From 613afed069c4b9c5a29d88ca515c50c894874e75 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 22:16:21 +0100 Subject: [PATCH 174/310] - removed xmpp, php modes etc. from sql files --- install/sql/incremental/upd_0083.sql | 2 +- .../sql/incremental/upd_dev_collection.sql | 39 ++++++- install/sql/ispconfig3.sql | 107 +----------------- 3 files changed, 40 insertions(+), 108 deletions(-) diff --git a/install/sql/incremental/upd_0083.sql b/install/sql/incremental/upd_0083.sql index f0a3df83f..0a682eea9 100644 --- a/install/sql/incremental/upd_0083.sql +++ b/install/sql/incremental/upd_0083.sql @@ -10,6 +10,6 @@ UPDATE client SET db_servers = default_dbserver WHERE (db_servers = '' OR db_ser UPDATE client SET dns_servers = default_dnsserver WHERE (dns_servers = '' OR dns_servers IS NULL); ALTER TABLE `client_template` ADD `default_slave_dnsserver` INT NOT NULL DEFAULT '0' AFTER `limit_dns_slave_zone`; ALTER TABLE `client_template` ADD `mail_servers` TEXT NULL DEFAULT NULL AFTER `template_type`; -ALTER TABLE `client_template` ADD `web_servers` TEXT NULL DEFAULT NULL AFTER `limit_xmpp_httparchive`; +ALTER TABLE `client_template` ADD `web_servers` TEXT NULL DEFAULT NULL AFTER `mail_servers`; ALTER TABLE `client_template` ADD `dns_servers` TEXT NULL DEFAULT NULL AFTER `limit_aps`; ALTER TABLE `client_template` ADD `db_servers` TEXT NULL DEFAULT NULL AFTER `limit_dns_record`; \ No newline at end of file diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index caab02181..bc979d5bc 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -108,4 +108,41 @@ ALTER TABLE `xmpp_domain` -- STRIPDOWN! ALTER TABLE `web_backup` CHANGE `backup_type` `backup_type` enum('web','mysql') NOT NULL DEFAULT 'web'; -ALTER TABLE `web_database_user` DROP COLUMN `database_password_mongo`; \ No newline at end of file +ALTER TABLE `web_database_user` DROP COLUMN `database_password_mongo`; +ALTER TABLE `client` CHANGE `web_php_options` `web_php_options` VARCHAR(255) NOT NULL DEFAULT 'no,fast-cgi,mod,php-fpm'; +ALTER TABLE `client_template` + DROP COLUMN `default_xmppserver`, + DROP COLUMN `xmpp_servers`, + DROP COLUMN `limit_xmpp_domain`, + DROP COLUMN `limit_xmpp_user`, + DROP COLUMN `limit_xmpp_muc`, + DROP COLUMN `limit_xmpp_anon`, + DROP COLUMN `limit_xmpp_vjud`, + DROP COLUMN `limit_xmpp_proxy`, + DROP COLUMN `limit_xmpp_status`, + DROP COLUMN `limit_xmpp_pastebin`, + DROP COLUMN `limit_xmpp_httparchive`, + DROP COLUMN `limit_xmpp_webpresence`, + DROP COLUMN `limit_xmpp_http_upload`; + +ALTER TABLE `server` DROP COLUMN `xmpp_server`; + +ALTER TABLE `client` + DROP COLUMN `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1', + DROP COLUMN `xmpp_servers`, + DROP COLUMN `limit_xmpp_domain`, + DROP COLUMN `limit_xmpp_user`, + DROP COLUMN `limit_xmpp_muc`, + DROP COLUMN `limit_xmpp_anon`, + DROP COLUMN `limit_xmpp_auth_options`, + DROP COLUMN `limit_xmpp_vjud`, + DROP COLUMN `limit_xmpp_proxy`, + DROP COLUMN `limit_xmpp_status`, + DROP COLUMN `limit_xmpp_pastebin`, + DROP COLUMN `limit_xmpp_httparchive`, + DROP COLUMN `limit_xmpp_webpresence`, + DROP COLUMN `limit_xmpp_http_upload`; + + +DROP TABLE `xmpp_domain`; +DROP TABLE `xmpp_user`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index dd684c7b8..e5a99a293 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -184,24 +184,12 @@ CREATE TABLE `client` ( `limit_spamfilter_wblist` int(11) NOT NULL DEFAULT '0', `limit_spamfilter_user` int(11) NOT NULL DEFAULT '0', `limit_spamfilter_policy` int(11) NOT NULL DEFAULT '0', - `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1', - `xmpp_servers` text, - `limit_xmpp_domain` int(11) NOT NULL DEFAULT '-1', - `limit_xmpp_user` int(11) NOT NULL DEFAULT '-1', - `limit_xmpp_muc` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_anon` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_auth_options` varchar(255) NOT NULL DEFAULT 'plain,hashed,isp', - `limit_xmpp_vjud` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_proxy` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_status` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_pastebin` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_httparchive` ENUM( 'n', 'y' ) NOT NULL default 'n', `default_webserver` int(11) unsigned NOT NULL DEFAULT '1', `web_servers` text, `limit_web_ip` text, `limit_web_domain` int(11) NOT NULL DEFAULT '-1', `limit_web_quota` int(11) NOT NULL DEFAULT '-1', - `web_php_options` varchar(255) NOT NULL DEFAULT 'no,fast-cgi,cgi,mod,suphp,php-fpm,hhvm', + `web_php_options` varchar(255) NOT NULL DEFAULT 'no,fast-cgi,mod,php-fpm', `limit_cgi` enum('n','y') NOT NULL DEFAULT 'n', `limit_ssi` enum('n','y') NOT NULL DEFAULT 'n', `limit_perl` enum('n','y') NOT NULL DEFAULT 'n', @@ -315,17 +303,6 @@ CREATE TABLE `client_template` ( `limit_spamfilter_wblist` int(11) NOT NULL default '0', `limit_spamfilter_user` int(11) NOT NULL default '0', `limit_spamfilter_policy` int(11) NOT NULL default '0', - `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1', - `xmpp_servers` text, - `limit_xmpp_domain` int(11) NOT NULL DEFAULT '-1', - `limit_xmpp_user` int(11) NOT NULL DEFAULT '-1', - `limit_xmpp_muc` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_anon` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_vjud` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_proxy` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_status` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_pastebin` ENUM( 'n', 'y' ) NOT NULL default 'n', - `limit_xmpp_httparchive` ENUM( 'n', 'y' ) NOT NULL default 'n', `web_servers` text, `limit_web_ip` text, `limit_web_domain` int(11) NOT NULL default '-1', @@ -1358,7 +1335,6 @@ CREATE TABLE `server` ( `vserver_server` tinyint(1) NOT NULL default '0', `proxy_server` tinyint(1) NOT NULL default '0', `firewall_server` tinyint(1) NOT NULL default '0', - `xmpp_server` tinyint(1) NOT NULL default '0', `config` text, `updated` bigint(20) unsigned NOT NULL default '0', `mirror_server_id` int(11) unsigned NOT NULL default '0', @@ -2146,87 +2122,6 @@ CREATE TABLE `web_traffic` ( -- -------------------------------------------------------- --- --- Table structure for table `xmpp_domain` --- - -CREATE TABLE `xmpp_domain` ( - `domain_id` int(11) unsigned NOT NULL auto_increment, - `sys_userid` int(11) unsigned NOT NULL default '0', - `sys_groupid` int(11) unsigned NOT NULL default '0', - `sys_perm_user` varchar(5) NOT NULL default '', - `sys_perm_group` varchar(5) NOT NULL default '', - `sys_perm_other` varchar(5) NOT NULL default '', - `server_id` int(11) unsigned NOT NULL default '0', - `domain` varchar(255) NOT NULL default '', - - `management_method` ENUM( 'normal', 'maildomain' ) NOT NULL default 'normal', - `public_registration` ENUM( 'n', 'y' ) NOT NULL default 'n', - `registration_url` varchar(255) NOT NULL DEFAULT '', - `registration_message` varchar(255) NOT NULL DEFAULT '', - `domain_admins` text, - - `use_pubsub` enum('n','y') NOT NULL DEFAULT 'n', - `use_proxy` enum('n','y') NOT NULL DEFAULT 'n', - `use_anon_host` enum('n','y') NOT NULL DEFAULT 'n', - - `use_vjud` enum('n','y') NOT NULL DEFAULT 'n', - `vjud_opt_mode` enum('in', 'out') NOT NULL DEFAULT 'in', - - `use_muc_host` enum('n','y') NOT NULL DEFAULT 'n', - `muc_name` varchar(30) NOT NULL DEFAULT '', - `muc_restrict_room_creation` enum('n', 'y', 'm') NOT NULL DEFAULT 'm', - `muc_admins` text, - `use_pastebin` enum('n','y') NOT NULL DEFAULT 'n', - `pastebin_expire_after` int(3) NOT NULL DEFAULT 48, - `pastebin_trigger` varchar(10) NOT NULL DEFAULT '!paste', - `use_http_archive` enum('n','y') NOT NULL DEFAULT 'n', - `http_archive_show_join` enum('n', 'y') NOT NULL DEFAULT 'n', - `http_archive_show_status` enum('n', 'y') NOT NULL DEFAULT 'n', - `use_status_host` enum('n','y') NOT NULL DEFAULT 'n', - - `ssl_state` varchar(255) NULL, - `ssl_locality` varchar(255) NULL, - `ssl_organisation` varchar(255) NULL, - `ssl_organisation_unit` varchar(255) NULL, - `ssl_country` varchar(255) NULL, - `ssl_email` varchar(255) NULL, - `ssl_request` mediumtext NULL, - `ssl_cert` mediumtext NULL, - `ssl_bundle` mediumtext NULL, - `ssl_key` mediumtext NULL, - `ssl_action` varchar(16) NULL, - - `active` enum('n','y') NOT NULL DEFAULT 'n', - PRIMARY KEY (`domain_id`), - KEY `server_id` (`server_id`,`domain`), - KEY `domain_active` (`domain`,`active`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- Table structure for table `xmpp_user` --- - -CREATE TABLE `xmpp_user` ( - `xmppuser_id` int(11) unsigned NOT NULL auto_increment, - `sys_userid` int(11) unsigned NOT NULL default '0', - `sys_groupid` int(11) unsigned NOT NULL default '0', - `sys_perm_user` varchar(5) NOT NULL default '', - `sys_perm_group` varchar(5) NOT NULL default '', - `sys_perm_other` varchar(5) NOT NULL default '', - `server_id` int(11) unsigned NOT NULL default '0', - `jid` varchar(255) NOT NULL default '', - `password` varchar(255) NOT NULL default '', - `active` enum('n','y') NOT NULL DEFAULT 'n', - PRIMARY KEY (`xmppuser_id`), - KEY `server_id` (`server_id`,`jid`), - KEY `jid_active` (`jid`,`active`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - -- -------------------------------------------------------- -- -------------------------------------------------------- -- DB-DATA -- GitLab From e78ec10fa949a68130bf06dede72e503b438ef1c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 22:31:33 +0100 Subject: [PATCH 175/310] - remove support for apache < 2.4 --- .../dist/tpl/gentoo/apache_apps.vhost.master | 6 +- .../tpl/gentoo/apache_ispconfig.conf.master | 6 +- .../tpl/gentoo/apache_ispconfig.vhost.master | 6 +- install/lib/install.lib.php | 6 +- install/tpl/apache_apps.vhost.master | 15 ---- install/tpl/apache_ispconfig.conf.master | 68 ------------------- install/tpl/apache_ispconfig.vhost.master | 20 ------ install/tpl/server.ini.master | 1 - .../web/admin/form/server_config.tform.php | 10 +-- .../templates/server_config_fastcgi_edit.htm | 6 -- server/conf/apache_apps.vhost.master | 15 ---- server/conf/apache_ispconfig.conf.master | 68 ------------------- server/conf/vhost.conf.master | 60 ---------------- .../classes/plugin_webserver_apache.inc.php | 1 - .../lib/classes/plugin_webserver_base.inc.php | 2 - server/lib/classes/system.inc.php | 6 +- 16 files changed, 13 insertions(+), 283 deletions(-) diff --git a/install/dist/tpl/gentoo/apache_apps.vhost.master b/install/dist/tpl/gentoo/apache_apps.vhost.master index ac29f81bb..aff93d06f 100644 --- a/install/dist/tpl/gentoo/apache_apps.vhost.master +++ b/install/dist/tpl/gentoo/apache_apps.vhost.master @@ -21,8 +21,7 @@ SetHandler fcgid-script FCGIWrapper {website_basedir}/php-fcgi-scripts/apps/.php-fcgi-starter .php - Order allow,deny - Allow from all + Require all granted DirectoryIndex index.php @@ -33,8 +32,7 @@ Options +FollowSymLinks AllowOverride None - Order allow,deny - Allow from all + Require all granted diff --git a/install/dist/tpl/gentoo/apache_ispconfig.conf.master b/install/dist/tpl/gentoo/apache_ispconfig.conf.master index 799a39601..2cd17d3f1 100644 --- a/install/dist/tpl/gentoo/apache_ispconfig.conf.master +++ b/install/dist/tpl/gentoo/apache_ispconfig.conf.master @@ -9,13 +9,11 @@ CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -s access.log -t \"%Y%m AllowOverride None - Order Deny,Allow - Deny from all + Require all denied # allow path to awstats and alias for awstats icons - Order allow,deny - Allow from all + Require all granted Alias /awstats/icon "/usr/share/awstats/htdocs/icon" diff --git a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master index f4f08d2bb..fb1b9d2a1 100644 --- a/install/dist/tpl/gentoo/apache_ispconfig.vhost.master +++ b/install/dist/tpl/gentoo/apache_ispconfig.vhost.master @@ -20,8 +20,7 @@ NameVirtualHost *:{vhost_port} SetHandler fcgid-script FCGIWrapper /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter .php - Order allow,deny - Allow from all + Require all granted DirectoryIndex index.php @@ -32,8 +31,7 @@ NameVirtualHost *:{vhost_port} Options +FollowSymLinks AllowOverride None - Order allow,deny - Allow from all + Require all granted php_value magic_quotes_gpc 0 diff --git a/install/lib/install.lib.php b/install/lib/install.lib.php index b2d9e66f7..cb31fb28e 100644 --- a/install/lib/install.lib.php +++ b/install/lib/install.lib.php @@ -970,20 +970,20 @@ function getapacheversion($get_minor = false) { elseif(is_installed('apachectl')) $cmd = 'apachectl -v'; else { ilog("Could not check apache version, apachectl not found."); - return '2.2'; + return '2.4'; } exec($cmd, $output, $return_var); if($return_var != 0 || !$output[0]) { ilog("Could not check apache version, apachectl did not return any data."); - return '2.2'; + return '2.4'; } if(preg_match('/version:\s*Apache\/(\d+)(\.(\d+)(\.(\d+))*)?(\D|$)/i', $output[0], $matches)) { return $matches[1] . (isset($matches[3]) ? '.' . $matches[3] : '') . (isset($matches[5]) && $get_minor == true ? '.' . $matches[5] : ''); } else { ilog("Could not check apache version, did not find version string in apachectl output."); - return '2.2'; + return '2.4'; } } diff --git a/install/tpl/apache_apps.vhost.master b/install/tpl/apache_apps.vhost.master index ee1b69309..6ffb1df8a 100644 --- a/install/tpl/apache_apps.vhost.master +++ b/install/tpl/apache_apps.vhost.master @@ -25,12 +25,7 @@ Options FollowSymLinks AllowOverride None - Require all granted - - Order allow,deny - Allow from all - @@ -40,12 +35,7 @@ Options FollowSymLinks AllowOverride None - Require all granted - - Order allow,deny - Allow from all - @@ -59,12 +49,7 @@ SetHandler fcgid-script FCGIWrapper {tmpl_var name='apps_vhost_basedir'}/php-fcgi-scripts/apps/.php-fcgi-starter .php - Require all granted - - Order allow,deny - Allow from all - diff --git a/install/tpl/apache_ispconfig.conf.master b/install/tpl/apache_ispconfig.conf.master index 333450726..0f4a77cd9 100644 --- a/install/tpl/apache_ispconfig.conf.master +++ b/install/tpl/apache_ispconfig.conf.master @@ -27,131 +27,63 @@ CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -s access.log -t \"%Y%m AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - # Do not allow access to the root file system of the server for security reasons Options -Indexes AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - # Except of the following directories that contain website scripts - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - # Allow access to mailman on OpenSuSE - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - Options +FollowSymLinks - Require all granted - - Order allow,deny - Allow from all - # allow path to awstats and alias for awstats icons - Require all granted - - Order allow,deny - Allow from all - Alias /awstats-icon "/usr/share/awstats/icon" Alias /.well-known/acme-challenge /usr/local/ispconfig/interface/acme/.well-known/acme-challenge - Require all granted - - Order allow,deny - Allow from all - AssignUserId www-data www-data - - -NameVirtualHost *:80 -NameVirtualHost *:443 - -NameVirtualHost {tmpl_var name="ip_address"}:{tmpl_var name="port"} - - diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index eab55f322..d77060d33 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -33,12 +33,7 @@ SetHandler fcgid-script FCGIWrapper /var/www/php-fcgi-scripts/ispconfig/.php-fcgi-starter .php - Require all granted - - Order allow,deny - Allow from all - IPCCommTimeout 7200 MaxRequestLen 15728640 @@ -52,12 +47,7 @@ # php_admin_value open_basedir "/usr/local/ispconfig/interface:/usr/share:/tmp" Options +FollowSymLinks AllowOverride None - Require all granted - - Order allow,deny - Allow from all - php_value magic_quotes_gpc 0 @@ -121,20 +111,10 @@ AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index e6c44613e..bf3306fa9 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -134,7 +134,6 @@ fastcgi_phpini_path=/etc/php5/cgi/ fastcgi_children=8 fastcgi_max_requests=5000 fastcgi_bin=/usr/bin/php-cgi -fastcgi_config_syntax=2 [jailkit] jailkit_chroot_home=/home/[username] diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index ceb7626f5..21b77fc0f 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1602,15 +1602,7 @@ $form["tabs"]['fastcgi'] = array( 'value' => '', 'width' => '40', 'maxlength' => '255' - ), - 'fastcgi_config_syntax' => array( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '2', - 'value' => array('1' => 'Old (apache 2.0)', '2' => 'New (apache 2.2)'), - 'width' => '40', - 'maxlength' => '255' - ), + ) //################################# // ENDE Datatable fields //################################# diff --git a/interface/web/admin/templates/server_config_fastcgi_edit.htm b/interface/web/admin/templates/server_config_fastcgi_edit.htm index c36b482e7..db476a091 100644 --- a/interface/web/admin/templates/server_config_fastcgi_edit.htm +++ b/interface/web/admin/templates/server_config_fastcgi_edit.htm @@ -26,12 +26,6 @@
-
- -
-
diff --git a/server/conf/apache_apps.vhost.master b/server/conf/apache_apps.vhost.master index 7dc2fd9dd..ecd3ff1a0 100644 --- a/server/conf/apache_apps.vhost.master +++ b/server/conf/apache_apps.vhost.master @@ -24,12 +24,7 @@ Options FollowSymLinks AllowOverride None - Require all granted - - Order allow,deny - Allow from all - @@ -39,12 +34,7 @@ Options FollowSymLinks AllowOverride None - Require all granted - - Order allow,deny - Allow from all - @@ -58,12 +48,7 @@ SetHandler fcgid-script FCGIWrapper {tmpl_var name='apps_vhost_basedir'}/php-fcgi-scripts/apps/.php-fcgi-starter .php - Require all granted - - Order allow,deny - Allow from all - diff --git a/server/conf/apache_ispconfig.conf.master b/server/conf/apache_ispconfig.conf.master index 6165f0496..c5bdb0a2d 100644 --- a/server/conf/apache_ispconfig.conf.master +++ b/server/conf/apache_ispconfig.conf.master @@ -27,131 +27,63 @@ CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -s access.log -t \"%Y%m AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - # Do not allow access to the root file system of the server for security reasons Options -Indexes AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - # Except of the following directories that contain website scripts - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - # Allow access to mailman on OpenSuSE - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - Options +FollowSymLinks - Require all granted - - Order allow,deny - Allow from all - # allow path to awstats and alias for awstats icons - Require all granted - - Order allow,deny - Allow from all - Alias /awstats-icon "/usr/share/awstats/icon" Alias /.well-known/acme-challenge /usr/local/ispconfig/interface/acme/.well-known/acme-challenge - Require all granted - - Order allow,deny - Allow from all - AssignUserId www-data www-data - - -NameVirtualHost *:80 -NameVirtualHost *:443 - -NameVirtualHost {tmpl_var name="ip_address"}:{tmpl_var name="port"} - - diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index 52b0dc372..05390b54d 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -2,12 +2,7 @@ AllowOverride None - Require all denied - - Order Deny,Allow - Deny from all - @@ -89,12 +84,7 @@ DocumentRoot Options +FollowSymLinks AllowOverride - Require all granted - - Order allow,deny - Allow from all - # ssi enabled @@ -104,13 +94,7 @@ DocumentRoot - Require all denied - - Order allow,deny - Deny from all - Allow from none - @@ -121,12 +105,7 @@ DocumentRoot Options +FollowSymLinks AllowOverride - Require all granted - - Order allow,deny - Allow from all - # ssi enabled @@ -136,13 +115,7 @@ DocumentRoot - Require all denied - - Order allow,deny - Deny from all - Allow from none - @@ -209,12 +182,7 @@ DocumentRoot # cgi enabled - Require all granted - - Order allow,deny - Allow from all - ScriptAlias /cgi-bin/ /cgi-bin/ @@ -245,7 +213,6 @@ DocumentRoot # php as fast-cgi enabled # For config options see: http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html - FcgidIdleTimeout 300 FcgidProcessLifeTime 3600 # FcgidMaxProcesses 1000 @@ -256,16 +223,6 @@ DocumentRoot FcgidIOTimeout 600 FcgidBusyTimeout 3600 FcgidMaxRequestLen 1073741824 - - IdleTimeout 300 - ProcessLifeTime 3600 - # MaxProcessCount 1000 - DefaultMinClassProcessCount 0 - DefaultMaxClassProcessCount 10 - IPCConnectTimeout 3 - IPCCommTimeout 600 - BusyTimeout 3600 - @@ -277,12 +234,7 @@ DocumentRoot FCGIWrapper .php5 Options +ExecCGI AllowOverride - Require all granted - - Order allow,deny - Allow from all - @@ -294,23 +246,13 @@ DocumentRoot FCGIWrapper .php5 Options +ExecCGI AllowOverride - Require all granted - - Order allow,deny - Allow from all - - Require all granted - - Order allow,deny - Allow from all - @@ -377,10 +319,8 @@ DocumentRoot RewriteEngine on - RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/ RewriteRule ^ - [END] - diff --git a/server/lib/classes/plugin_webserver_apache.inc.php b/server/lib/classes/plugin_webserver_apache.inc.php index 8393f529a..bed651b68 100644 --- a/server/lib/classes/plugin_webserver_apache.inc.php +++ b/server/lib/classes/plugin_webserver_apache.inc.php @@ -367,7 +367,6 @@ class plugin_webserver_apache { $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); } else { diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 184f08ce4..1fb4f7131 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -2921,8 +2921,6 @@ class plugin_webserver_base { $output .= "AuthUserFile $webdavRoot/$file\n"; $output .= "Require valid-user\n"; $output .= "Options +Indexes\n"; - if($app->system->getapacheversion()<=2.2) - $output .= "Order allow,deny\nAllow from all\n"; $output .= "\n"; } } diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index f4d94743a..d681761d4 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -1945,20 +1945,20 @@ class system{ elseif($this->is_installed('apachectl')) $cmd = 'apachectl -v'; else { $app->log("Could not check apache version, apachectl not found.", LOGLEVEL_DEBUG); - return '2.2'; + return '2.4'; } exec($cmd, $output, $return_var); if($return_var != 0 || !$output[0]) { $app->log("Could not check apache version, apachectl did not return any data.", LOGLEVEL_WARN); - return '2.2'; + return '2.4'; } if(preg_match('/version:\s*Apache\/(\d+)(\.(\d+)(\.(\d+))*)?(\D|$)/i', $output[0], $matches)) { return $matches[1] . (isset($matches[3]) ? '.' . $matches[3] : '') . (isset($matches[5]) && $get_minor == true ? '.' . $matches[5] : ''); } else { $app->log("Could not check apache version, did not find version string in apachectl output.", LOGLEVEL_WARN); - return '2.2'; + return '2.4'; } } -- GitLab From 472d7b912c07b5c14fcb4ec1d3edf22117de03ac Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 22:34:08 +0100 Subject: [PATCH 176/310] - removed unneccessary checks for apache > 2.2 --- install/tpl/apache_ispconfig.conf.master | 2 - install/tpl/apache_ispconfig.vhost.master | 1 - server/conf/vhost.conf.master | 53 +++++------------------ 3 files changed, 12 insertions(+), 44 deletions(-) diff --git a/install/tpl/apache_ispconfig.conf.master b/install/tpl/apache_ispconfig.conf.master index 0f4a77cd9..271a9b8ad 100644 --- a/install/tpl/apache_ispconfig.conf.master +++ b/install/tpl/apache_ispconfig.conf.master @@ -4,11 +4,9 @@ ServerTokens ProductOnly ServerSignature Off - SSLStaplingCache shmcb:/var/run/ocsp(128000) - ################################################ # ISPConfig Logfile configuration for vlogger diff --git a/install/tpl/apache_ispconfig.vhost.master b/install/tpl/apache_ispconfig.vhost.master index d77060d33..f97dad85b 100644 --- a/install/tpl/apache_ispconfig.vhost.master +++ b/install/tpl/apache_ispconfig.vhost.master @@ -4,7 +4,6 @@ ###################################################### Listen -NameVirtualHost *: > ServerAdmin webmaster@localhost diff --git a/server/conf/vhost.conf.master b/server/conf/vhost.conf.master index 05390b54d..7d129e559 100644 --- a/server/conf/vhost.conf.master +++ b/server/conf/vhost.conf.master @@ -256,24 +256,16 @@ DocumentRoot - - - SetHandler php-fcgi - - - SetHandler php-fcgi - + + SetHandler php-fcgi + - - - SetHandler php-fcgi - - - SetHandler php-fcgi - + + SetHandler php-fcgi + Action php-fcgi /php-fcgi virtual @@ -290,13 +282,9 @@ DocumentRoot #ProxyPassMatch ^/(.*\.php[345]?(/.*)?)$ fcgi://127.0.0.1:/$1 - - - SetHandler "proxy:fcgi://127.0.0.1:" - - - SetHandler "proxy:fcgi://127.0.0.1:" - + + SetHandler "proxy:fcgi://127.0.0.1:" + @@ -304,13 +292,9 @@ DocumentRoot #ProxyPassMatch ^/(.*\.php[345]?(/.*)?)$ unix://|fcgi://localhost//$1 - - - SetHandler "proxy:unix:|fcgi://localhost" - - - SetHandler "proxy:unix:|fcgi://localhost" - + + SetHandler "proxy:unix:|fcgi://localhost" + @@ -325,30 +309,19 @@ DocumentRoot RewriteCond %{HTTPS} off - RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ - RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] RewriteCond %{HTTP_HOST} ^$ [NC] - - RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ - RewriteRule ^ https://%{REQUEST_URI} [R=301,NE,L] RewriteCond %{HTTP_HOST} ^$ [NC] - - RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ - RewriteRule ^ https://%{REQUEST_URI} [R=301,NE,L] RewriteCond %{HTTP_HOST} $ [NC] - - RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ - RewriteCond %{REQUEST_URI} !^/webdav/ RewriteCond %{REQUEST_URI} !^/php-fcgi/ @@ -361,8 +334,6 @@ DocumentRoot RewriteCond %{HTTPS} off - RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ - RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE] -- GitLab From 5827252b7c9e76d18d1bc71cd478ab998cced52e Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 22:53:08 +0100 Subject: [PATCH 177/310] - removed courier support --- install/dist/conf/centos52.conf.php | 14 - install/dist/conf/centos53.conf.php | 14 - install/dist/conf/centos70.conf.php | 14 - install/dist/conf/centos72.conf.php | 14 - install/dist/conf/debian40.conf.php | 14 - install/dist/conf/debian60.conf.php | 14 - install/dist/conf/debian90.conf.php | 14 - install/dist/conf/debiantesting.conf.php | 14 - install/dist/conf/fedora9.conf.php | 14 - install/dist/conf/gentoo.conf.php | 15 - install/dist/conf/opensuse110.conf.php | 14 - install/dist/conf/opensuse112.conf.php | 14 - install/dist/conf/ubuntu1604.conf.php | 14 - install/dist/conf/ubuntu1710.conf.php | 14 - install/dist/conf/ubuntu1804.conf.php | 14 - install/dist/lib/fedora.lib.php | 68 ----- install/dist/lib/gentoo.lib.php | 43 --- install/dist/lib/opensuse.lib.php | 71 ----- install/install.php | 31 +- install/lib/installer_base.lib.php | 121 -------- install/lib/update.lib.php | 2 - install/tpl/sasl_smtpd.conf.master | 9 - install/tpl/sasl_smtpd2.conf.master | 10 - install/tpl/server.ini.master | 2 - install/update.php | 20 -- .../plugins/mail_user_filter_plugin.inc.php | 192 ++++--------- .../web/admin/form/server_config.tform.php | 12 - .../templates/server_config_mail_edit.htm | 12 - server/conf/mailfilter_move_junk.master | 19 -- .../cron.d/100-monitor_email_quota.inc.php | 16 +- server/lib/classes/system.inc.php | 28 +- server/plugins-available/mail_plugin.inc.php | 50 +--- .../plugins-available/maildrop_plugin.inc.php | 270 ------------------ .../server_services_plugin.inc.php | 3 +- 34 files changed, 78 insertions(+), 1112 deletions(-) delete mode 100644 install/tpl/sasl_smtpd.conf.master delete mode 100644 install/tpl/sasl_smtpd2.conf.master delete mode 100644 server/conf/mailfilter_move_junk.master delete mode 100644 server/plugins-available/maildrop_plugin.inc.php diff --git a/install/dist/conf/centos52.conf.php b/install/dist/conf/centos52.conf.php index 77462bd7f..c738b7ff6 100644 --- a/install/dist/conf/centos52.conf.php +++ b/install/dist/conf/centos52.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = ''; -$conf['courier']['courier-pop'] = ''; -$conf['courier']['courier-pop-ssl'] = ''; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/sysconfig/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc'; diff --git a/install/dist/conf/centos53.conf.php b/install/dist/conf/centos53.conf.php index 77462bd7f..c738b7ff6 100644 --- a/install/dist/conf/centos53.conf.php +++ b/install/dist/conf/centos53.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = ''; -$conf['courier']['courier-pop'] = ''; -$conf['courier']['courier-pop-ssl'] = ''; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/sysconfig/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc'; diff --git a/install/dist/conf/centos70.conf.php b/install/dist/conf/centos70.conf.php index c3076c4aa..baebbfb7a 100644 --- a/install/dist/conf/centos70.conf.php +++ b/install/dist/conf/centos70.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = ''; -$conf['courier']['courier-pop'] = ''; -$conf['courier']['courier-pop-ssl'] = ''; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/sysconfig/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavisd'; diff --git a/install/dist/conf/centos72.conf.php b/install/dist/conf/centos72.conf.php index b6cbcabe2..70d4c122f 100644 --- a/install/dist/conf/centos72.conf.php +++ b/install/dist/conf/centos72.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = ''; -$conf['courier']['courier-pop'] = ''; -$conf['courier']['courier-pop-ssl'] = ''; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/sysconfig/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavisd'; diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php index a85841e4f..a3170b786 100644 --- a/install/dist/conf/debian40.conf.php +++ b/install/dist/conf/debian40.conf.php @@ -129,25 +129,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index 18b54cb4e..4f95c60e9 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -129,25 +129,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index 68a47a04f..db741ed8a 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -129,25 +129,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index 2f911afdd..27d1369e3 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -129,25 +129,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php index 85121e7c8..9df56faf8 100644 --- a/install/dist/conf/fedora9.conf.php +++ b/install/dist/conf/fedora9.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap'; -$conf['courier']['courier-pop'] = 'courier-imap'; -$conf['courier']['courier-pop-ssl'] = 'courier-imap'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/sysconfig/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavisd'; diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index f15eac65d..7a76c13a9 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -138,26 +138,11 @@ $conf['getmail']['user'] = 'getmail'; $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authlib'; -$conf['courier']['courier-imap'] = 'courier-imapd'; -$conf['courier']['courier-imap-ssl'] = 'courier-imapd-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop3d'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop3d-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config_file'] = '/etc/conf.d/saslauthd'; -$conf['saslauthd']['config_dir'] = '/etc/sasl2'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_file'] = '/etc/amavisd.conf'; diff --git a/install/dist/conf/opensuse110.conf.php b/install/dist/conf/opensuse110.conf.php index 909a53aba..eaf7763bb 100644 --- a/install/dist/conf/opensuse110.conf.php +++ b/install/dist/conf/opensuse110.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/opensuse112.conf.php b/install/dist/conf/opensuse112.conf.php index 648a9222e..5759faad0 100644 --- a/install/dist/conf/opensuse112.conf.php +++ b/install/dist/conf/opensuse112.conf.php @@ -127,25 +127,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/authlib'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc'; diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index ea07eb54e..c18a7c2bf 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -129,25 +129,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/ubuntu1710.conf.php b/install/dist/conf/ubuntu1710.conf.php index 4f260b0ff..d539ac8ed 100644 --- a/install/dist/conf/ubuntu1710.conf.php +++ b/install/dist/conf/ubuntu1710.conf.php @@ -125,25 +125,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/conf/ubuntu1804.conf.php b/install/dist/conf/ubuntu1804.conf.php index c2c6021c9..cafd33850 100644 --- a/install/dist/conf/ubuntu1804.conf.php +++ b/install/dist/conf/ubuntu1804.conf.php @@ -125,25 +125,11 @@ $conf['getmail']['installed'] = false; // will be detected automatically during $conf['getmail']['config_dir'] = '/etc/getmail'; $conf['getmail']['program'] = '/usr/bin/getmail'; -//* Courier -$conf['courier']['installed'] = false; // will be detected automatically during installation -$conf['courier']['config_dir'] = '/etc/courier'; -$conf['courier']['courier-authdaemon'] = 'courier-authdaemon'; -$conf['courier']['courier-imap'] = 'courier-imap'; -$conf['courier']['courier-imap-ssl'] = 'courier-imap-ssl'; -$conf['courier']['courier-pop'] = 'courier-pop'; -$conf['courier']['courier-pop-ssl'] = 'courier-pop-ssl'; - //* Dovecot $conf['dovecot']['installed'] = false; // will be detected automatically during installation $conf['dovecot']['config_dir'] = '/etc/dovecot'; $conf['dovecot']['init_script'] = 'dovecot'; -//* SASL -$conf['saslauthd']['installed'] = false; // will be detected automatically during installation -$conf['saslauthd']['config'] = '/etc/default/saslauthd'; -$conf['saslauthd']['init_script'] = 'saslauthd'; - //* Amavisd $conf['amavis']['installed'] = false; // will be detected automatically during installation $conf['amavis']['config_dir'] = '/etc/amavis'; diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 176245cea..699908722 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -241,10 +241,6 @@ class installer_dist extends installer_base { caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - //** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. - $command = 'chmod 755 /var/spool/authdaemon'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - //* Changing maildrop lines in posfix master.cf if(is_file($config_dir.'/master.cf')){ copy($config_dir.'/master.cf', $config_dir.'/master.cf~'); @@ -297,70 +293,6 @@ class installer_dist extends installer_base { } - public function configure_saslauthd() { - global $conf; - - $configfile = 'tpl/fedora_saslauthd_smtpd_conf.master'; - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/fedora_saslauthd_smtpd_conf.master', $configfile); - wf('/usr/lib/sasl2/smtpd.conf', $content); - if(is_dir('/usr/lib64')) wf('/usr/lib64/sasl/smtpd.conf', $content); - if(is_dir('/usr/lib64')) wf('/usr/lib64/sasl2/smtpd.conf', $content); - - } - - public function configure_pam() - { - global $conf; - $pam = $conf['pam']; - //* configure pam for SMTP authentication agains the ispconfig database - $configfile = 'pamd_smtp'; - if(is_file("$pam/smtp")) copy("$pam/smtp", "$pam/smtp~"); - if(is_file("$pam/smtp~")) exec("chmod 400 $pam/smtp~"); - - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', "tpl/$configfile.master"); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - wf("$pam/smtp", $content); - // On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect. - if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp"); - } - - public function configure_courier() - { - global $conf; - $config_dir = $conf['courier']['config_dir']; - //* authmysqlrc - $configfile = 'authmysqlrc'; - if(is_file("$config_dir/$configfile")){ - copy("$config_dir/$configfile", "$config_dir/$configfile~"); - } - exec("chmod 400 $config_dir/$configfile~"); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', "tpl/$configfile.master"); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); - $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); - wf("$config_dir/$configfile", $content); - - exec("chmod 660 $config_dir/$configfile"); - exec("chown root:root $config_dir/$configfile"); - - //* authdaemonrc - $configfile = $conf['courier']['config_dir'].'/authdaemonrc'; - if(is_file($configfile)){ - copy($configfile, $configfile.'~'); - } - if(is_file($configfile.'~')){ - exec('chmod 400 '.$configfile.'~'); - } - $content = rf($configfile); - $content = str_replace('authmodulelist=', 'authmodulelist="authmysql"', $content); - wf($configfile, $content); - } - public function configure_dovecot() { global $conf; diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index dad0f880e..af936e886 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -181,12 +181,6 @@ class installer extends installer_base caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - //* We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. - $command = 'chmod 755 /var/lib/courier/authdaemon/'; - if (is_dir('/var/lib/courier/authdaemon')) { - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - } - //* Changing maildrop lines in posfix master.cf $configfile = $config_dir.'/master.cf'; $content = rf($configfile); @@ -233,43 +227,6 @@ class installer extends installer_base } - public function configure_saslauthd() - { - global $conf; - - $content = $this->get_template_file('sasl_smtpd.conf', true, true); //* get contents & insert db cred - $this->write_config_file($conf['saslauthd']['config_dir'].'/smtpd.conf', $content); - - //* Edit the file saslauthd config file - $content = rf($conf['saslauthd']['config_file']); - $content = preg_replace('/(?<=\n)SASLAUTHD_OPTS="\$\{SASLAUTHD_OPTS\}[^"]+"/', 'SASLAUTHD_OPTS="${SASLAUTHD_OPTS} -a pam -r -c -s 128 -t 30 -n 5"', $content); - - $this->write_config_file($conf['saslauthd']['config_file'], $content); - } - - public function configure_courier() - { - global $conf; - - //* authmysqlrc - $content = $this->get_template_file('authmysqlrc', true, true); //* get contents & insert db cred - $this->write_config_file($conf['courier']['config_dir'].'/authmysqlrc', $content); - - //* authdaemonrc - $configfile = $conf['courier']['config_dir'].'/authdaemonrc'; - - $content = rf($configfile); - $content = preg_replace('/(?<=\n)authmodulelist="[^"]+"/', "authmodulelist=\"authmysql\"", $content); - $this->write_config_file($configfile, $content); - - //* create certificates - $command = 'mkimapdcert'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - - $command = 'mkpop3dcert'; - caselog($command." &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - } - public function configure_dovecot() { global $conf; diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index ea862a67e..7dc63401a 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -248,10 +248,6 @@ class installer_dist extends installer_base { caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - //** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. - $command = 'chmod 755 /var/run/authdaemon.courier-imap'; - caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - //* Check maildrop service in posfix master.cf $regex = "/^maildrop unix.*pipe flags=DRhu user=vmail argv=\\/usr\\/bin\\/maildrop -d ".$cf['vmail_username']." \\$\{extension} \\$\{recipient} \\$\{user} \\$\{nexthop} \\$\{sender}/"; $configfile = $config_dir.'/master.cf'; @@ -304,73 +300,6 @@ class installer_dist extends installer_base { } - public function configure_saslauthd() { - global $conf; - - // Edit the file /etc/init.d/saslauthd - $configfile = $conf["init_scripts"].'/'.$conf["saslauthd"]["init_script"]; - $content = rf($configfile); - $content = str_replace('/sbin/startproc $AUTHD_BIN -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1', '/sbin/startproc $AUTHD_BIN -r -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1', $content); - $content = str_replace('/sbin/startproc $AUTHD_BIN $SASLAUTHD_PARAMS -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1', '/sbin/startproc $AUTHD_BIN $SASLAUTHD_PARAMS -r -a $SASLAUTHD_AUTHMECH -n $SASLAUTHD_THREADS > /dev/null 2>&1', $content); - - - if(is_file($configfile)) wf($configfile, $content); - - } - - public function configure_pam() - { - global $conf; - $pam = $conf['pam']; - //* configure pam for SMTP authentication agains the ispconfig database - $configfile = 'pamd_smtp'; - if(is_file("$pam/smtp")) copy("$pam/smtp", "$pam/smtp~"); - if(is_file("$pam/smtp~")) exec("chmod 400 $pam/smtp~"); - - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', "tpl/$configfile.master"); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - wf("$pam/smtp", $content); - // On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect. - if(is_file("$pam/smtp")) exec("chmod o= $pam/smtp"); - } - - public function configure_courier() - { - global $conf; - $config_dir = $conf['courier']['config_dir']; - //* authmysqlrc - $configfile = 'authmysqlrc'; - if(is_file("$config_dir/$configfile")){ - copy("$config_dir/$configfile", "$config_dir/$configfile~"); - } - exec("chmod 400 $config_dir/$configfile~"); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', "tpl/$configfile.master"); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); - $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); - wf("$config_dir/$configfile", $content); - - exec("chmod 660 $config_dir/$configfile"); - exec("chown root:root $config_dir/$configfile"); - - //* authdaemonrc - $configfile = $conf['courier']['config_dir'].'/authdaemonrc'; - if(is_file($configfile)){ - copy($configfile, $configfile.'~'); - } - if(is_file($configfile.'~')){ - exec('chmod 400 '.$configfile.'~'); - } - $content = rf($configfile); - $content = str_replace('authmodulelist=', 'authmodulelist="authmysql"', $content); - wf($configfile, $content); - } - public function configure_dovecot() { global $conf; diff --git a/install/install.php b/install/install.php index faa1463d7..d5578b932 100644 --- a/install/install.php +++ b/install/install.php @@ -352,34 +352,15 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Mail } //* Check for Dovecot and Courier - if(!$conf['dovecot']['installed'] && !$conf['courier']['installed']) { + if(!$conf['dovecot']['installed']) { $conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot', ($install_mode == 'expert')); - $conf['courier']['installed'] = $inst->force_configure_app('Courier', ($install_mode == 'expert')); - } - //* Configure Mailserver - Dovecot or Courier - if($conf['dovecot']['installed'] && $conf['courier']['installed']) { - $mail_server_to_use = $inst->simple_query('Dovecot and Courier detected. Select server to use with ISPConfig:', array('dovecot', 'courier'), 'dovecot','mail_server'); - if($mail_server_to_use == 'dovecot'){ - $conf['courier']['installed'] = false; - } else { - $conf['dovecot']['installed'] = false; - } } //* Configure Dovecot if($conf['dovecot']['installed']) { swriteln('Configuring Dovecot'); $inst->configure_dovecot(); } - //* Configure Courier - if($conf['courier']['installed']) { - swriteln('Configuring Courier'); - $inst->configure_courier(); - swriteln('Configuring SASL'); - $inst->configure_saslauthd(); - swriteln('Configuring PAM'); - $inst->configure_pam(); - } - + //* Configure Spamasassin $force = @($conf['spamassassin']['installed']) ? true : $inst->force_configure_app('Spamassassin', ($install_mode == 'expert')); if($force) { @@ -599,16 +580,8 @@ $inst->detect_ips(); swriteln('Restarting services ...'); if($conf['mysql']['installed'] == true && $conf['mysql']['init_script'] != '') system($inst->getinitcommand($conf['mysql']['init_script'], 'restart').' >/dev/null 2>&1'); if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart')); -if($conf['saslauthd']['installed'] == true && $conf['saslauthd']['init_script'] != '') system($inst->getinitcommand($conf['saslauthd']['init_script'], 'restart')); if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart')); if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart')); -if($conf['courier']['installed'] == true){ - if($conf['courier']['courier-authdaemon'] != '') system($inst->getinitcommand($conf['courier']['courier-authdaemon'], 'restart')); - if($conf['courier']['courier-imap'] != '') system($inst->getinitcommand($conf['courier']['courier-imap'], 'restart')); - if($conf['courier']['courier-imap-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-imap-ssl'], 'restart')); - if($conf['courier']['courier-pop'] != '') system($inst->getinitcommand($conf['courier']['courier-pop'], 'restart')); - if($conf['courier']['courier-pop-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-pop-ssl'], 'restart')); -} if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart')); if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &'); if($conf['apache']['installed'] == true && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart')); diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index b1b5dff70..c9e8391dc 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -160,9 +160,7 @@ class installer_base { if(is_installed('mlmmj') || is_installed('mlmmj-make-ml')) $conf['mlmmj']['installed'] = true; if(is_installed('apache') || is_installed('apache2') || is_installed('httpd') || is_installed('httpd2')) $conf['apache']['installed'] = true; if(is_installed('getmail')) $conf['getmail']['installed'] = true; - if(is_installed('courierlogger')) $conf['courier']['installed'] = true; if(is_installed('dovecot')) $conf['dovecot']['installed'] = true; - if(is_installed('saslauthd')) $conf['saslauthd']['installed'] = true; if(is_installed('amavisd-new') || is_installed('amavisd')) $conf['amavis']['installed'] = true; if(is_installed('clamdscan')) $conf['clamav']['installed'] = true; if(is_installed('pure-ftpd') || is_installed('pure-ftpd-wrapper')) $conf['pureftpd']['installed'] = true; @@ -321,8 +319,6 @@ class installer_base { $tpl_ini_array['web']['group'] = $conf['apache']['group']; $tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache']; $tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi']; - $tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier'; - $tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop'; $tpl_ini_array['mail']['mailinglist_manager'] = ($conf['mlmmj']['installed'] == true)?'mlmmj':'mailman'; $tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user']; $tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group']; @@ -1132,10 +1128,6 @@ class installer_base { caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); } - //** We have to change the permissions of the courier authdaemon directory to make it accessible for maildrop. - $command = 'chmod 755 /var/run/courier/authdaemon/'; - if(is_file('/var/run/courier/authdaemon/')) caselog($command.' &> /dev/null', __FILE__, __LINE__, 'EXECUTED: '.$command, 'Failed to execute the command '.$command); - //* Check maildrop service in posfix master.cf $regex = "/^maildrop unix.*pipe flags=DRhu user=vmail argv=\\/usr\\/bin\\/maildrop -d ".$cf['vmail_username']." \\$\{extension} \\$\{recipient} \\$\{user} \\$\{nexthop} \\$\{sender}/"; $configfile = $config_dir.'/master.cf'; @@ -1185,119 +1177,6 @@ class installer_base { } - public function configure_saslauthd() { - global $conf; - - //* Get saslsauthd version - exec('saslauthd -v 2>&1', $out); - $parts = explode(' ', $out[0]); - $saslversion = $parts[1]; - unset($parts); - unset($out); - - if(version_compare($saslversion , '2.1.23', '<=')) { - //* Configfile for saslauthd versions up to 2.1.23 - $configfile = 'sasl_smtpd.conf'; - } else { - //* Configfile for saslauthd versions 2.1.24 and newer - $configfile = 'sasl_smtpd2.conf'; - } - - if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf')) copy($conf['postfix']['config_dir'].'/sasl/smtpd.conf', $conf['postfix']['config_dir'].'/sasl/smtpd.conf~'); - if(is_file($conf['postfix']['config_dir'].'/sasl/smtpd.conf~')) chmod($conf['postfix']['config_dir'].'/sasl/smtpd.conf~', 0400); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - wf($conf['postfix']['config_dir'].'/sasl/smtpd.conf', $content); - - // TODO: Chmod and chown on the config file - - - // Recursively create the spool directory - if(!@is_dir('/var/spool/postfix/var/run/saslauthd')) mkdir('/var/spool/postfix/var/run/saslauthd', 0755, true); - - // Edit the file /etc/default/saslauthd - $configfile = $conf['saslauthd']['config']; - if(is_file($configfile)) copy($configfile, $configfile.'~'); - if(is_file($configfile.'~')) chmod($configfile.'~', 0400); - $content = rf($configfile); - $content = str_replace('START=no', 'START=yes', $content); - // Debian - $content = str_replace('OPTIONS="-c"', 'OPTIONS="-m /var/spool/postfix/var/run/saslauthd -r"', $content); - // Ubuntu - $content = str_replace('OPTIONS="-c -m /var/run/saslauthd"', 'OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r"', $content); - wf($configfile, $content); - - // Edit the file /etc/init.d/saslauthd - $configfile = $conf['init_scripts'].'/'.$conf['saslauthd']['init_script']; - $content = rf($configfile); - $content = str_replace('PIDFILE=$RUN_DIR/saslauthd.pid', 'PIDFILE="/var/spool/postfix/var/run/${NAME}/saslauthd.pid"', $content); - wf($configfile, $content); - - // add the postfix user to the sasl group (at least necessary for Ubuntu 8.04 and most likely Debian Lenny as well. - exec('adduser postfix sasl'); - - - } - - public function configure_pam() { - global $conf; - $pam = $conf['pam']; - //* configure pam for SMTP authentication agains the ispconfig database - $configfile = 'pamd_smtp'; - if(is_file($pam.'/smtp')) copy($pam.'/smtp', $pam.'/smtp~'); - if(is_file($pam.'/smtp~')) chmod($pam.'/smtp~', 0400); - - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_ip}', $conf['mysql']['ip'], $content); - wf($pam.'/smtp', $content); - // On some OSes smtp is world readable which allows for reading database information. Removing world readable rights should have no effect. - if(is_file($pam.'/smtp')) exec("chmod o= $pam/smtp"); - chmod($pam.'/smtp', 0660); - chown($pam.'/smtp', 'daemon'); - chgrp($pam.'/smtp', 'daemon'); - - } - - public function configure_courier() { - global $conf; - $config_dir = $conf['courier']['config_dir']; - //* authmysqlrc - $configfile = 'authmysqlrc'; - if(is_file($config_dir.'/'.$configfile)) { - copy($config_dir.'/'.$configfile, $config_dir.'/'.$configfile.'~'); - } - chmod($config_dir.'/'.$configfile.'~', 0400); - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$configfile.'.master', 'tpl/'.$configfile.'.master'); - $content = str_replace('{mysql_server_ispconfig_user}', $conf['mysql']['ispconfig_user'], $content); - $content = str_replace('{mysql_server_ispconfig_password}', $conf['mysql']['ispconfig_password'], $content); - $content = str_replace('{mysql_server_database}', $conf['mysql']['database'], $content); - $content = str_replace('{mysql_server_host}', $conf['mysql']['host'], $content); - $content = str_replace('{mysql_server_port}', $conf['mysql']['port'], $content); - wf($config_dir.'/'.$configfile, $content); - - chmod($config_dir.'/'.$configfile, 0660); - chown($config_dir.'/'.$configfile, 'daemon'); - chgrp($config_dir.'/'.$configfile, 'daemon'); - - //* authdaemonrc - $configfile = $config_dir.'/authdaemonrc'; - if(is_file($configfile)) { - copy($configfile, $configfile.'~'); - } - if(is_file($configfile.'~')) { - chmod($configfile.'~', 0400); - } - $content = rf($configfile); - $content = str_replace('authmodulelist="authpam"', 'authmodulelist="authmysql"', $content); - wf($configfile, $content); - } - public function configure_dovecot() { global $conf; diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index 3406b760b..2342291ab 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -333,8 +333,6 @@ function updateDbAndIni() { $tpl_ini_array['web']['group'] = $conf['apache']['group']; $tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache']; $tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi']; - $tpl_ini_array['mail']['pop3_imap_daemon'] = ($conf['dovecot']['installed'] == true)?'dovecot':'courier'; - $tpl_ini_array['mail']['mail_filter_syntax'] = ($conf['dovecot']['installed'] == true)?'sieve':'maildrop'; $tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user']; $tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group']; $tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir']; diff --git a/install/tpl/sasl_smtpd.conf.master b/install/tpl/sasl_smtpd.conf.master deleted file mode 100644 index 723712700..000000000 --- a/install/tpl/sasl_smtpd.conf.master +++ /dev/null @@ -1,9 +0,0 @@ -pwcheck_method: saslauthd -mech_list: plain login -allow_plaintext: true -auxprop_plugin: mysql -sql_hostnames: {mysql_server_ip} -sql_user: {mysql_server_ispconfig_user} -sql_passwd: {mysql_server_ispconfig_password} -sql_database: {mysql_server_database} -sql_select: select password from mail_user where (login = '%u' or email = '%u@%r') and postfix = 'y' and disablesmtp = 'n' \ No newline at end of file diff --git a/install/tpl/sasl_smtpd2.conf.master b/install/tpl/sasl_smtpd2.conf.master deleted file mode 100644 index 5fafe3670..000000000 --- a/install/tpl/sasl_smtpd2.conf.master +++ /dev/null @@ -1,10 +0,0 @@ -pwcheck_method: saslauthd -mech_list: plain login -allow_plaintext: true -auxprop_plugin: sql -sql_engine: mysql -sql_hostnames: {mysql_server_ip} -sql_user: {mysql_server_ispconfig_user} -sql_passwd: {mysql_server_ispconfig_password} -sql_database: {mysql_server_database} -sql_select: select password from mail_user where (login = '%u' or email = '%u@%r') and postfix = 'y' and disablesmtp = 'n' diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index bf3306fa9..d5bd6f9e2 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -38,8 +38,6 @@ homedir_path=/var/vmail maildir_format=maildir dkim_path=/var/lib/amavis/dkim dkim_strength=1024 -pop3_imap_daemon=courier -mail_filter_syntax=maildrop mailuser_uid=5000 mailuser_gid=5000 mailuser_name=vmail diff --git a/install/update.php b/install/update.php index 68c5b76cf..f621e7bd9 100644 --- a/install/update.php +++ b/install/update.php @@ -364,18 +364,6 @@ if($reconfigure_services_answer == 'yes' || $reconfigure_services_answer == 'sel //* Configure dovecot swriteln('Configuring Dovecot'); $inst->configure_dovecot(); - } elseif ($conf['courier']['installed'] == true) { - //** Configure saslauthd - swriteln('Configuring SASL'); - $inst->configure_saslauthd(); - - //** Configure PAM - swriteln('Configuring PAM'); - $inst->configure_pam(); - - //* Configure courier - swriteln('Configuring Courier'); - $inst->configure_courier(); } } @@ -530,16 +518,8 @@ if($reconfigure_services_answer == 'yes') { if($conf['mysql']['installed'] == true && $conf['mysql']['init_script'] != '') system($inst->getinitcommand($conf['mysql']['init_script'], 'restart').' >/dev/null 2>&1'); if($conf['services']['mail']) { if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != '') system($inst->getinitcommand($conf['postfix']['init_script'], 'restart')); - if($conf['saslauthd']['installed'] == true && $conf['saslauthd']['init_script'] != '') system($inst->getinitcommand($conf['saslauthd']['init_script'], 'restart')); if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart')); if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart')); - if($conf['courier']['installed'] == true){ - if($conf['courier']['courier-authdaemon'] != '') system($inst->getinitcommand($conf['courier']['courier-authdaemon'], 'restart')); - if($conf['courier']['courier-imap'] != '') system($inst->getinitcommand($conf['courier']['courier-imap'], 'restart')); - if($conf['courier']['courier-imap-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-imap-ssl'], 'restart')); - if($conf['courier']['courier-pop'] != '') system($inst->getinitcommand($conf['courier']['courier-pop'], 'restart')); - if($conf['courier']['courier-pop-ssl'] != '') system($inst->getinitcommand($conf['courier']['courier-pop-ssl'], 'restart')); - } if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart')); if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &'); } diff --git a/interface/lib/plugins/mail_user_filter_plugin.inc.php b/interface/lib/plugins/mail_user_filter_plugin.inc.php index a4e973973..b2d1c18ce 100644 --- a/interface/lib/plugins/mail_user_filter_plugin.inc.php +++ b/interface/lib/plugins/mail_user_filter_plugin.inc.php @@ -125,154 +125,84 @@ class mail_user_filter_plugin { $mailuser_rec = $app->db->queryOneRecord("SELECT server_id FROM mail_user WHERE mailuser_id = ?", $page_form->dataRecord["mailuser_id"]); $mail_config = $app->getconf->get_server_config($app->functions->intval($mailuser_rec["server_id"]), 'mail'); - if($mail_config['mail_filter_syntax'] == 'sieve') { - - // ####################################################### - // Filter in Sieve Syntax - // ####################################################### - - $content = ''; - $content .= '### BEGIN FILTER_ID:'.$page_form->id."\n"; - - //$content .= 'require ["fileinto", "regex", "vacation"];'."\n"; - - if($page_form->dataRecord["op"] == 'domain') { - $content .= 'if address :domain :is "'.strtolower($page_form->dataRecord["source"]).'" "'.$page_form->dataRecord["searchterm"].'" {'."\n"; - } elseif ($page_form->dataRecord["op"] == 'localpart') { - $content .= 'if address :localpart :is "'.strtolower($page_form->dataRecord["source"]).'" "'.$page_form->dataRecord["searchterm"].'" {'."\n"; - } elseif ($page_form->dataRecord["source"] == 'Size') { - if(substr(trim($page_form->dataRecord["searchterm"]),-1) == 'k' || substr(trim($page_form->dataRecord["searchterm"]),-1) == 'K') { - $unit = 'k'; - } else { - $unit = 'm'; - } - $content .= 'if size :over '.intval($page_form->dataRecord["searchterm"]).$unit.' {'."\n"; - } else { - if($page_form->dataRecord["source"] == 'Detail') { - $content .= 'if envelope :detail :regex "to" ["'; - } else { - if($page_form->dataRecord["source"] == 'Header') { - $parts = explode(':',trim($page_form->dataRecord["searchterm"])); - $page_form->dataRecord["source"] = trim($parts[0]); - unset($parts[0]); - $page_form->dataRecord["searchterm"] = trim(implode(':',$parts)); - unset($parts); - } - - $content .= 'if header :regex ["'.strtolower($page_form->dataRecord["source"]).'"] ["'; - } - - $searchterm = preg_quote($page_form->dataRecord["searchterm"]); - $searchterm = str_replace( - array( - '"', - '\\[', - '\\]' - ), - array( - '\\"', - '\\\\[', - '\\\\]' - ), $searchterm); - - if($page_form->dataRecord["op"] == 'contains') { - $content .= ".*".$searchterm; - } elseif ($page_form->dataRecord["op"] == 'is') { - $content .= "^".$searchterm."$"; - } elseif ($page_form->dataRecord["op"] == 'begins') { - $content .= "^".$searchterm.""; - } elseif ($page_form->dataRecord["op"] == 'ends') { - $content .= ".*".$searchterm."$"; - } - - $content .= '"] {'."\n"; - } - - if($page_form->dataRecord["action"] == 'move') { - $content .= ' fileinto "'.$page_form->dataRecord["target"].'";' . "\n stop;\n"; - } elseif ($page_form->dataRecord["action"] == 'keep') { - $content .= " keep;\n"; - } elseif ($page_form->dataRecord["action"] == 'stop') { - $content .= " stop;\n"; - } elseif ($page_form->dataRecord["action"] == 'reject') { - $content .= ' reject "'.$page_form->dataRecord["target"].'"; stop;\n\n'; - } elseif ($page_form->dataRecord["action"] == 'read') { - $content .= ' setflag "\\\\Seen";\n stop;\n'; + // ####################################################### + // Filter in Sieve Syntax + // ####################################################### + + $content = ''; + $content .= '### BEGIN FILTER_ID:'.$page_form->id."\n"; + + //$content .= 'require ["fileinto", "regex", "vacation"];'."\n"; + + if($page_form->dataRecord["op"] == 'domain') { + $content .= 'if address :domain :is "'.strtolower($page_form->dataRecord["source"]).'" "'.$page_form->dataRecord["searchterm"].'" {'."\n"; + } elseif ($page_form->dataRecord["op"] == 'localpart') { + $content .= 'if address :localpart :is "'.strtolower($page_form->dataRecord["source"]).'" "'.$page_form->dataRecord["searchterm"].'" {'."\n"; + } elseif ($page_form->dataRecord["source"] == 'Size') { + if(substr(trim($page_form->dataRecord["searchterm"]),-1) == 'k' || substr(trim($page_form->dataRecord["searchterm"]),-1) == 'K') { + $unit = 'k'; } else { - $content .= " discard;\n stop;\n"; + $unit = 'm'; } - - $content .= "}\n"; - - $content .= '### END FILTER_ID:'.$page_form->id."\n"; - + $content .= 'if size :over '.intval($page_form->dataRecord["searchterm"]).$unit.' {'."\n"; } else { + if($page_form->dataRecord["source"] == 'Detail') { + $content .= 'if envelope :detail :regex "to" ["'; + } else { + if($page_form->dataRecord["source"] == 'Header') { + $parts = explode(':',trim($page_form->dataRecord["searchterm"])); + $page_form->dataRecord["source"] = trim($parts[0]); + unset($parts[0]); + $page_form->dataRecord["searchterm"] = trim(implode(':',$parts)); + unset($parts); + } - // ####################################################### - // Filter in Maildrop Syntax - // ####################################################### - $content = ''; - $content .= '### BEGIN FILTER_ID:'.$page_form->id."\n"; - - $TargetNoQuotes = $page_form->dataRecord["target"]; - $TargetQuotes = "\"$TargetNoQuotes\""; - - $TestChDirNoQuotes = '$DEFAULT/.'.$TargetNoQuotes; - $TestChDirQuotes = "\"$TestChDirNoQuotes\""; - - $MailDirMakeNoQuotes = $TargetQuotes.' $DEFAULT'; - - $EchoTargetFinal = $TargetNoQuotes; - - - if($page_form->dataRecord["action"] == 'move') { - - $content .= " -`test -e ".$TestChDirQuotes." && exit 1 || exit 0` -if ( ".'$RETURNCODE'." != 1 ) -{ - `maildirmake -f $MailDirMakeNoQuotes` - `chmod -R 0700 ".$TestChDirQuotes."` - `echo \"INBOX.$EchoTargetFinal\" >> ".'$DEFAULT'."/courierimapsubscribed` -} -"; + $content .= 'if header :regex ["'.strtolower($page_form->dataRecord["source"]).'"] ["'; } - $content .= "if (/^".$page_form->dataRecord["source"].": "; - $searchterm = preg_quote($page_form->dataRecord["searchterm"]); + $searchterm = str_replace( + array( + '"', + '\\[', + '\\]' + ), + array( + '\\"', + '\\\\[', + '\\\\]' + ), $searchterm); if($page_form->dataRecord["op"] == 'contains') { - $content .= ".*".$searchterm."/:h)\n"; + $content .= ".*".$searchterm; } elseif ($page_form->dataRecord["op"] == 'is') { - $content .= $searchterm."$/:h)\n"; + $content .= "^".$searchterm."$"; } elseif ($page_form->dataRecord["op"] == 'begins') { - $content .= $searchterm."/:h)\n"; + $content .= "^".$searchterm.""; } elseif ($page_form->dataRecord["op"] == 'ends') { - $content .= ".*".$searchterm."$/:h)\n"; - } - - $content .= "{\n"; - $content .= "exception {\n"; - - if($page_form->dataRecord["action"] == 'move') { - $content .= 'ID' . "$page_form->id" . 'EndFolder = "$DEFAULT/.' . $page_form->dataRecord['target'] . '/"' . "\n"; - $content .= "xfilter \"/usr/bin/formail -A \\\"X-User-Mail-Filter-ID"."$page_form->id".": Yes\\\"\"" . "\n"; - $content .= "to ". '$ID' . "$page_form->id" . 'EndFolder' . "\n"; - } elseif ($page_form->dataRecord["action"] == 'read') { - $content .= ''; // mark as read currently not supported for Maildrop - } else { - $content .= "to /dev/null\n"; + $content .= ".*".$searchterm."$"; } - $content .= "}\n"; - $content .= "}\n"; + $content .= '"] {'."\n"; + } - //} + if($page_form->dataRecord["action"] == 'move') { + $content .= ' fileinto "'.$page_form->dataRecord["target"].'";' . "\n stop;\n"; + } elseif ($page_form->dataRecord["action"] == 'keep') { + $content .= " keep;\n"; + } elseif ($page_form->dataRecord["action"] == 'stop') { + $content .= " stop;\n"; + } elseif ($page_form->dataRecord["action"] == 'reject') { + $content .= ' reject "'.$page_form->dataRecord["target"].'"; stop;\n\n'; + } elseif ($page_form->dataRecord["action"] == 'read') { + $content .= ' setflag "\\\\Seen";\n stop;\n'; + } else { + $content .= " discard;\n stop;\n"; + } - $content .= '### END FILTER_ID:'.$page_form->id."\n"; + $content .= "}\n"; - } + $content .= '### END FILTER_ID:'.$page_form->id."\n"; return $content; } diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 21b77fc0f..19938e769 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -523,18 +523,6 @@ $form["tabs"]['mail'] = array( 'maxlength' => '255' ), - 'pop3_imap_daemon' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => '20', - 'value' => array('courier' => 'Courier', 'dovecot' => 'Dovecot') - ), - 'mail_filter_syntax' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => '20', - 'value' => array('maildrop' => 'Maildrop', 'sieve' => 'Sieve') - ), 'mailuser_uid' => array( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm index 1e01dc760..5323e98b4 100644 --- a/interface/web/admin/templates/server_config_mail_edit.htm +++ b/interface/web/admin/templates/server_config_mail_edit.htm @@ -32,18 +32,6 @@ {tmpl_var name='dkim_strength'}
-
- -
-
-
- -
-
diff --git a/server/conf/mailfilter_move_junk.master b/server/conf/mailfilter_move_junk.master deleted file mode 100644 index ef346c922..000000000 --- a/server/conf/mailfilter_move_junk.master +++ /dev/null @@ -1,19 +0,0 @@ - -SPAMDIR="Junk" -SPAMDIRFULL="$DEFAULT/.Junk" - -if ( /^X-Spam-Flag: YES$/ ) -{ - exception { - - `test -e $SPAMDIRFULL` - if ( $RETURNCODE != 0 ) - { - `maildirmake -f $SPAMDIR $DEFAULT` - `chown vmail:vmail -R $SPAMDIRFULL` - `chmod 0700 $SPAMDIRFULL` - `echo INBOX.$SPAMDIR >> $DEFAULT/courierimapsubscribed` - } - to "$SPAMDIRFULL/" - } -} \ No newline at end of file diff --git a/server/lib/classes/cron.d/100-monitor_email_quota.inc.php b/server/lib/classes/cron.d/100-monitor_email_quota.inc.php index 75014c347..b9a78e9e7 100644 --- a/server/lib/classes/cron.d/100-monitor_email_quota.inc.php +++ b/server/lib/classes/cron.d/100-monitor_email_quota.inc.php @@ -80,7 +80,7 @@ class cronjob_monitor_email_quota extends cronjob { //* with dovecot we can use doveadm instead of 'du -s' $dovecot = false; - if (isset($mail_config['pop3_imap_daemon']) && $mail_config ['pop3_imap_daemon'] = 'dovecot' && is_executable('doveadm')) { + if (is_executable('doveadm')) { exec('doveadm quota 2>&1', $tmp_output, $tmp_retval); // with dovecot 2.2.x 'doveadm quota' is unuseable if ($retval = 64) $dovecot = true; } @@ -110,20 +110,6 @@ class cronjob_monitor_email_quota extends cronjob { unset($mailboxes); - //* Dovecot quota check Courier in progress lathama@gmail.com - /* - if($dir = opendir("/var/vmail")){ - while (($quotafiles = readdir($dir)) !== false){ - if(preg_match('/.\_quota$/', $quotafiles)){ - $quotafile = (file("/var/vmail/" . $quotafiles)); - $emailaddress = preg_replace('/_quota/',"", $quotafiles); - $emailaddress = preg_replace('/_/',"@", $emailaddress); - $data[$emailaddress]['used'] = trim($quotafile['1']); - } - } - closedir($dir); - } - */ $res = array(); $res['server_id'] = $server_id; $res['type'] = $type; diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index d681761d4..5cd9d3f76 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -1639,29 +1639,15 @@ class system{ //* Add the subfolder to the subscriptions and courierimapsubscribed files if($subfolder != '') { - // Courier - if($mail_config['pop3_imap_daemon'] == 'courier') { - if(!is_file($maildir_path.'/courierimapsubscribed')) { - $tmp_file = escapeshellcmd($maildir_path.'/courierimapsubscribed'); - touch($tmp_file); - chmod($tmp_file, 0744); - chown($tmp_file, 'vmail'); - chgrp($tmp_file, 'vmail'); - } - $this->replaceLine($maildir_path.'/courierimapsubscribed', 'INBOX.'.$subfolder, 'INBOX.'.$subfolder, 1, 1); - } - // Dovecot - if($mail_config['pop3_imap_daemon'] == 'dovecot') { - if(!is_file($maildir_path.'/subscriptions')) { - $tmp_file = escapeshellcmd($maildir_path.'/subscriptions'); - touch($tmp_file); - chmod($tmp_file, 0744); - chown($tmp_file, 'vmail'); - chgrp($tmp_file, 'vmail'); - } - $this->replaceLine($maildir_path.'/subscriptions', $subfolder, $subfolder, 1, 1); + if(!is_file($maildir_path.'/subscriptions')) { + $tmp_file = escapeshellcmd($maildir_path.'/subscriptions'); + touch($tmp_file); + chmod($tmp_file, 0744); + chown($tmp_file, 'vmail'); + chgrp($tmp_file, 'vmail'); } + $this->replaceLine($maildir_path.'/subscriptions', $subfolder, $subfolder, 1, 1); } $app->log('Created Maildir '.$maildir_path.' with subfolder: '.$subfolder, LOGLEVEL_DEBUG); diff --git a/server/plugins-available/mail_plugin.inc.php b/server/plugins-available/mail_plugin.inc.php index 17f48efe2..2b9384826 100644 --- a/server/plugins-available/mail_plugin.inc.php +++ b/server/plugins-available/mail_plugin.inc.php @@ -145,11 +145,9 @@ class mail_plugin { } else { // Dovecot uses a different mail layout with a separate 'Maildir' subdirectory. - if($mail_config['pop3_imap_daemon'] == 'dovecot') { - $app->system->mkdirpath($maildomain_path, 0700, $user, $group); - $app->log('Created Directory: '.$maildomain_path, LOGLEVEL_DEBUG); - $maildomain_path .= '/Maildir'; - } + $app->system->mkdirpath($maildomain_path, 0700, $user, $group); + $app->log('Created Directory: '.$maildomain_path, LOGLEVEL_DEBUG); + $maildomain_path .= '/Maildir'; //* When the mail user dir exists but it is not a valid maildir, move it to corrupted maildir folder if(!empty($maildomain_path) && is_dir($maildomain_path) && !is_dir($maildomain_path.'/new') && !is_dir($maildomain_path.'/cur')) { @@ -163,12 +161,6 @@ class mail_plugin { //exec("su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']); $app->system->maildirmake($maildomain_path, $user, '', $group); - - //* This is to fix the maildrop quota not being rebuilt after the quota is changed. - if($mail_config['pop3_imap_daemon'] != 'dovecot') { - if(is_dir($maildomain_path)) exec("su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($maildomain_path)."' ".$user); // Avoid maildirmake quota bug, see debian bug #214911 - $app->log('Created Maildir: '."su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($maildomain_path)."' ".$user, LOGLEVEL_DEBUG); - } } if(!is_dir($data['new']['maildir'].'/.Sent')) { @@ -196,13 +188,6 @@ class mail_plugin { exec('chown -R '.$user.':'.$group.' '.escapeshellcmd($data['new']['maildir'])); $app->log('Set ownership on '.escapeshellcmd($data['new']['maildir']), LOGLEVEL_DEBUG); - //* Set the maildir quota - if(is_dir($data['new']['maildir'].'/new') && $mail_config['pop3_imap_daemon'] != 'dovecot') { - if($data['new']['quota'] > 0) { - if(is_dir($data['new']['maildir'])) exec("su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($data['new']['maildir'])."' ".$user); - $app->log('Set Maildir quota: '."su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($data['new']['maildir'])."' ".$user, LOGLEVEL_DEBUG); - } - } } //* Send the welcome email message @@ -360,11 +345,9 @@ class mail_plugin { } else { // Dovecot uses a different mail layout with a separate 'Maildir' subdirectory. - if($mail_config['pop3_imap_daemon'] == 'dovecot') { - $app->system->mkdirpath($maildomain_path, 0700, $user, $group); - $app->log('Created Directory: '.$base_path, LOGLEVEL_DEBUG); - $maildomain_path .= '/Maildir'; - } + $app->system->mkdirpath($maildomain_path, 0700, $user, $group); + $app->log('Created Directory: '.$base_path, LOGLEVEL_DEBUG); + $maildomain_path .= '/Maildir'; //* When the mail user dir exists but it is not a valid maildir, move it to corrupted maildir folder if(!empty($maildomain_path) && is_dir($maildomain_path) && !is_dir($maildomain_path.'/new') && !is_dir($maildomain_path.'/cur')) { @@ -378,17 +361,6 @@ class mail_plugin { //exec("su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name']); //$app->log("Created Maildir "."su -c 'maildirmake ".escapeshellcmd($maildomain_path)."' ".$mail_config['mailuser_name'],LOGLEVEL_DEBUG); $app->system->maildirmake($maildomain_path, $user, '', $group); - - //* This is to fix the maildrop quota not being rebuilt after the quota is changed. - if($mail_config['pop3_imap_daemon'] != 'dovecot') { - if($data['new']['quota'] > 0) { - if(is_dir($maildomain_path)) exec("su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($maildomain_path)."' ".$user); // Avoid maildirmake quota bug, see debian bug #214911 - $app->log('Updated Maildir quota: '."su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($maildomain_path)."' ".$user, LOGLEVEL_DEBUG); - } else { - if(file_exists($data['new']['maildir'].'/maildirsize')) unlink($data['new']['maildir'].'/maildirsize'); - $app->log('Set Maildir quota to unlimited.', LOGLEVEL_DEBUG); - } - } } if(!is_dir($data['new']['maildir'].'/.Sent')) { @@ -429,16 +401,6 @@ class mail_plugin { $app->log('Moved Maildir from: '.$data['old']['maildir'].' to '.$data['new']['maildir'], LOGLEVEL_DEBUG); } //This is to fix the maildrop quota not being rebuilt after the quota is changed. - // Courier Layout - if(is_dir($data['new']['maildir'].'/new') && $mail_config['pop3_imap_daemon'] != 'dovecot') { - if($data['new']['quota'] > 0) { - if(is_dir($data['new']['maildir'])) exec("su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($data['new']['maildir'])."' ".$user); - $app->log('Updated Maildir quota: '."su -c 'maildirmake -q ".$data['new']['quota']."S ".escapeshellcmd($data['new']['maildir'])."' ".$user, LOGLEVEL_DEBUG); - } else { - if(file_exists($data['new']['maildir'].'/maildirsize')) unlink($data['new']['maildir'].'/maildirsize'); - $app->log('Set Maildir quota to unlimited.', LOGLEVEL_DEBUG); - } - } } } diff --git a/server/plugins-available/maildrop_plugin.inc.php b/server/plugins-available/maildrop_plugin.inc.php deleted file mode 100644 index 2fefa26cf..000000000 --- a/server/plugins-available/maildrop_plugin.inc.php +++ /dev/null @@ -1,270 +0,0 @@ -plugins->registerEvent('mail_user_insert', 'maildrop_plugin', 'update'); - $app->plugins->registerEvent('mail_user_update', 'maildrop_plugin', 'update'); - $app->plugins->registerEvent('mail_user_delete', 'maildrop_plugin', 'delete'); - - } - - - function update($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses("getconf"); - $mail_config = $app->getconf->get_server_config($conf["server_id"], 'mail'); - if(substr($mail_config["homedir_path"], -1) == '/') { - $mail_config["homedir_path"] = substr($mail_config["homedir_path"], 0, -1); - } - $this->mailfilter_config_dir = $mail_config["homedir_path"].'/mailfilters'; - - - // Check if the config directory exists. - if(!is_dir($this->mailfilter_config_dir)) { - $app->log("Mailfilter config directory '".$this->mailfilter_config_dir."' does not exist. Creating it now.", LOGLEVEL_WARN); - mkdir($this->mailfilter_config_dir); - chown($this->mailfilter_config_dir, 'vmail'); - chmod($this->mailfilter_config_dir, 0770); - } - - if(isset($data["new"]["email"])) { - $email_parts = explode("@", $data["new"]["email"]); - } else { - $email_parts = explode("@", $data["old"]["email"]); - } - - // make sure that the config directories exist - if(!is_dir($this->mailfilter_config_dir.'/'.$email_parts[1])) { - mkdir($this->mailfilter_config_dir.'/'.$email_parts[1]); - chown($this->mailfilter_config_dir.'/'.$email_parts[1], 'vmail'); - chmod($this->mailfilter_config_dir.'/'.$email_parts[1], 0770); - } - if(!is_dir($this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0])) { - mkdir($this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0]); - chown($this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0], 'vmail'); - chmod($this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0], 0770); - } - - // Check if something has been changed regarding the autoresponders - if($data["old"]["autoresponder_text"] != $data["new"]["autoresponder_text"] - or $data["old"]["autoresponder"] != $data["new"]["autoresponder"] - or (isset($data["new"]["email"]) and $data["old"]["email"] != $data["new"]["email"]) - or $data["old"]["autoresponder_start_date"] != $data["new"]["autoresponder_start_date"] - or $data["old"]["autoresponder_end_date"] != $data["new"]["autoresponder_end_date"]) { - - // We delete the old autoresponder, if it exists - $email_parts = explode("@", $data["old"]["email"]); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lock'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst.gdbm'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst.lock'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.msg'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.autoresponder'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - - - //Now we create the new autoresponder, if it is enabled - if($data["new"]["autoresponder"] == 'y') { - if(isset($data["new"]["email"])) { - $email_parts = explode("@", $data["new"]["email"]); - } else { - $email_parts = explode("@", $data["old"]["email"]); - } - - // Load the master template - if(file_exists($conf["rootpath"].'/conf-custom/autoresponder.master')) { - $tpl = file_get_contents($conf["rootpath"].'/conf-custom/autoresponder.master'); - } else { - $tpl = file_get_contents($conf["rootpath"].'/conf/autoresponder.master'); - } - $tpl = str_replace('{vmail_mailbox_base}', $mail_config["homedir_path"], $tpl); - - if ($data['new']['autoresponder_start_date'] && $data["new"]["autoresponder_start_date"] != '0000-00-00 00:00:00') { // Dates have been set - $tpl = str_replace('{start_date}', strtotime($data["new"]["autoresponder_start_date"]), $tpl); - $tpl = str_replace('{end_date}', strtotime($data["new"]["autoresponder_end_date"]), $tpl); - } else { - $tpl = str_replace('{start_date}', -7200, $tpl); - $tpl = str_replace('{end_date}', 2147464800, $tpl); - } - - // Write the config file. - $config_file_path = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.autoresponder'; - file_put_contents($config_file_path, $tpl); - $app->log("Writing Autoresponder mailfilter file: $config_file_path", LOGLEVEL_DEBUG); - chmod($config_file_path, 0770); - chown($config_file_path, 'vmail'); - unset($tpl); - unset($config_file_path); - - // Write the autoresponder message file - $config_file_path = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.msg'; - file_put_contents($config_file_path, $data["new"]["autoresponder_text"]); - chmod($config_file_path, 0770); - chown($config_file_path, 'vmail'); - $app->log("Writing Autoresponder message file: $config_file_path", LOGLEVEL_DEBUG); - } - } - - // Write the custom mailfilter script, if mailfilter recipe has changed - if($data["old"]["custom_mailfilter"] != $data["new"]["custom_mailfilter"] - or $data["old"]["move_junk"] != $data["new"]["move_junk"] - or $data["old"]["cc"] != $data["new"]["cc"]) { - - $app->log("Mailfilter config has been changed", LOGLEVEL_DEBUG); - if(trim($data["new"]["custom_mailfilter"]) != '' - or $data["new"]["move_junk"] != 'n' - or $data["new"]["cc"] != '') { - - // Delete the old filter recipe - $email_parts = explode("@", $data["old"]["email"]); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.mailfilter'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - - // write the new recipe - if(isset($data["new"]["email"])) { - $email_parts = explode("@", $data["new"]["email"]); - } else { - $email_parts = explode("@", $data["old"]["email"]); - } - $config_file_path = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.mailfilter'; - - $mailfilter_content = ''; - - if($data["new"]["cc"] != '') { - $tmp_mails_arr = explode(',',$data["new"]["cc"]); - foreach($tmp_mails_arr as $address) { - if(trim($address) != '') $mailfilter_content .= "cc \"!".trim($address)."\"\n"; - } - //$mailfilter_content .= "cc \"!".$data["new"]["cc"]."\"\n"; - $app->log("Added CC address ".$data["new"]["cc"].' to mailfilter file.', LOGLEVEL_DEBUG); - } - - if($data["new"]["move_junk"] == 'y') { - if(file_exists($conf["rootpath"].'/conf-custom/mailfilter_move_junk.master')) { - $mailfilter_content .= file_get_contents($conf["rootpath"].'/conf-custom/mailfilter_move_junk.master')."\n"; - } else { - $mailfilter_content .= file_get_contents($conf["rootpath"].'/conf/mailfilter_move_junk.master')."\n"; - } - } - $mailfilter_content .= str_replace("\r\n","\n",$data["new"]["custom_mailfilter"]); - - // Replace windows linebreaks in mailfilter file - $mailfilter_content = str_replace("\r\n", "\n", $mailfilter_content); - - file_put_contents($config_file_path, $mailfilter_content); - $app->log("Writing new custom Mailfiter".$config_file_path, LOGLEVEL_DEBUG); - chmod($config_file_path, 0770); - chown($config_file_path, 'vmail'); - unset($config_file_path); - } else { - // Delete the mailfilter recipe - if(isset($data["old"]["email"])) { - $email_parts = explode("@", $data["old"]["email"]); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.mailfilter'; - if(is_file($file)) { - unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $app->log("Deleting custom Mailfiter".$file, LOGLEVEL_DEBUG); - } - } - } - } - } - - function delete($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses("getconf"); - $mail_config = $app->getconf->get_server_config($conf["server_id"], 'mail'); - $this->mailfilter_config_dir = $mail_config["homedir_path"].'/mailfilters'; - - $email_parts = explode("@", $data["old"]["email"]); - $dir = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0]; - if(is_dir($dir)) { - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lock'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.msg'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.autoresponder'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.mailfilter'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst.gdbm'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - $file = $this->mailfilter_config_dir.'/'.$email_parts[1].'/'.$email_parts[0].'/.vacation.lst.lock'; - if(is_file($file)) unlink($file) or $app->log("Unable to delete file: $file", LOGLEVEL_WARN); - rmdir($dir) or $app->log("Unable to delete directory: $dir", LOGLEVEL_WARN); - } - } - - -} // end class - -?> diff --git a/server/plugins-available/server_services_plugin.inc.php b/server/plugins-available/server_services_plugin.inc.php index 5b2eff74f..bb75ac55b 100644 --- a/server/plugins-available/server_services_plugin.inc.php +++ b/server/plugins-available/server_services_plugin.inc.php @@ -39,7 +39,6 @@ class server_services_plugin { var $services = array('mail_server', 'web_server', 'dns_server', 'db_server', 'vserver_server'); var $mail_plugins = array('getmail_plugin', 'mail_plugin', 'mail_plugin_dkim', 'mailman_plugin', 'postfix_filter_plugin', 'postfix_server_plugin'); - var $courier_plugins = array('maildrop_plugin'); var $dovecot_plugins = array('maildeliver_plugin'); var $web_plugins = array('aps_plugin', 'cron_plugin', 'cron_jailkit_plugin', 'ftpuser_base_plugin', 'shelluser_base_plugin', 'shelluser_jailkit_plugin', 'webserver_plugin'); @@ -95,7 +94,7 @@ class server_services_plugin { switch($service) { case 'mail_server': $config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - $plugins = @($config['pop3_imap_daemon'] == 'dovecot')?$this->dovecot_plugins:$this->courier_plugins; + $plugins = $this->dovecot_plugins; $plugins = array_merge($plugins, $this->mail_plugins); $this->change_state($plugins, $value, $config); break; -- GitLab From aed1f6fda475aab947fb92846bf2498ff1f54367 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 12 Nov 2018 23:10:21 +0100 Subject: [PATCH 178/310] - remove legacy php from pages on update --- install/sql/incremental/upd_dev_collection.sql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index bc979d5bc..29d570078 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -143,6 +143,12 @@ ALTER TABLE `client` DROP COLUMN `limit_xmpp_webpresence`, DROP COLUMN `limit_xmpp_http_upload`; - DROP TABLE `xmpp_domain`; DROP TABLE `xmpp_user`; + +-- only on nginx +UPDATE `web_domain` as d INNER JOIN `server` as s ON (s.server_id = d.server_id) SET d.php = 'php-fpm' WHERE d.php = 'fast-cgi' AND s.config LIKE '%\nserver_type=nginx\n%' AND s.config NOT LIKE '%\nserver_type=apache\n%'; + +UPDATE `web_domain` SET `php` = 'php-fpm' WHERE `php` = 'hhvm'; +UPDATE `web_domain` SET `php` = 'fast-cgi' WHERE `php` = 'cgi'; +UPDATE `web_domain` SET `php` = 'mod' WHERE `php` = 'suphp'; \ No newline at end of file -- GitLab From cb67fdf94bb79a46b9ebff3e1b73cc8e2e28f43a Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 11:24:32 +0100 Subject: [PATCH 179/310] - added acme.sh support --- interface/lib/classes/system.inc.php | 2 +- .../classes/cron.d/900-letsencrypt.inc.php | 24 +-- server/lib/classes/letsencrypt.inc.php | 147 +++++++++++++++--- 3 files changed, 139 insertions(+), 34 deletions(-) diff --git a/interface/lib/classes/system.inc.php b/interface/lib/classes/system.inc.php index cef9424a7..710722827 100644 --- a/interface/lib/classes/system.inc.php +++ b/interface/lib/classes/system.inc.php @@ -41,7 +41,7 @@ class system { // simple query cache if($this->client_service===null) - $this->client_service = $app->db->queryOneRecord("SELECT client.* FROM sys_user, client WHERE sys_user.userid = ? AND sys_user.client_id = client.client_id", $userid); + $this->client_service = $app->db->queryOneRecord("SELECT client.* FROM sys_user, client WHERE sys_user.userid = ? AND sys_user.client_id = client.client_id", $userid); // isn't service if(!$this->client_service) return false; diff --git a/server/lib/classes/cron.d/900-letsencrypt.inc.php b/server/lib/classes/cron.d/900-letsencrypt.inc.php index d03d4a184..1fc06f357 100644 --- a/server/lib/classes/cron.d/900-letsencrypt.inc.php +++ b/server/lib/classes/cron.d/900-letsencrypt.inc.php @@ -35,15 +35,11 @@ class cronjob_letsencrypt extends cronjob { /* 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(); } @@ -52,9 +48,19 @@ class cronjob_letsencrypt extends cronjob { $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); if(!isset($server_config['migration_mode']) || $server_config['migration_mode'] != 'y') { - $letsencrypt = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); - $letsencrypt = reset($letsencrypt); - if(is_executable($letsencrypt)) { + + $acme = $app->letsencrypt->get_acme_script(); + if($acme) { + // skip letsencrypt + parent::onRunJob(); + return; + } + + $letsencrypt = $app->letsencrypt->get_certbot_script(); + if($letsencrypt) { + $ret = null; + $val = 0; + $matches = array(); $version = exec($letsencrypt . ' --version 2>&1', $ret, $val); if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $version, $matches)) { $type = strtolower($matches[1]); @@ -85,11 +91,7 @@ class cronjob_letsencrypt extends cronjob { /* this function is optional if it contains no custom code */ public function onAfterRun() { - global $app; - parent::onAfterRun(); } } - -?> diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index 4f681cc48..254d5058c 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -42,10 +42,110 @@ class letsencrypt { public function __construct(){ } + + public function get_acme_script() { + $acme = excplode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); + $acme = reset($acme); + if(is_executable($acme)) { + return $acme; + } else { + return false; + } + } + + public function get_acme_command($domains, $key_file, $bundle_file, $cert_file) { + + $letsencrypt = $this->get_acme_script(); + + $cmd = ''; + // generate cli format + foreach($domains as $domain) { + $cmd .= (string) " -d " . $domain; + } + + $cmd = $letsencrypt . " --issue $cmd -w /usr/local/ispconfig/interface/acme && " . $letsencrypt . " --install-cert " . $cmd . " --key-file " . escapeshellarg($key_file) . " --fullchain-file " . escapeshellarg($bundle_file) . " --cert-file " . escapeshellarg($cert_file) . " --reloadcmd " . escapeshellarg($this->get_reload_command()); + + return $cmd; + } + + public function get_certbot_script() { + $letsencrypt = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); + $letsencrypt = reset($letsencrypt); + if(is_executable($letsencrypt)) { + return $letsencrypt; + } else { + return false; + } + } + private function install_acme() { + $install_cmd = 'wget -O - https://get.acme.sh | sh'; + $ret = null; + $val = 0; + exec($install_cmd . ' 2>&1', $ret, $val); + + return ($val == 0 ? true : false); + } + + private function get_reload_command() { + global $app, $conf; + + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + $daemon = ''; + switch ($web_config['server_type']) { + case 'nginx': + $daemon = $web_config['server_type']; + break; + default: + if(is_file($conf['init_scripts'] . '/' . 'httpd24-httpd') || is_dir('/opt/rh/httpd24/root/etc/httpd')) { + $daemon = 'httpd24-httpd'; + } elseif(is_file($conf['init_scripts'] . '/' . 'httpd') || is_dir('/etc/httpd')) { + $daemon = 'httpd'; + } else { + $daemon = 'apache2'; + } + } + + $cmd = $app->system->getinitcommand($daemon, 'force-reload'); + return $cmd; + } + + public function get_certbot_command($domains) { + + $letsencrypt = $this->get_certbot_script(); + + $cmd = ''; + // generate cli format + foreach($domains as $domain) { + $cmd .= (string) " --domains " . $domain; + } + + $matches = array(); + $ret = null; + $val = 0; + $letsencrypt_version = exec($letsencrypt . ' --version 2>&1', $ret, $val); + if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $letsencrypt_version, $matches)) { + $letsencrypt_version = $matches[2]; + } + if (version_compare($letsencrypt_version, '0.22', '>=')) { + $acme_version = 'https://acme-v02.api.letsencrypt.org/directory'; + } else { + $acme_version = 'https://acme-v01.api.letsencrypt.org/directory'; + } + + $cmd = $letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server $acme_version --rsa-key-size 4096 --email postmaster@$domain $cmd --webroot-path /usr/local/ispconfig/interface/acme"; + + return $cmd; + } + public function get_letsencrypt_certificate_paths($domains = array()) { global $app; + if($this->get_acme_script()) { + return false; + } + if(empty($domains)) return false; if(!is_dir($this->renew_config_path)) return false; @@ -183,11 +283,17 @@ class letsencrypt { $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); + $use_acme = false; + if($this->get_acme_script()) { + $use_acme = true; + } elseif(!$this->get_certbot_script()) { + // acme and le missing + $this->install_acme(); + } + $tmp = $app->letsencrypt->get_website_certificate_paths($data); $domain = $tmp['domain']; $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; $crt_file = $tmp['crt']; $bundle_file = $tmp['bundle']; @@ -256,43 +362,40 @@ class letsencrypt { $app->log("There were " . $le_domain_count . " domains in the domain list. LE only supports 100, so we strip the rest.", LOGLEVEL_WARN); } - // generate cli format - foreach($temp_domains as $temp_domain) { - $cli_domain_arg .= (string) " --domains " . $temp_domain; - } - // unset useless data unset($subdomains); unset($aliasdomains); $letsencrypt_cmd = ''; + if($use_acme) { + $letsencrypt_cmd = $this->get_acme_command($temp_domains, $key_file, $bundle_file, $crt_file); + } else { + $letsencrypt_cmd = $this->get_certbot_command($temp_domains); + } + $success = false; if(!empty($cli_domain_arg)) { if(!isset($server_config['migration_mode']) || $server_config['migration_mode'] != 'y') { $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); $app->log("Let's Encrypt SSL Cert domains: $cli_domain_arg", LOGLEVEL_DEBUG); - $letsencrypt = explode("\n", shell_exec('which letsencrypt certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot')); - $letsencrypt = reset($letsencrypt); - if(is_executable($letsencrypt)) { - $letsencrypt_version = exec($letsencrypt . ' --version 2>&1', $ret, $val); - if(preg_match('/^(\S+|\w+)\s+(\d+(\.\d+)+)$/', $letsencrypt_version, $matches)) { - $letsencrypt_version = $matches[2]; - } - if ($letsencrypt_version >=0.22) { - $acme_version = 'https://acme-v02.api.letsencrypt.org/directory'; - } else { - $acme_version = 'https://acme-v01.api.letsencrypt.org/directory'; - } - $letsencrypt_cmd = $letsencrypt . " certonly -n --text --agree-tos --expand --authenticator webroot --server $acme_version --rsa-key-size 4096 --email postmaster@$domain $cli_domain_arg --webroot-path /usr/local/ispconfig/interface/acme"; - $success = $app->system->_exec($letsencrypt_cmd); - } + $success = $app->system->_exec($letsencrypt_cmd); } else { $app->log("Migration mode active, skipping Let's Encrypt SSL Cert creation for: $domain", LOGLEVEL_DEBUG); $success = true; } } + if($use_acme === true) { + if(!$success) { + $app->log('Let\'s Encrypt SSL Cert for: ' . $domain . ' could not be issued.', LOGLEVEL_WARN); + $app->log($letsencrypt_cmd, LOGLEVEL_WARN); + return false; + } else { + return true; + } + } + $le_files = $this->get_letsencrypt_certificate_paths($temp_domains); unset($temp_domains); -- GitLab From a09188540958de4c27f13d76af5deed09a413db2 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 13:56:47 +0100 Subject: [PATCH 180/310] - ported rspamd support --- .../sql/incremental/upd_dev_collection.sql | 36 ++- install/sql/ispconfig3.sql | 19 +- install/tpl/mailfilter.master | 90 -------- install/tpl/server.ini.master | 2 + .../web/admin/form/server_config.tform.php | 80 ++++++- .../web/admin/lib/lang/de_server_config.lng | 5 +- .../web/admin/lib/lang/en_server_config.lng | 6 +- interface/web/admin/server_config_edit.php | 64 ++++++ .../templates/server_config_mail_edit.htm | 35 +++ .../web/mail/form/spamfilter_policy.tform.php | 36 +++ interface/web/mail/lib/lang/de.lng | 4 +- .../mail/lib/lang/de_spamfilter_policy.lng | 9 +- interface/web/mail/lib/lang/en.lng | 3 +- .../mail/lib/lang/en_spamfilter_policy.lng | 9 +- interface/web/mail/mail_domain_edit.php | 5 +- interface/web/mail/mail_user_edit.php | 4 +- interface/web/mail/spamfilter_policy_edit.php | 72 +++++- interface/web/mail/spamfilter_policy_list.php | 29 ++- .../mail/templates/spamfilter_policy_edit.htm | 5 +- .../mail/templates/spamfilter_policy_list.htm | 12 +- .../templates/spamfilter_taglevel_edit.htm | 29 ++- server/conf/apache_apps.vhost.master | 10 + server/conf/autoresponder.master | 4 +- server/conf/nginx_apps.vhost.master | 25 +++ server/conf/rspamd.local.lua.master | 3 + server/conf/rspamd_antivirus.conf.master | 30 +++ .../conf/rspamd_classifier-bayes.conf.master | 3 + server/conf/rspamd_dkim_signing.conf.master | 2 + server/conf/rspamd_greylist.conf.master | 1 + server/conf/rspamd_metrics.conf.master | 17 ++ .../conf/rspamd_metrics_override.conf.master | 159 +++++++++++++ server/conf/rspamd_mx_check.conf.master | 9 + server/conf/rspamd_users.conf.master | 43 ++++ server/conf/rspamd_users.inc.conf.master | 41 ++++ server/conf/rspamd_wblist.inc.conf.master | 18 ++ .../conf/rspamd_worker-controller.inc.master | 8 + server/conf/sieve_filter.master | 6 +- server/conf/sieve_filter_1.2.master | 6 +- server/mods-available/mail_module.inc.php | 37 +++ .../apps_vhost_plugin.inc.php | 22 +- .../postfix_server_plugin.inc.php | 150 ++++++++++++- .../plugins-available/rspamd_plugin.inc.php | 210 ++++++++++++++++++ 42 files changed, 1205 insertions(+), 153 deletions(-) delete mode 100644 install/tpl/mailfilter.master create mode 100644 server/conf/rspamd.local.lua.master create mode 100644 server/conf/rspamd_antivirus.conf.master create mode 100644 server/conf/rspamd_classifier-bayes.conf.master create mode 100644 server/conf/rspamd_dkim_signing.conf.master create mode 100644 server/conf/rspamd_greylist.conf.master create mode 100644 server/conf/rspamd_metrics.conf.master create mode 100644 server/conf/rspamd_metrics_override.conf.master create mode 100644 server/conf/rspamd_mx_check.conf.master create mode 100644 server/conf/rspamd_users.conf.master create mode 100644 server/conf/rspamd_users.inc.conf.master create mode 100644 server/conf/rspamd_wblist.inc.conf.master create mode 100644 server/conf/rspamd_worker-controller.inc.master create mode 100644 server/plugins-available/rspamd_plugin.inc.php diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 29d570078..351c89936 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -151,4 +151,38 @@ UPDATE `web_domain` as d INNER JOIN `server` as s ON (s.server_id = d.server_id) UPDATE `web_domain` SET `php` = 'php-fpm' WHERE `php` = 'hhvm'; UPDATE `web_domain` SET `php` = 'fast-cgi' WHERE `php` = 'cgi'; -UPDATE `web_domain` SET `php` = 'mod' WHERE `php` = 'suphp'; \ No newline at end of file +UPDATE `web_domain` SET `php` = 'mod' WHERE `php` = 'suphp'; + +-- rspamd +ALTER TABLE `spamfilter_policy` ADD `rspamd_greylisting` ENUM('n','y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'n' AFTER `policyd_greylist`; +ALTER TABLE `spamfilter_policy` ADD `rspamd_spam_greylisting_level` DECIMAL(5,2) NULL DEFAULT NULL AFTER `rspamd_greylisting`; +ALTER TABLE `spamfilter_policy` ADD `rspamd_spam_tag_level` DECIMAL(5,2) NULL DEFAULT NULL AFTER `rspamd_spam_greylisting_level`; +ALTER TABLE `spamfilter_policy` ADD `rspamd_spam_tag_method` ENUM('add_header','rewrite_subject') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'rewrite_subject' AFTER `rspamd_spam_tag_level`; +ALTER TABLE `spamfilter_policy` ADD `rspamd_spam_kill_level` DECIMAL(5,2) NULL DEFAULT NULL AFTER `rspamd_spam_tag_method`; + +UPDATE `spamfilter_policy` SET `rspamd_greylisting` = 'y' WHERE id = 4; +UPDATE `spamfilter_policy` SET `rspamd_greylisting` = 'y' WHERE id = 5; +UPDATE `spamfilter_policy` SET `rspamd_greylisting` = 'y' WHERE id = 6; + +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '4.00'; +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '6.00' WHERE id = 1; +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '999.00' WHERE id = 2; +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '999.00' WHERE id = 3; +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '2.00' WHERE id = 6; +UPDATE `spamfilter_policy` SET `rspamd_spam_greylisting_level` = '7.00' WHERE id = 7; + +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '6.00'; +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '8.00' WHERE id = 1; +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '999.00' WHERE id = 2; +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '999.00' WHERE id = 3; +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '4.00' WHERE id = 6; +UPDATE `spamfilter_policy` SET `rspamd_spam_tag_level` = '10.00' WHERE id = 7; + +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '10.00'; +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '12.00' WHERE id = 1; +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '999.00' WHERE id = 2; +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '999.00' WHERE id = 3; +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '8.00' WHERE id = 6; +UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '20.00' WHERE id = 7; +-- end of rspamd + diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index e5a99a293..2d86f57ff 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1576,6 +1576,11 @@ CREATE TABLE `spamfilter_policy` ( `policyd_quota_out` int(11) NOT NULL DEFAULT '-1', `policyd_quota_out_period` int(11) NOT NULL DEFAULT '24', `policyd_greylist` ENUM( 'Y', 'N' ) NOT NULL DEFAULT 'N', + `rspamd_greylisting` enum('n','y') NOT NULL DEFAULT 'n', + `rspamd_spam_greylisting_level` decimal(5,2) DEFAULT NULL, + `rspamd_spam_tag_level` decimal(5,2) DEFAULT NULL, + `rspamd_spam_tag_method` enum('add_header','rewrite_subject') NOT NULL DEFAULT 'rewrite_subject', + `rspamd_spam_kill_level` decimal(5,2) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; @@ -2423,13 +2428,13 @@ INSERT INTO `software_repo` (`software_repo_id`, `sys_userid`, `sys_groupid`, `s -- Dumping data for table `spamfilter_policy` -- -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(1, 1, 0, 'riud', 'riud', 'r', 'Non-paying', 'N', 'N', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'Y', '', '', '', '', '', '', 3, 7, 10, 0, 0, '', '', '', '', 'N', 'N', 'N', '', '', '', '', '', '', '', 0, ''); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(2, 1, 0, 'riud', 'riud', 'r', 'Uncensored', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', NULL, NULL, NULL, NULL, NULL, NULL, 3, 999, 999, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(3, 1, 0, 'riud', 'riud', 'r', 'Wants all spam', 'N', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 999, 999, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(4, 1, 0, 'riud', 'riud', 'r', 'Wants viruses', 'Y', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 6.9, 6.9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(5, 1, 0, 'riud', 'riud', 'r', 'Normal', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', '', '', '', '', '', '', 1, 4.5, 50, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '***SPAM***', NULL, NULL); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(6, 1, 0, 'riud', 'riud', 'r', 'Trigger happy', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 5, 5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); -INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`) VALUES(7, 1, 0, 'riud', 'riud', 'r', 'Permissive', 'N', 'N', 'N', 'Y', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 10, 20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(1, 1, 0, 'riud', 'riud', 'r', 'Non-paying', 'N', 'N', 'N', 'N', 'Y', 'Y', 'Y', 'N', 'Y', '', '', '', '', '', '', 3, 7, 10, 0, 0, '', '', '', '', 'N', 'N', 'N', '', '', '', '', '', '', '', 0, '', 'n', 6.00, 8.00, 'rewrite_subject', 12.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(2, 1, 0, 'riud', 'riud', 'r', 'Uncensored', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'N', 'N', 'N', NULL, NULL, NULL, NULL, NULL, NULL, 3, 999, 999, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'n', 999.00, 999.00, 'rewrite_subject', 999.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(3, 1, 0, 'riud', 'riud', 'r', 'Wants all spam', 'N', 'Y', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 999, 999, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'n', 999.00, 999.00, 'rewrite_subject', 999.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(4, 1, 0, 'riud', 'riud', 'r', 'Wants viruses', 'Y', 'N', 'Y', 'Y', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 6.9, 6.9, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'y', 4.00, 6.00, 'rewrite_subject', 10.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(5, 1, 0, 'riud', 'riud', 'r', 'Normal', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', '', '', '', '', '', '', 1, 4.5, 50, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '', '***SPAM***', NULL, NULL, 'y', 4.00, 6.00, 'rewrite_subject', 10.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(6, 1, 0, 'riud', 'riud', 'r', 'Trigger happy', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 5, 5, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'y', 2.00, 4.00, 'rewrite_subject', 8.00); +INSERT INTO `spamfilter_policy` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `policy_name`, `virus_lover`, `spam_lover`, `banned_files_lover`, `bad_header_lover`, `bypass_virus_checks`, `bypass_spam_checks`, `bypass_banned_checks`, `bypass_header_checks`, `spam_modifies_subj`, `virus_quarantine_to`, `spam_quarantine_to`, `banned_quarantine_to`, `bad_header_quarantine_to`, `clean_quarantine_to`, `other_quarantine_to`, `spam_tag_level`, `spam_tag2_level`, `spam_kill_level`, `spam_dsn_cutoff_level`, `spam_quarantine_cutoff_level`, `addr_extension_virus`, `addr_extension_spam`, `addr_extension_banned`, `addr_extension_bad_header`, `warnvirusrecip`, `warnbannedrecip`, `warnbadhrecip`, `newvirus_admin`, `virus_admin`, `banned_admin`, `bad_header_admin`, `spam_admin`, `spam_subject_tag`, `spam_subject_tag2`, `message_size_limit`, `banned_rulenames`, `rspamd_greylisting`, `rspamd_spam_greylisting_level`, `rspamd_spam_tag_level`, `rspamd_spam_tag_method`, `rspamd_spam_kill_level`) VALUES(7, 1, 0, 'riud', 'riud', 'r', 'Permissive', 'N', 'N', 'N', 'Y', 'N', 'N', 'N', 'N', 'Y', NULL, NULL, NULL, NULL, NULL, NULL, 3, 10, 20, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'n', 7.00, 10.00, 'rewrite_subject', 20.00); -- -------------------------------------------------------- diff --git a/install/tpl/mailfilter.master b/install/tpl/mailfilter.master deleted file mode 100644 index ba0e94539..000000000 --- a/install/tpl/mailfilter.master +++ /dev/null @@ -1,90 +0,0 @@ -# -# Import variables -# - -LOGNAME=tolower("$LOGNAME") -EXTENSION="$1" -RECIPIENT=tolower("$2") -USER=tolower("$3") -HOST=tolower("$4") -SENDER="$5" -DEFAULT="{dist_postfix_vmail_mailbox_base}/$HOST/$USER/." - -# Workaround for broken tolower function in some current fedora releases - -if(!$USER) -{ - USER=$3 -} -if(!$HOST) -{ - HOST=$4 -} - -if ( "$EXTENSION" ne "" ) -{ - DELIMITER="+" -} - -if (!$SENDER) -{ - SENDER = "<>" -} - -# -# Autocreate maildir, if not existant -# - -#`test -e {dist_postfix_vmail_mailbox_base}/$HOST` -#if ( $RETURNCODE != 0 ) -#{ -# `mkdir {dist_postfix_vmail_mailbox_base}/$HOST` -#} - -#`test -e {dist_postfix_vmail_mailbox_base}/$HOST/$USER` -#if ( $RETURNCODE != 0 ) -#{ -# `maildirmake {dist_postfix_vmail_mailbox_base}/$HOST/$USER` -# `chmod -R 0700 {dist_postfix_vmail_mailbox_base}/$HOST` -#} - -# Check if the user has a autoresponder enabled - -`test -f {dist_postfix_vmail_mailbox_base}/mailfilters/$HOST/$USER/.autoresponder` -if ( $RETURNCODE == 0 ) -{ - include "{dist_postfix_vmail_mailbox_base}/mailfilters/$HOST/$USER/.autoresponder" -} - -# Create a mailsize file -`test -e {dist_postfix_vmail_mailbox_base}/$HOST/$USER` -if ( $RETURNCODE == 0 ) -{ -`echo $SIZE >> {dist_postfix_vmail_mailbox_base}/$HOST/$USER/ispconfig_mailsize` -} - - -# -# Test if the user has his own maildrop include, -# if not available, check if $DEFAULT is set -# (newer maildrop get's that from the DB and updates -# it) and deliver or fail temporarily if not available -# - -`test -f {dist_postfix_vmail_mailbox_base}/mailfilters/$HOST/$USER/.mailfilter` -if ( $RETURNCODE == 0 ) -{ - include "{dist_postfix_vmail_mailbox_base}/mailfilters/$HOST/$USER/.mailfilter" -} -else -{ - if ( "$DEFAULT" ne "" ) - { - to "$DEFAULT" - } - else - { - EXITCODE=75 - exit - } -} \ No newline at end of file diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index d5bd6f9e2..172b68b2f 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -38,6 +38,8 @@ homedir_path=/var/vmail maildir_format=maildir dkim_path=/var/lib/amavis/dkim dkim_strength=1024 +content_filter=rspamd +rspamd_password= mailuser_uid=5000 mailuser_gid=5000 mailuser_name=vmail diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 19938e769..3eec00e9d 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -331,7 +331,12 @@ $form["tabs"]['server'] = array( ), 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'monit_user' => array( 'datatype' => 'VARCHAR', @@ -345,7 +350,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'monit_password' => array( 'datatype' => 'VARCHAR', @@ -353,7 +363,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'munin_url' => array( 'datatype' => 'VARCHAR', @@ -365,7 +380,12 @@ $form["tabs"]['server'] = array( ), 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'munin_user' => array( 'datatype' => 'VARCHAR', @@ -379,7 +399,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'munin_password' => array( 'datatype' => 'VARCHAR', @@ -387,7 +412,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'nagios_url' => array( 'datatype' => 'VARCHAR', @@ -399,7 +429,12 @@ $form["tabs"]['server'] = array( ), 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'nagios_user' => array( 'datatype' => 'VARCHAR', @@ -407,7 +442,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'nagios_password' => array( 'datatype' => 'VARCHAR', @@ -415,7 +455,12 @@ $form["tabs"]['server'] = array( 'default' => '', 'value' => '', 'width' => '40', - 'maxlength' => '255' + 'maxlength' => '255', + 'filters' => array( 0 => array( + 'event' => 'SAVE', + 'type' => 'TRIM' + ), + ) ), 'monitor_system_updates' => array( 'datatype' => 'VARCHAR', @@ -494,6 +539,23 @@ $form["tabs"]['mail'] = array( 'width' => '40', 'maxlength' => '255' ), + 'content_filter' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'rspamd', + 'value' => array('amavisd' => 'Amavisd', 'rspamd' => 'Rspamd') + ), + 'rspamd_password' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'TEXT', + 'default' => '', + 'value' => '', + 'width' => '40', + 'maxlength' => '255', + 'filters' => array( 0 => array( 'event' => 'SAVE', + 'type' => 'TRIM'), + ), + ), 'dkim_path' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index e3ac69888..f05d36b6c 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -299,4 +299,7 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Beschreibung Standard PHP'; $wb['php_default_name_error_empty'] = 'Beschreibung Standard PHP ist leer.'; -?> +$wb['content_filter_txt'] = 'Content-Filter'; +$wb['rspamd_url_txt'] = 'Rspamd-URL'; +$wb['rspamd_user_txt'] = 'Rspamd-Benutzer'; +$wb['rspamd_password_txt'] = 'Rspamd-Passwort'; \ No newline at end of file diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index 7a960e552..ce9d6e428 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -301,4 +301,8 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; -?> +$wb['content_filter_txt'] = 'Content Filter'; +$wb['rspamd_url_txt'] = 'Rspamd URL'; +$wb['rspamd_user_txt'] = 'Rspamd User'; +$wb['rspamd_password_txt'] = 'Rspamd Password'; + diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index e446bf3ad..9c344e074 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -52,6 +52,21 @@ $app->load('tform_actions'); class page_action extends tform_actions { + function onShow() { + global $app, $conf; + + // get the config + $app->uses('getconf'); + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + if($web_config['server_type'] == 'nginx'){ + unset($app->tform->formDef["tabs"]["fastcgi"]); + unset($app->tform->formDef["tabs"]["vlogger"]); + } + + parent::onShow(); + } + function onShowEdit() { global $app, $conf; @@ -64,11 +79,17 @@ class page_action extends tform_actions { $server_id = $this->id; $this->dataRecord = $app->getconf->get_server_config($server_id, $section); + + if($section == 'mail'){ + $server_config = $app->getconf->get_server_config($server_id, 'server'); + $rspamd_url = 'https://'.$server_config['hostname'].':8081/rspamd/'; + } } $record = $app->tform->getHTML($this->dataRecord, $this->active_tab, 'EDIT'); $record['id'] = $this->id; + if(isset($rspamd_url)) $record['rspamd_url'] = $rspamd_url; $app->tpl->setVar($record); } @@ -112,6 +133,49 @@ class page_action extends tform_actions { } } + function onAfterUpdate() { + global $app; + + if(isset($this->dataRecord['content_filter'])){ + $app->uses('ini_parser'); + $old_config = $app->ini_parser->parse_ini_string(stripslashes($this->oldDataRecord['config'])); + if($this->dataRecord['content_filter'] == 'rspamd' && $old_config['mail']['content_filter'] != $this->dataRecord['content_filter']){ + + $spamfilter_users = $app->db->queryAllRecords("SELECT * FROM spamfilter_users WHERE server_id = ?", intval($this->id)); + if(is_array($spamfilter_users) && !empty($spamfilter_users)){ + foreach($spamfilter_users as $spamfilter_user){ + $app->db->datalogUpdate('spamfilter_users', $spamfilter_user, 'id', $spamfilter_user["id"], true); + } + } + + $spamfilter_wblists = $app->db->queryAllRecords("SELECT * FROM spamfilter_wblist WHERE server_id = ?", intval($this->id)); + if(is_array($spamfilter_wblists) && !empty($spamfilter_wblists)){ + foreach($spamfilter_wblists as $spamfilter_wblist){ + $app->db->datalogUpdate('spamfilter_wblist', $spamfilter_wblist, 'wblist_id', $spamfilter_wblist["wblist_id"], true); + } + } + + $mail_users = $app->db->queryAllRecords("SELECT * FROM mail_user WHERE server_id = ? AND (autoresponder = 'y' OR move_junk = 'y')", intval($this->id)); + if(is_array($mail_users) && !empty($mail_users)){ + foreach($mail_users as $mail_user){ + if($mail_user['autoresponder'] == 'y'){ + $mail_user['autoresponder'] = 'n'; + $app->db->datalogUpdate('mail_user', $mail_user, 'mailuser_id', $mail_user["mailuser_id"], true); + $mail_user['autoresponder'] = 'y'; + $app->db->datalogUpdate('mail_user', $mail_user, 'mailuser_id', $mail_user["mailuser_id"], true); + } else { + $mail_user['move_junk'] = 'n'; + $app->db->datalogUpdate('mail_user', $mail_user, 'mailuser_id', $mail_user["mailuser_id"], true); + $mail_user['move_junk'] = 'y'; + $app->db->datalogUpdate('mail_user', $mail_user, 'mailuser_id', $mail_user["mailuser_id"], true); + } + + } + } + } + } + } + } $app->tform_actions = new page_action; diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm index 5323e98b4..9b12dbc0a 100644 --- a/interface/web/admin/templates/server_config_mail_edit.htm +++ b/interface/web/admin/templates/server_config_mail_edit.htm @@ -32,6 +32,20 @@ {tmpl_var name='dkim_strength'} +
+ +
+
+
+ + +
+
+ +
+
@@ -119,3 +133,24 @@ + + diff --git a/interface/web/mail/form/spamfilter_policy.tform.php b/interface/web/mail/form/spamfilter_policy.tform.php index 31e8b8092..f0fc645cb 100644 --- a/interface/web/mail/form/spamfilter_policy.tform.php +++ b/interface/web/mail/form/spamfilter_policy.tform.php @@ -216,6 +216,42 @@ $form["tabs"]['quarantine'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'rspamd_greylisting' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'rspamd_spam_greylisting_level' => array ( + 'datatype' => 'DOUBLE', + 'formtype' => 'TEXT', + 'default' => '0', + 'value' => '', + 'width' => '10', + 'maxlength' => '255' + ), + 'rspamd_spam_tag_level' => array ( + 'datatype' => 'DOUBLE', + 'formtype' => 'TEXT', + 'default' => '0', + 'value' => '', + 'width' => '10', + 'maxlength' => '255' + ), + 'rspamd_spam_tag_method' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => 'rewrite_subject', + 'value' => array('add_header' => $app->lng('add_header_txt'), 'rewrite_subject' => $app->lng('rewrite_subject_txt')) + ), + 'rspamd_spam_kill_level' => array ( + 'datatype' => 'DOUBLE', + 'formtype' => 'TEXT', + 'default' => '0', + 'value' => '', + 'width' => '10', + 'maxlength' => '255' + ), //################################# // ENDE Datatable fields //################################# diff --git a/interface/web/mail/lib/lang/de.lng b/interface/web/mail/lib/lang/de.lng index 91418972d..108d7d5cc 100644 --- a/interface/web/mail/lib/lang/de.lng +++ b/interface/web/mail/lib/lang/de.lng @@ -45,4 +45,6 @@ $wb['Global Filters'] = 'Globale Filter'; $wb['Domain Alias'] = 'E-Mail Domain Alias'; $wb['Relay Recipients'] = 'Relay Empfänger'; $wb['Mailbox quota'] = 'E-Mail Konto Speichernutzung'; -?> +$wb['add_header_txt'] = 'Header (fügt "X-Spam: Yes" hinzu)'; +$wb['rewrite_subject_txt'] = 'Betreff (fügt "***SPAM***" am Anfang hinzu)'; + diff --git a/interface/web/mail/lib/lang/de_spamfilter_policy.lng b/interface/web/mail/lib/lang/de_spamfilter_policy.lng index 32acca468..bb53335eb 100644 --- a/interface/web/mail/lib/lang/de_spamfilter_policy.lng +++ b/interface/web/mail/lib/lang/de_spamfilter_policy.lng @@ -35,4 +35,11 @@ $wb['bad_header_admin_txt'] = 'Bad Header Administrator'; $wb['spam_admin_txt'] = 'SPAM Administrator'; $wb['message_size_limit_txt'] = 'Nachrichtengrößen Limit'; $wb['banned_rulenames_txt'] = 'Banned Richtliniennamen'; -?> +$wb['rspamd_greylisting_txt'] = 'Greylisting nutzen'; +$wb['rspamd_spam_greylisting_level_txt'] = 'Greylisting-Level'; +$wb['rspamd_spam_tag_level_txt'] = 'SPAM-Markierungslevel'; +$wb['rspamd_spam_tag_method_txt'] = 'SPAM-Markierungsmethode'; +$wb['rspamd_spam_kill_level_txt'] = 'SPAM-Reject-Level'; +$wb['btn_save_txt'] = 'Speichern'; +$wb['btn_cancel_txt'] = 'Abbrechen'; + diff --git a/interface/web/mail/lib/lang/en.lng b/interface/web/mail/lib/lang/en.lng index e320511bb..d41761d25 100644 --- a/interface/web/mail/lib/lang/en.lng +++ b/interface/web/mail/lib/lang/en.lng @@ -45,4 +45,5 @@ $wb['Global Filters'] = 'Global Filters'; $wb['Domain Alias'] = 'Domain Alias'; $wb["Relay Recipients"] = 'Relay Recipients'; $wb['Mailbox quota'] = 'Mailbox quota'; -?> +$wb['add_header_txt'] = 'Header (adds "X-Spam: Yes")'; +$wb['rewrite_subject_txt'] = 'Subject (adds "***SPAM***" at the beginning)'; diff --git a/interface/web/mail/lib/lang/en_spamfilter_policy.lng b/interface/web/mail/lib/lang/en_spamfilter_policy.lng index 2e0f05d6c..f9e8a8e30 100644 --- a/interface/web/mail/lib/lang/en_spamfilter_policy.lng +++ b/interface/web/mail/lib/lang/en_spamfilter_policy.lng @@ -35,4 +35,11 @@ $wb["bad_header_admin_txt"] = 'Bad header admin'; $wb["spam_admin_txt"] = 'SPAM admin'; $wb["message_size_limit_txt"] = 'Message size limit'; $wb["banned_rulenames_txt"] = 'Banned rulenames'; -?> +$wb['rspamd_greylisting_txt'] = 'Use greylisting'; +$wb['rspamd_spam_greylisting_level_txt'] = 'Greylisting level'; +$wb['rspamd_spam_tag_level_txt'] = 'SPAM tag level'; +$wb['rspamd_spam_tag_method_txt'] = 'SPAM tag method'; +$wb['rspamd_spam_kill_level_txt'] = 'SPAM reject level'; +$wb['btn_save_txt'] = 'Save'; +$wb['btn_cancel_txt'] = 'Cancel'; +?> \ No newline at end of file diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index d7d6ea4c6..4d7b7d8d3 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -273,7 +273,10 @@ class page_action extends tform_actions { } //* make sure that the email domain is lowercase - if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + if(isset($this->dataRecord["domain"])){ + $this->dataRecord["domain"] = $app->functions->idn_encode($this->dataRecord["domain"]); + $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); + } parent::onSubmit(); diff --git a/interface/web/mail/mail_user_edit.php b/interface/web/mail/mail_user_edit.php index 910d7a096..263b98ef3 100644 --- a/interface/web/mail/mail_user_edit.php +++ b/interface/web/mail/mail_user_edit.php @@ -295,7 +295,7 @@ class page_action extends tform_actions { "priority" => 10, "policy_id" => $policy_id, "email" => $this->dataRecord["email"], - "fullname" => $this->dataRecord["email"], + "fullname" => $app->functions->idn_decode($this->dataRecord["email"]), "local" => 'Y' ); $app->db->datalogInsert('spamfilter_users', $insert_data, 'id'); @@ -342,7 +342,7 @@ class page_action extends tform_actions { "priority" => 10, "policy_id" => $policy_id, "email" => $this->dataRecord["email"], - "fullname" => $this->dataRecord["email"], + "fullname" => $app->functions->idn_decode($this->dataRecord["email"]), "local" => 'Y' ); $app->db->datalogInsert('spamfilter_users', $insert_data, 'id'); diff --git a/interface/web/mail/spamfilter_policy_edit.php b/interface/web/mail/spamfilter_policy_edit.php index 532050684..55a42fe84 100644 --- a/interface/web/mail/spamfilter_policy_edit.php +++ b/interface/web/mail/spamfilter_policy_edit.php @@ -49,6 +49,46 @@ $app->uses('tpl,tform,tform_actions'); $app->load('tform_actions'); class page_action extends tform_actions { + + function onShow() { + global $app, $conf; + + // get the config + $app->uses('getconf'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + $content_filter = 'amavisd'; + if($mail_config['content_filter'] == 'rspamd'){ + $content_filter = 'rspamd'; + unset($app->tform->formDef["tabs"]["policy"]['fields']['banned_files_lover']); + unset($app->tform->formDef["tabs"]["policy"]['fields']['bad_header_lover']); + unset($app->tform->formDef["tabs"]["policy"]['fields']['bypass_virus_checks']); + unset($app->tform->formDef["tabs"]["policy"]['fields']['bypass_banned_checks']); + unset($app->tform->formDef["tabs"]["policy"]['fields']['bypass_header_checks']); + + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_tag_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_tag2_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_kill_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_dsn_cutoff_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_quarantine_cutoff_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_modifies_subj']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_subject_tag']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['spam_subject_tag2']); + + unset($app->tform->formDef["tabs"]["quarantine"]); + unset($app->tform->formDef["tabs"]["other"]); + } else { + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['rspamd_greylisting']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['rspamd_spam_greylisting_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['rspamd_spam_tag_level']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['rspamd_spam_tag_method']); + unset($app->tform->formDef["tabs"]["taglevel"]['fields']['rspamd_spam_kill_level']); + } + $app->tpl->setVar("content_filter", $content_filter); + + parent::onShow(); + } + function onShowNew() { global $app, $conf; @@ -86,11 +126,37 @@ class page_action extends tform_actions { parent::onSubmit(); } + + function onAfterUpdate() { + global $app, $conf; + + $app->uses('getconf'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + $record_has_changed = false; + if(isset($this->dataRecord['rspamd_spam_greylisting_level']) && !isset($this->dataRecord['rspamd_greylisting'])) $this->dataRecord['rspamd_greylisting'] = 'n'; + foreach($this->dataRecord as $key => $val) { + if(isset($this->oldDataRecord[$key]) && @$this->oldDataRecord[$key] != $val) { + // Record has changed + $record_has_changed = true; + } + } + + if($record_has_changed){ + $spamfilter_users = $app->db->queryAllRecords("SELECT * FROM spamfilter_users WHERE policy_id = ?", intval($this->id)); + + if(is_array($spamfilter_users) && !empty($spamfilter_users)){ + foreach($spamfilter_users as $spamfilter_user){ + $app->db->datalogUpdate('spamfilter_users', $spamfilter_user, 'id', $spamfilter_user["id"], true); + } + } + } + } + } } $app->tform_actions = new page_action; $app->tform_actions->onLoad(); - - -?> +?> \ No newline at end of file diff --git a/interface/web/mail/spamfilter_policy_list.php b/interface/web/mail/spamfilter_policy_list.php index c2ab38d5f..2aa7c7bec 100644 --- a/interface/web/mail/spamfilter_policy_list.php +++ b/interface/web/mail/spamfilter_policy_list.php @@ -16,9 +16,28 @@ $list_def_file = "list/spamfilter_policy.list.php"; $app->auth->check_module_permissions('mail'); $app->uses('listform_actions'); -//$app->listform_actions->SQLExtWhere = "wb = 'W'"; -$app->listform_actions->onLoad(); - - -?> +class list_action extends listform_actions { + + function onShow() { + global $app, $conf; + + // get the config + $app->uses('getconf'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + $content_filter = 'amavisd'; + if($mail_config['content_filter'] == 'rspamd'){ + $content_filter = 'rspamd'; + } + $app->tpl->setVar("content_filter", $content_filter); + + parent::onShow(); + } + +} + +$list = new list_action; +//$list->SQLExtWhere = "wb = 'W'"; +$list->onLoad(); +?> \ No newline at end of file diff --git a/interface/web/mail/templates/spamfilter_policy_edit.htm b/interface/web/mail/templates/spamfilter_policy_edit.htm index 317bbdb82..eb8b6c1cb 100644 --- a/interface/web/mail/templates/spamfilter_policy_edit.htm +++ b/interface/web/mail/templates/spamfilter_policy_edit.htm @@ -20,6 +20,7 @@ {tmpl_var name='spam_lover'} +
- +
-
\ No newline at end of file + diff --git a/interface/web/mail/templates/spamfilter_policy_list.htm b/interface/web/mail/templates/spamfilter_policy_list.htm index da1183d75..84b1a0440 100644 --- a/interface/web/mail/templates/spamfilter_policy_list.htm +++ b/interface/web/mail/templates/spamfilter_policy_list.htm @@ -19,16 +19,20 @@ + + {tmpl_var name='search_limit'} + + @@ -40,8 +44,10 @@ {tmpl_var name="policy_name"} {tmpl_var name="virus_lover"} {tmpl_var name="spam_lover"} + {tmpl_var name="banned_files_lover"} {tmpl_var name="bad_header_lover"} + @@ -49,17 +55,17 @@
- {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - + - \ No newline at end of file + diff --git a/interface/web/mail/templates/spamfilter_taglevel_edit.htm b/interface/web/mail/templates/spamfilter_taglevel_edit.htm index ba92662ba..73fd4e6ac 100644 --- a/interface/web/mail/templates/spamfilter_taglevel_edit.htm +++ b/interface/web/mail/templates/spamfilter_taglevel_edit.htm @@ -4,7 +4,7 @@

- +
@@ -32,6 +32,33 @@
+
+ +
+ +
+ {tmpl_var name='rspamd_greylisting'} +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
diff --git a/server/conf/apache_apps.vhost.master b/server/conf/apache_apps.vhost.master index ecd3ff1a0..d77cde2e4 100644 --- a/server/conf/apache_apps.vhost.master +++ b/server/conf/apache_apps.vhost.master @@ -52,6 +52,16 @@ +{tmpl_if name="use_rspamd"} + + Order allow,deny + Allow from all + + RewriteEngine On + RewriteRule ^/rspamd$ /rspamd/ [R,L] + RewriteRule ^/rspamd/(.*) http://127.0.0.1:11334/$1 [P] +{/tmpl_if} + diff --git a/server/conf/autoresponder.master b/server/conf/autoresponder.master index 0126c998d..3e84b802f 100644 --- a/server/conf/autoresponder.master +++ b/server/conf/autoresponder.master @@ -4,7 +4,7 @@ if ($RETURNCODE==1) { if (!/^List-Unsubscribe:.*/:h ) { - if (!/^X-Spam-Flag: YES/:h ) + if (!/^(X-Spam-Flag: YES|X-Spam: Yes|Subject: \*\*\*\s*SPAM\s*\*\*\*.*)/:h ) { NOW=time if ({start_date} lt $NOW && {end_date} gt $NOW) @@ -20,4 +20,4 @@ if ($RETURNCODE==1) } } } -} \ No newline at end of file +} diff --git a/server/conf/nginx_apps.vhost.master b/server/conf/nginx_apps.vhost.master index 75daa4df8..1c8c4e70a 100644 --- a/server/conf/nginx_apps.vhost.master +++ b/server/conf/nginx_apps.vhost.master @@ -199,4 +199,29 @@ server { alias /var/lib/mailman/archives/public; autoindex on; } + + {use_rspamd}location /rspamd/ { + {use_rspamd}proxy_pass http://127.0.0.1:11334/; + {use_rspamd}rewrite ^//(.*) /$1; + {use_rspamd}proxy_set_header X-Forwarded-Proto $scheme; + {use_rspamd}proxy_set_header Host $host; + {use_rspamd}proxy_set_header X-Real-IP $remote_addr; + {use_rspamd}proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + {use_rspamd}proxy_pass_header Authorization; + {use_rspamd}client_max_body_size 0; + {use_rspamd}client_body_buffer_size 1m; + {use_rspamd}proxy_intercept_errors on; + {use_rspamd}proxy_buffering on; + {use_rspamd}proxy_buffer_size 128k; + {use_rspamd}proxy_buffers 256 16k; + {use_rspamd}proxy_busy_buffers_size 256k; + {use_rspamd}proxy_temp_file_write_size 256k; + {use_rspamd}proxy_max_temp_file_size 0; + {use_rspamd}proxy_read_timeout 300; + {use_rspamd} + {use_rspamd}location ~* ^/rspamd/(.+\.(jpg|jpeg|gif|css|png|js|ico|html?|xml|txt))$ { + {use_rspamd}alias /usr/share/rspamd/www/$1; + {use_rspamd}} + {use_rspamd}} + } diff --git a/server/conf/rspamd.local.lua.master b/server/conf/rspamd.local.lua.master new file mode 100644 index 000000000..8ef81da26 --- /dev/null +++ b/server/conf/rspamd.local.lua.master @@ -0,0 +1,3 @@ +rspamd_config.R_DUMMY = function (task) + return true +end \ No newline at end of file diff --git a/server/conf/rspamd_antivirus.conf.master b/server/conf/rspamd_antivirus.conf.master new file mode 100644 index 000000000..71427d762 --- /dev/null +++ b/server/conf/rspamd_antivirus.conf.master @@ -0,0 +1,30 @@ +clamav { + # If set force this action if any virus is found (default unset: no action is forced) + #action = "reject"; + # if `true` only messages with non-image attachments will be checked (default true) + attachments_only = true; + # If `max_size` is set, messages > n bytes in size are not scanned + #max_size = 20000000; + # symbol to add (add it to metric if you want non-zero weight) + symbol = "CLAM_VIRUS"; + # type of scanner: "clamav", "fprot", "sophos" or "savapi" + type = "clamav"; + # For "savapi" you must also specify the following variable + #product_id = 12345; + # You can enable logging for clean messages + #log_clean = true; + # servers to query (if port is unspecified, scanner-specific default is used) + # can be specified multiple times to pool servers + # can be set to a path to a unix socket + # Enable this in local.d/antivirus.conf + #servers = "127.0.0.1:3310"; + servers = "/var/run/clamav/clamd.ctl"; + # if `patterns` is specified virus name will be matched against provided regexes and the related + # symbol will be yielded if a match is found. If no match is found, default symbol is yielded. + patterns { + # symbol_name = "pattern"; + JUST_EICAR = "^Eicar-Test-Signature$"; + } + # `whitelist` points to a map of IP addresses. Mail from these addresses is not scanned. + whitelist = "/etc/rspamd/antivirus.wl"; +} \ No newline at end of file diff --git a/server/conf/rspamd_classifier-bayes.conf.master b/server/conf/rspamd_classifier-bayes.conf.master new file mode 100644 index 000000000..1688d57e2 --- /dev/null +++ b/server/conf/rspamd_classifier-bayes.conf.master @@ -0,0 +1,3 @@ +autolearn = [-0.01, 5.00]; +per_user = true; +per_language = true; \ No newline at end of file diff --git a/server/conf/rspamd_dkim_signing.conf.master b/server/conf/rspamd_dkim_signing.conf.master new file mode 100644 index 000000000..0e55a7ead --- /dev/null +++ b/server/conf/rspamd_dkim_signing.conf.master @@ -0,0 +1,2 @@ +path = "/$domain.private"; +selector = "default"; \ No newline at end of file diff --git a/server/conf/rspamd_greylist.conf.master b/server/conf/rspamd_greylist.conf.master new file mode 100644 index 000000000..74ea715a2 --- /dev/null +++ b/server/conf/rspamd_greylist.conf.master @@ -0,0 +1 @@ +servers = "127.0.0.1:6379"; \ No newline at end of file diff --git a/server/conf/rspamd_metrics.conf.master b/server/conf/rspamd_metrics.conf.master new file mode 100644 index 000000000..f59eff0f0 --- /dev/null +++ b/server/conf/rspamd_metrics.conf.master @@ -0,0 +1,17 @@ +subject = "***SPAM*** %s"; + +symbol { + weight = 50; + name = "CLAM_VIRUS"; + description = "Clamav has found a virus."; +} +symbol { + weight = 50; + name = "JUST_EICAR"; + description = "Clamav has found a virus."; +} +symbol { + weight = 0.0; + name = "R_DUMMY"; + description = "Dummy symbol"; +} \ No newline at end of file diff --git a/server/conf/rspamd_metrics_override.conf.master b/server/conf/rspamd_metrics_override.conf.master new file mode 100644 index 000000000..8e3df15ed --- /dev/null +++ b/server/conf/rspamd_metrics_override.conf.master @@ -0,0 +1,159 @@ +# RBL +symbol "RBL_SENDERSCORE" { + weight = 4.0; + description = "From address is listed in senderscore.com BL"; +} +symbol "RBL_SPAMHAUS_SBL" { + weight = 2.0; + description = "From address is listed in zen sbl"; +} +symbol "RBL_SPAMHAUS_CSS" { + weight = 2.0; + description = "From address is listed in zen css"; +} +symbol "RBL_SPAMHAUS_XBL" { + weight = 4.0; + description = "From address is listed in zen xbl"; +} +symbol "RBL_SPAMHAUS_XBL_ANY" { + weight = 4.0; + description = "From or receive address is listed in zen xbl (any list)"; +} +symbol "RBL_SPAMHAUS_PBL" { + weight = 2.0; + description = "From address is listed in zen pbl (ISP list)"; +} +symbol "RBL_SPAMHAUS_DROP" { + weight = 7.0; + description = "From address is listed in zen drop bl"; +} +symbol "RECEIVED_SPAMHAUS_XBL" { + weight = 3.0; + description = "Received address is listed in zen xbl"; + one_shot = true; +} +symbol "RBL_MAILSPIKE_WORST" { + weight = 2.0; + description = "From address is listed in RBL - worst possible reputation"; +} +symbol "RBL_MAILSPIKE_VERYBAD" { + weight = 1.5; + description = "From address is listed in RBL - very bad reputation"; +} +symbol "RBL_MAILSPIKE_BAD" { + weight = 1.0; + description = "From address is listed in RBL - bad reputation"; +} +symbol "RBL_SEM" { + weight = 1.0; + description = "Address is listed in Spameatingmonkey RBL"; +} +# /RBL +# SURBL +symbol "PH_SURBL_MULTI" { + weight = 5.5; + description = "SURBL: Phishing sites"; +} +symbol "MW_SURBL_MULTI" { + weight = 5.5; + description = "SURBL: Malware sites"; +} +symbol "ABUSE_SURBL" { + weight = 5.5; + description = "SURBL: ABUSE"; +} +symbol "CRACKED_SURBL" { + weight = 4.0; + description = "SURBL: cracked site"; +} +symbol "RAMBLER_URIBL" { + weight = 4.5; + description = "Rambler uribl"; + one_shot = true; +} +symbol "RAMBLER_EMAILBL" { + weight = 9.5; + description = "Rambler emailbl"; + one_shot = true; +} +symbol "MSBL_EBL" { + weight = 7.5; + description = "MSBL emailbl"; + one_shot = true; +} +symbol "SEM_URIBL" { + weight = 3.5; + description = "Spameatingmonkey uribl"; +} +symbol "SEM_URIBL_FRESH15" { + weight = 3.0; + description = "Spameatingmonkey uribl. Domains registered in the last 15 days (.AERO,.BIZ,.COM,.INFO,.NAME,.NET,.PRO,.SK,.TEL,.US)"; +} +symbol "DBL" { + weight = 0.0; + description = "DBL unknown result"; +} +symbol "DBL_SPAM" { + weight = 6.5; + description = "DBL uribl spam"; +} +symbol "DBL_PHISH" { + weight = 6.5; + description = "DBL uribl phishing"; +} +symbol "DBL_MALWARE" { + weight = 6.5; + description = "DBL uribl malware"; +} +symbol "DBL_BOTNET" { + weight = 5.5; + description = "DBL uribl botnet C&C domain"; +} +symbol "DBL_ABUSE" { + weight = 6.5; + description = "DBL uribl abused legit spam"; +} +symbol "DBL_ABUSE_REDIR" { + weight = 1.5; + description = "DBL uribl abused spammed redirector domain"; +} +symbol "DBL_ABUSE_PHISH" { + weight = 7.5; + description = "DBL uribl abused legit phish"; +} +symbol "DBL_ABUSE_MALWARE" { + weight = 7.5; + description = "DBL uribl abused legit malware"; +} +symbol "DBL_ABUSE_BOTNET" { + weight = 5.5; + description = "DBL uribl abused legit botnet C&C"; +} +symbol "URIBL_BLACK" { + weight = 7.5; + description = "uribl.com black url"; +} +symbol "URIBL_RED" { + weight = 3.5; + description = "uribl.com red url"; +} +symbol "URIBL_GREY" { + weight = 1.5; + description = "uribl.com grey url"; + one_shot = true; +} +symbol "URIBL_SBL" { + weight = 6.5; + description = "Spamhaus SBL URIBL"; +} +symbol "URIBL_SBL_CSS" { + weight = 6.5; + description = "Spamhaus SBL CSS URIBL"; +} +symbol "RBL_SARBL_BAD" { + weight = 2.5; + description = "A domain listed in the mail is blacklisted in SARBL"; +} +# /SURBL +actions { +} \ No newline at end of file diff --git a/server/conf/rspamd_mx_check.conf.master b/server/conf/rspamd_mx_check.conf.master new file mode 100644 index 000000000..0a628f9c8 --- /dev/null +++ b/server/conf/rspamd_mx_check.conf.master @@ -0,0 +1,9 @@ +enabled = true; +servers = "localhost"; +key_prefix = "rmx"; +symbol_bad_mx = "MX_INVALID"; +symbol_no_mx = "MX_MISSING"; +symbol_good_mx = "MX_GOOD"; +expire = 86400; +expire_novalid = 7200; +greylist_invalid = false; \ No newline at end of file diff --git a/server/conf/rspamd_users.conf.master b/server/conf/rspamd_users.conf.master new file mode 100644 index 000000000..975300bf9 --- /dev/null +++ b/server/conf/rspamd_users.conf.master @@ -0,0 +1,43 @@ +settings { + authenticated { + priority = 10; + authenticated = yes; + #apply "default" { groups_disabled = ["rbl", "spf"]; } + apply "default" { + symbols_enabled = []; + symbols_disabled = []; + groups_enabled = []; + groups_disabled = []; + } + } + whitelist { + priority = 10; + rcpt = "postmaster"; + rcpt = "hostmaster"; + rcpt = "abuse"; + want_spam = yes; + } + whitelist-ip { + priority = 10; + + ip = ""; + + + want_spam = yes; + } + whitelist-timmehosting { + priority = 20; + from = "@timmehosting.de"; + from = "@timmehosting.com"; + want_spam = yes; + } + whitelist-ca { + priority = 20; + from = "@comodo.com"; + from = "@geotrust.com"; + from = "@geotrusteurope.com"; + want_spam = yes; + } + .include(try=true; glob=true) "$LOCAL_CONFDIR/local.d/users/*.conf" + .include(try=true; priority=1,duplicate=merge) "$LOCAL_CONFDIR/local.d/users.local.conf" +} diff --git a/server/conf/rspamd_users.inc.conf.master b/server/conf/rspamd_users.inc.conf.master new file mode 100644 index 000000000..1fe08439a --- /dev/null +++ b/server/conf/rspamd_users.inc.conf.master @@ -0,0 +1,41 @@ +spamfilter_users- { + priority = ; + rcpt = ""; + + want_spam = yes; + + + apply "default" { + CLAM_VIRUS = 1999.0; + JUST_EICAR = 1999.0; + actions { + reject = 999.0; + } + } + + + apply "default" { + CLAM_VIRUS = -999.0; + JUST_EICAR = -999.0; + actions { + greylist = ; + + = ; + reject = ; + } + } + + + apply "default" { + CLAM_VIRUS = ; + JUST_EICAR = ; + actions { + greylist = ; + + = ; + reject = ; + } + } + + +} \ No newline at end of file diff --git a/server/conf/rspamd_wblist.inc.conf.master b/server/conf/rspamd_wblist.inc.conf.master new file mode 100644 index 000000000..fc06127ea --- /dev/null +++ b/server/conf/rspamd_wblist.inc.conf.master @@ -0,0 +1,18 @@ +spamfilter_wblist- { + priority = ; + from = ""; + rcpt = ""; + + want_spam = yes; + + apply "default" { + R_DUMMY = 999.0; + actions { + reject = 0.2; + add_header = 0.1; + greylist = 0.1; + rewrite_subject = 0.1; + } + } + +} \ No newline at end of file diff --git a/server/conf/rspamd_worker-controller.inc.master b/server/conf/rspamd_worker-controller.inc.master new file mode 100644 index 000000000..75b744c88 --- /dev/null +++ b/server/conf/rspamd_worker-controller.inc.master @@ -0,0 +1,8 @@ +# Included from top-level .conf file + +type = "controller"; +count = 1; +password = ""; +secure_ip = "127.0.0.1"; +secure_ip = "::1"; +static_dir = "${WWWDIR}"; \ No newline at end of file diff --git a/server/conf/sieve_filter.master b/server/conf/sieve_filter.master index bfd75c4d4..13c08dd56 100644 --- a/server/conf/sieve_filter.master +++ b/server/conf/sieve_filter.master @@ -1,4 +1,4 @@ -require ["fileinto", "regex", "vacation", "imap4flags", "envelope", "subaddress"]; +require ["fileinto", "regex", "date", "relational", "vacation", "imap4flags", "envelope", "subaddress", "copy", "reject"]; # Send a copy of email to @@ -9,7 +9,7 @@ redirect ""; # Move spam to spam folder -if header :contains "X-Spam-Flag" "YES" { +if anyof (header :contains "X-Spam-Flag" "YES", header :contains "X-Spam" "Yes", header :contains "subject" "*** SPAM ***", header :contains "subject" "***SPAM***") { fileinto "Junk"; # Stop here so that we do not reply on spams stop; @@ -26,7 +26,7 @@ keep; ################################################################# # Move spam to spam folder -if header :contains "X-Spam-Flag" "YES" { +if anyof (header :contains "X-Spam-Flag" "YES", header :contains "X-Spam" "Yes", header :contains "subject" "*** SPAM ***", header :contains "subject" "***SPAM***") { fileinto "Junk"; # Stop here so that we do not reply on spams stop; diff --git a/server/conf/sieve_filter_1.2.master b/server/conf/sieve_filter_1.2.master index 8a1c80713..524469310 100644 --- a/server/conf/sieve_filter_1.2.master +++ b/server/conf/sieve_filter_1.2.master @@ -1,8 +1,8 @@ -require ["fileinto", "regex", "date", "relational", "vacation", "imap4flags", "envelope", "subaddress"]; +require ["fileinto", "regex", "date", "relational", "vacation", "imap4flags", "envelope", "subaddress", "copy", "reject"]; # Move spam to spam folder -if header :contains "X-Spam-Flag" "YES" { +if anyof (header :contains "X-Spam-Flag" "YES", header :contains "X-Spam" "Yes", header :contains "subject" "*** SPAM ***", header :contains "subject" "***SPAM***") { fileinto "Junk"; # Stop here so that we do not reply on spams stop; @@ -26,7 +26,7 @@ keep; ################################################################# # Move spam to spam folder -if header :contains "X-Spam-Flag" "YES" { +if anyof (header :contains "X-Spam-Flag" "YES", header :contains "X-Spam" "Yes", header :contains "subject" "*** SPAM ***", header :contains "subject" "***SPAM***") { # Stop here so that we do not reply on spams stop; } diff --git a/server/mods-available/mail_module.inc.php b/server/mods-available/mail_module.inc.php index 8460d5d96..ffb72d68f 100644 --- a/server/mods-available/mail_module.inc.php +++ b/server/mods-available/mail_module.inc.php @@ -56,6 +56,12 @@ class mail_module { 'mail_mailinglist_insert', 'mail_mailinglist_update', 'mail_mailinglist_delete', + 'spamfilter_users_insert', + 'spamfilter_users_update', + 'spamfilter_users_delete', + 'spamfilter_wblist_insert', + 'spamfilter_wblist_update', + 'spamfilter_wblist_delete', 'mail_ml_member_insert', 'mail_ml_member_update', 'mail_ml_member_delete'); @@ -107,6 +113,10 @@ class mail_module { $app->modules->registerTableHook('mail_mailinglist', 'mail_module', 'process'); $app->modules->registerTableHook('mail_ml_membership', 'mail_module', 'process'); + $app->modules->registerTableHook('spamfilter_users', 'mail_module', 'process'); + $app->modules->registerTableHook('spamfilter_wblist', 'mail_module', 'process'); + + $app->services->registerService('rspamd', 'mail_module', 'restartRspamd'); } /* @@ -163,9 +173,36 @@ class mail_module { if($action == 'u') $app->plugins->raiseEvent('mail_ml_member_update', $data); if($action == 'd') $app->plugins->raiseEvent('mail_ml_member_delete', $data); break; + case 'spamfilter_users': + if($action == 'i') $app->plugins->raiseEvent('spamfilter_users_insert', $data); + if($action == 'u') $app->plugins->raiseEvent('spamfilter_users_update', $data); + if($action == 'd') $app->plugins->raiseEvent('spamfilter_users_delete', $data); + break; + case 'spamfilter_wblist': + if($action == 'i') $app->plugins->raiseEvent('spamfilter_wblist_insert', $data); + if($action == 'u') $app->plugins->raiseEvent('spamfilter_wblist_update', $data); + if($action == 'd') $app->plugins->raiseEvent('spamfilter_wblist_delete', $data); + break; } // end switch } // end function + function restartRspamd($action = 'reload') { + global $app; + + $app->uses('system'); + + $daemon = 'rspamd'; + + $retval = array('output' => '', 'retval' => 0); + if($action == 'restart') { + exec($app->system->getinitcommand($daemon, 'restart').' 2>&1', $retval['output'], $retval['retval']); + } else { + exec($app->system->getinitcommand($daemon, 'reload').' 2>&1', $retval['output'], $retval['retval']); + } + return $retval; + } + + } // end class ?> diff --git a/server/plugins-available/apps_vhost_plugin.inc.php b/server/plugins-available/apps_vhost_plugin.inc.php index b843e3c8a..32a62174f 100644 --- a/server/plugins-available/apps_vhost_plugin.inc.php +++ b/server/plugins-available/apps_vhost_plugin.inc.php @@ -106,6 +106,16 @@ class apps_vhost_plugin { $vhost_port_listen = '#'; } $tpl->setVar('vhost_port_listen', $vhost_port_listen); + + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + if($mail_config['content_filter'] == 'rspamd'){ + $use_rspamd = true; + exec('/usr/sbin/a2enmod proxy'); + exec('/usr/sbin/a2enmod proxy_http'); + } else { + $use_rspamd = false; + } + $tpl->setVar('use_rspamd', $use_rspamd); $content = $tpl->grab(); @@ -184,6 +194,14 @@ class apps_vhost_plugin { $content = str_replace('{use_tcp}', $use_tcp, $content); $content = str_replace('{use_socket}', $use_socket, $content); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + if($mail_config['content_filter'] == 'rspamd'){ + $use_rspamd = ''; + } else { + $use_rspamd = '#'; + } + $content = str_replace('{use_rspamd}', $use_rspamd, $content); + // Fix socket path on PHP 7 systems if(file_exists('/var/run/php/php7.0-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.0-fpm.sock', $content); if(file_exists('/var/run/php/php7.1-fpm.sock')) $content = str_replace('/var/run/php5-fpm.sock', '/var/run/php/php7.1-fpm.sock', $content); @@ -221,7 +239,3 @@ class apps_vhost_plugin { } // end class - - - -?> diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index 64c557139..ea0c951dc 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -60,15 +60,15 @@ class postfix_server_plugin { Register for the events */ - $app->plugins->registerEvent('server_insert', 'postfix_server_plugin', 'insert'); - $app->plugins->registerEvent('server_update', 'postfix_server_plugin', 'update'); - - + $app->plugins->registerEvent('server_insert', $this->plugin_name, 'insert'); + $app->plugins->registerEvent('server_update', $this->plugin_name, 'update'); + $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); } function insert($event_name, $data) { - global $app, $conf; $this->update($event_name, $data); @@ -116,7 +116,7 @@ class postfix_server_plugin { if($rbl_hosts != ''){ $rbl_hosts = explode(",", $rbl_hosts); } - $options = explode(", ", exec("postconf -h smtpd_recipient_restrictions")); + $options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions")); $new_options = array(); foreach ($options as $key => $value) { if (!preg_match('/reject_rbl_client/', $value)) { @@ -162,7 +162,8 @@ class postfix_server_plugin { } if($app->system->is_installed('dovecot')) { - $temp = exec("postconf -n virtual_transport", $out); + $out = null; + exec("postconf -n virtual_transport", $out); if ($mail_config["mailbox_virtual_uidgid_maps"] == 'y') { // If dovecot switch to lmtp if($out[0] != "virtual_transport = lmtp:unix:private/dovecot-lmtp") { @@ -182,12 +183,139 @@ class postfix_server_plugin { } } - exec("postconf -e 'mailbox_size_limit = ".intval($mail_config['mailbox_size_limit']*1024*1024)."'"); //TODO : no reload? - exec("postconf -e 'message_size_limit = ".intval($mail_config['message_size_limit']*1024*1024)."'"); //TODO : no reload? + if($mail_config['content_filter'] != $old_ini_data['mail']['content_filter']) { + if($mail_config['content_filter'] == 'rspamd'){ + exec("postconf -X 'receive_override_options'"); + exec("postconf -X 'content_filter'"); + + exec("postconf -e 'smtpd_milters = inet:localhost:11332'"); + exec("postconf -e 'milter_protocol = 6'"); + exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'"); + exec("postconf -e 'milter_default_action = accept'"); + + exec("postconf -e 'smtpd_sender_restrictions = check_sender_access mysql:/etc/postfix/mysql-virtual_sender.cf, permit_mynetworks, permit_sasl_authenticated'"); + + $new_options = array(); + $options = preg_split("/,\s*/", exec("postconf -h smtpd_recipient_restrictions")); + foreach ($options as $key => $value) { + if (!preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) { + $new_options[] = $value; + } + } + exec("postconf -e 'smtpd_recipient_restrictions = ".implode(", ", $new_options)."'"); + + if(!is_dir('/etc/rspamd/local.d/')){ + $app->system->mkdirpath('/etc/rspamd/local.d/'); + } + + $this->server_ip($event_name, $data); + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_antivirus.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_antivirus.conf.master /etc/rspamd/local.d/antivirus.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_antivirus.conf.master /etc/rspamd/local.d/antivirus.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_classifier-bayes.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_classifier-bayes.conf.master /etc/rspamd/local.d/classifier-bayes.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_classifier-bayes.conf.master /etc/rspamd/local.d/classifier-bayes.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_greylist.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_greylist.conf.master /etc/rspamd/local.d/greylist.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_greylist.conf.master /etc/rspamd/local.d/greylist.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_metrics.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_metrics.conf.master /etc/rspamd/local.d/metrics.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_metrics.conf.master /etc/rspamd/local.d/metrics.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_metrics_override.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_metrics_override.conf.master /etc/rspamd/override.d/metrics.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_metrics_override.conf.master /etc/rspamd/override.d/metrics.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_mx_check.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_mx_check.conf.master /etc/rspamd/local.d/mx_check.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_mx_check.conf.master /etc/rspamd/local.d/mx_check.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd.local.lua.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua'); + } + + $tpl = new tpl(); + $tpl->newTemplate('rspamd_dkim_signing.conf.master'); + $tpl->setVar('dkim_path', $mail_config['dkim_path']); + $app->system->file_put_contents('/etc/rspamd/local.d/dkim_signing.conf', $tpl->grab()); + + $app->system->add_user_to_group('amavis', '_rspamd'); + + if(strpos($app->system->file_get_contents('/etc/rspamd/rspamd.conf'), '.include "$LOCAL_CONFDIR/local.d/users.conf"') === false){ + $app->uses('file'); + $app->file->af('/etc/rspamd/rspamd.conf', '.include "$LOCAL_CONFDIR/local.d/users.conf"'); + } + + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + if($mail_config['content_filter'] == 'amavisd'){ + exec("postconf -X 'smtpd_milters'"); + exec("postconf -X 'milter_protocol'"); + exec("postconf -X 'milter_mail_macros'"); + exec("postconf -X 'milter_default_action'"); + + exec("postconf -e 'receive_override_options = no_address_mappings'"); + exec("postconf -e 'content_filter = amavis:[127.0.0.1]:10024'"); + + exec("postconf -e 'smtpd_sender_restrictions = check_sender_access mysql:/etc/postfix/mysql-virtual_sender.cf regexp:/etc/postfix/tag_as_originating.re, permit_mynetworks, permit_sasl_authenticated, check_sender_access regexp:/etc/postfix/tag_as_foreign.re'"); + } + } + if($mail_config['content_filter'] == 'rspamd' && ($mail_config['rspamd_password'] != $old_ini_data['mail']['rspamd_password'] || $mail_config['content_filter'] != $old_ini_data['mail']['content_filter'])) { + $tpl = new tpl(); + $tpl->newTemplate('rspamd_worker-controller.inc.master'); + $tpl->setVar('rspamd_password', $mail_config['rspamd_password']); + $app->system->file_put_contents('/etc/rspamd/local.d/worker-controller.inc', $tpl->grab()); + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + exec("postconf -e 'mailbox_size_limit = ".intval($mail_config['mailbox_size_limit']*1024*1024)."'"); //TODO : no reload? + exec("postconf -e 'message_size_limit = ".intval($mail_config['message_size_limit']*1024*1024)."'"); //TODO : no reload? + } -} // end class + function server_ip($event_name, $data) { + global $app, $conf; + + // get the config + $app->uses("getconf,system"); + $app->load('tpl'); -?> + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + $tpl = new tpl(); + $tpl->newTemplate('rspamd_users.conf.master'); + + $whitelist_ips = array(); + $ips = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ?", $conf['server_id']); + if(is_array($ips) && !empty($ips)){ + foreach($ips as $ip){ + $whitelist_ips[] = array('ip' => $ip['ip_address']); + } + } + $tpl->setLoop('whitelist_ips', $whitelist_ips); + $app->system->file_put_contents('/etc/rspamd/local.d/users.conf', $tpl->grab()); + + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + } +} // end class diff --git a/server/plugins-available/rspamd_plugin.inc.php b/server/plugins-available/rspamd_plugin.inc.php new file mode 100644 index 000000000..e3fb16b80 --- /dev/null +++ b/server/plugins-available/rspamd_plugin.inc.php @@ -0,0 +1,210 @@ +plugins->registerEvent('spamfilter_users_insert', $this->plugin_name, 'spamfilter_users_insert'); + $app->plugins->registerEvent('spamfilter_users_update', $this->plugin_name, 'spamfilter_users_update'); + $app->plugins->registerEvent('spamfilter_users_delete', $this->plugin_name, 'spamfilter_users_delete'); + + //* spamfilter_wblist + $app->plugins->registerEvent('spamfilter_wblist_insert', $this->plugin_name, 'spamfilter_wblist_insert'); + $app->plugins->registerEvent('spamfilter_wblist_update', $this->plugin_name, 'spamfilter_wblist_update'); + $app->plugins->registerEvent('spamfilter_wblist_delete', $this->plugin_name, 'spamfilter_wblist_delete'); + } + + function spamfilter_users_insert($event_name, $data) { + global $app, $conf; + + $this->action = 'insert'; + // just run the spamfilter_users_update function + $this->spamfilter_users_update($event_name, $data); + } + + function spamfilter_users_update($event_name, $data) { + global $app, $conf; + + // get the config + $app->uses('getconf,system,functions'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + $policy = $app->db->queryOneRecord("SELECT * FROM spamfilter_policy WHERE id = ?", intval($data['new']['policy_id'])); + + //* Create the config file + $user_file = $this->users_config_dir.'spamfilter_user_'.intval($data['new']['id']).'.conf'; + + if($data['new']['local'] == 'Y' && is_array($policy) && !empty($policy)){ + if(!is_dir($this->users_config_dir)){ + $app->system->mkdirpath($this->users_config_dir); + } + + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('rspamd_users.inc.conf.master'); + $tpl->setVar('record_id', intval($data['new']['id'])); + $tpl->setVar('priority', intval($data['new']['priority'])); + $tpl->setVar('recipient', $app->functions->idn_encode($data['new']['email'])); + + $tpl->setVar('rspamd_greylisting', $policy['rspamd_greylisting']); + $tpl->setVar('rspamd_spam_greylisting_level', floatval($policy['rspamd_spam_greylisting_level'])); + + $tpl->setVar('rspamd_spam_tag_level', floatval($policy['rspamd_spam_tag_level'])); + $tpl->setVar('rspamd_spam_tag_method', $policy['rspamd_spam_tag_method']); + + $tpl->setVar('rspamd_spam_kill_level', floatval($policy['rspamd_spam_kill_level'])); + $tpl->setVar('rspamd_virus_kill_level', floatval($policy['rspamd_spam_kill_level']) + 1000); + + $spam_lover_virus_lover = ''; + if($policy['spam_lover'] == 'Y' && $policy['virus_lover'] == 'Y') $spam_lover_virus_lover = 'spam_lover_AND_virus_lover'; + if($policy['spam_lover'] == 'Y' && $policy['virus_lover'] != 'Y') $spam_lover_virus_lover = 'spam_lover_AND_NOTvirus_lover'; + if($policy['spam_lover'] != 'Y' && $policy['virus_lover'] == 'Y') $spam_lover_virus_lover = 'NOTspam_lover_AND_virus_lover'; + if($policy['spam_lover'] != 'Y' && $policy['virus_lover'] != 'Y') $spam_lover_virus_lover = 'NOTspam_lover_AND_NOTvirus_lover'; + + $tpl->setVar('spam_lover_virus_lover', $spam_lover_virus_lover); + + //$groups_disabled = array(); + //if($policy['virus_lover'] == 'Y') $groups_disabled[] = ''; + + $app->system->file_put_contents($user_file, $tpl->grab()); + } else { + if(is_file($user_file)) unlink($user_file); + } + //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + } + + function spamfilter_users_delete($event_name, $data) { + global $app, $conf; + + // get the config + $app->uses('getconf'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + //* delete the config file + $user_file = $this->users_config_dir.'spamfilter_user_'.intval($data['old']['id']).'.conf'; + if(is_file($user_file)) unlink($user_file); + //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + } + + function spamfilter_wblist_insert($event_name, $data) { + global $app, $conf; + + $this->action = 'insert'; + // just run the spamfilter_wblist_update function + $this->spamfilter_wblist_update($event_name, $data); + } + + function spamfilter_wblist_update($event_name, $data) { + global $app, $conf; + + $app->uses('getconf,system,functions'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + $recipient = $app->db->queryOneRecord("SELECT email FROM spamfilter_users WHERE id = ?", intval($data['new']['rid'])); + //* Create the config file + $wblist_file = $this->users_config_dir.'spamfilter_wblist_'.intval($data['new']['wblist_id']).'.conf'; + + if($data['new']['active'] == 'y' && is_array($recipient) && !empty($recipient)){ + if(!is_dir($this->users_config_dir)){ + $app->system->mkdirpath($this->users_config_dir); + } + + $app->load('tpl'); + + $tpl = new tpl(); + $tpl->newTemplate('rspamd_wblist.inc.conf.master'); + $tpl->setVar('record_id', intval($data['new']['wblist_id'])); + $tpl->setVar('priority', intval($data['new']['priority'])); + $tpl->setVar('from', $app->functions->idn_encode($data['new']['email'])); + $tpl->setVar('recipient', $app->functions->idn_encode($recipient['email'])); + //$tpl->setVar('action', ($data['new']['wb'] == 'W'? 'want_spam = yes;' : 'action = "reject";')); + $tpl->setVar('wblist', $data['new']['wb']); + + $app->system->file_put_contents($wblist_file, $tpl->grab()); + } else { + if(is_file($wblist_file)) unlink($wblist_file); + } + //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + } + + function spamfilter_wblist_delete($event_name, $data) { + global $app, $conf; + + $app->uses('getconf'); + $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); + + if($mail_config['content_filter'] == 'rspamd'){ + //* delete the config file + $wblist_file = $this->users_config_dir.'spamfilter_wblist_'.intval($data['old']['wblist_id']).'.conf'; + if(is_file($wblist_file)) unlink($wblist_file); + //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } + } + +} // end class +?> \ No newline at end of file -- GitLab From 5ac40dc2ac54aa0fe8ed126eefd472dc8e7d2e34 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 14:27:12 +0100 Subject: [PATCH 181/310] - small cleanup --- server/plugins-available/postfix_server_plugin.inc.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index ea0c951dc..2d517bd6b 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -265,8 +265,7 @@ class postfix_server_plugin { } if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); - } - if($mail_config['content_filter'] == 'amavisd'){ + } elseif($mail_config['content_filter'] == 'amavisd'){ exec("postconf -X 'smtpd_milters'"); exec("postconf -X 'milter_protocol'"); exec("postconf -X 'milter_mail_macros'"); -- GitLab From 05161aeb0b5a399a906b8069851478ed98e88f09 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 15:47:28 +0100 Subject: [PATCH 182/310] - syntax error in apache config --- install/tpl/apache_ispconfig.conf.master | 1 + server/conf/apache_ispconfig.conf.master | 1 + 2 files changed, 2 insertions(+) diff --git a/install/tpl/apache_ispconfig.conf.master b/install/tpl/apache_ispconfig.conf.master index 271a9b8ad..e5a38a3ef 100644 --- a/install/tpl/apache_ispconfig.conf.master +++ b/install/tpl/apache_ispconfig.conf.master @@ -16,6 +16,7 @@ SSLStaplingCache shmcb:/var/run/ocsp(128000) LogFormat '%v %h %l %u %t "%r" %>s %S "%{Referer}i" "%{User-Agent}i"' combined_ispconfig LogFormat "%v %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined_ispconfig + CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -p -s access.log -t \"%Y%m%d-access.log\" /var/log/ispconfig/httpd" combined_ispconfig env=!dontlog diff --git a/server/conf/apache_ispconfig.conf.master b/server/conf/apache_ispconfig.conf.master index c5bdb0a2d..1a053fc43 100644 --- a/server/conf/apache_ispconfig.conf.master +++ b/server/conf/apache_ispconfig.conf.master @@ -18,6 +18,7 @@ SSLStaplingCache shmcb:/var/run/ocsp(128000) LogFormat '%v %h %l %u %t "%r" %>s %S "%{Referer}i" "%{User-Agent}i"' combined_ispconfig LogFormat "%v %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined_ispconfig + CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -p -s access.log -t \"%Y%m%d-access.log\" /var/log/ispconfig/httpd" combined_ispconfig env=!dontlog -- GitLab From 35957eb2af84b7b4d04fcc5f61aa0200325a7b35 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 16:20:43 +0100 Subject: [PATCH 183/310] - fixed syntax and logical errors --- server/lib/app.inc.php | 8 +++ server/lib/classes/letsencrypt.inc.php | 8 +-- .../lib/classes/plugin_webserver_base.inc.php | 53 ++++++++++--------- .../plugins-available/apache2_plugin.inc.php | 2 +- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/server/lib/app.inc.php b/server/lib/app.inc.php index 86df2a86f..59bf8b9eb 100644 --- a/server/lib/app.inc.php +++ b/server/lib/app.inc.php @@ -69,6 +69,14 @@ class app { } + public function __get($prop) { + if(property_exists($this, $prop)) return $this->{$prop}; + + $this->uses($prop); + if(property_exists($this, $prop)) return $this->{$prop}; + else return null; + } + function setCaller($caller) { $this->_calling_script = $caller; } diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index 254d5058c..600c79f34 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -44,7 +44,7 @@ class letsencrypt { } public function get_acme_script() { - $acme = excplode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); + $acme = explode("\n", shell_exec('which /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh')); $acme = reset($acme); if(is_executable($acme)) { return $acme; @@ -233,7 +233,10 @@ class letsencrypt { } private function get_ssl_domain($data) { + global $app; + $domain = $data['new']['ssl_domain']; + if(!$domain) $domain = $data['new']['domain']; if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y') { @@ -249,8 +252,6 @@ class letsencrypt { } public function get_website_certificate_paths($data) { - global $app; - $ssl_dir = $data['new']['document_root'].'/ssl'; $domain = $this->get_ssl_domain($data); @@ -472,4 +473,3 @@ class letsencrypt { } } -?> diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 1fb4f7131..8f18db749 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -33,38 +33,44 @@ class plugin_webserver_base { public function registerEvents($server_type = 'apache') { global $app; - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); + if($server_type === 'apache') { + $plugin_name = 'apache2_plugin'; + } else { + $plugin_name = 'nginx_plugin'; + } + + $app->plugins->registerEvent('web_domain_insert', $plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_update', $plugin_name, 'ssl'); + $app->plugins->registerEvent('web_domain_delete', $plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); + $app->plugins->registerEvent('web_domain_insert', $plugin_name, 'insert'); + $app->plugins->registerEvent('web_domain_update', $plugin_name, 'update'); + $app->plugins->registerEvent('web_domain_delete', $plugin_name, 'delete'); - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_insert', $plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_update', $plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_ip_delete', $plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_insert', $plugin_name, 'server_ip'); + $app->plugins->registerEvent('server_update', $plugin_name, 'server_ip'); - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + $app->plugins->registerEvent('client_delete', $plugin_name, 'client_delete'); - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_insert', $plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_update', $plugin_name, 'web_folder_user'); + $app->plugins->registerEvent('web_folder_user_delete', $plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); + $app->plugins->registerEvent('web_folder_update', $plugin_name, 'web_folder_update'); + $app->plugins->registerEvent('web_folder_delete', $plugin_name, 'web_folder_delete'); - $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); + $app->plugins->registerEvent('ftp_user_delete', $plugin_name, 'ftp_user_delete'); - $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); + $app->plugins->registerAction('php_ini_changed', $plugin_name, 'php_ini_changed'); if($server_type === 'apache') { - $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_insert', $plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_update', $plugin_name, 'webdav'); + $app->plugins->registerEvent('webdav_user_delete', $plugin_name, 'webdav'); } } @@ -1354,8 +1360,7 @@ class plugin_webserver_base { $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); } $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - + if($server_type === 'apache') { /* * maybe we have some webdav - user. If so, add them... diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 73f6f9939..2af63d270 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -98,7 +98,7 @@ class apache2_plugin { if($this->action != 'insert') $this->action = 'update'; - $app->plugins_webserver_base->eventUpdate($event_name, $data, 'apache'); + $app->plugin_webserver_base->eventUpdate($event_name, $data, 'apache'); //* Unset action to clean it for next processed vhost. $this->action = ''; -- GitLab From 9f0cb153d58e9923173237063159281d364a8180 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 16:33:11 +0100 Subject: [PATCH 184/310] - fixed missing action setting on merged plugin class --- server/lib/classes/plugin_webserver_base.inc.php | 8 ++++++-- server/plugins-available/apache2_plugin.inc.php | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 8f18db749..bbe9f6718 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -30,6 +30,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class plugin_webserver_base { + private $action = ''; + public function registerEvents($server_type = 'apache') { global $app; @@ -522,10 +524,12 @@ class plugin_webserver_base { $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); } } - - public function eventUpdate($event_name, $data, $server_type = 'apache') { + + public function eventUpdate($event_name, $data, $action, $server_type = 'apache') { global $app, $conf; + $this->action = $action; + if($server_type === 'nginx') { //* Check if the apache plugin is enabled if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 2af63d270..ccb7a81e0 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -98,7 +98,7 @@ class apache2_plugin { if($this->action != 'insert') $this->action = 'update'; - $app->plugin_webserver_base->eventUpdate($event_name, $data, 'apache'); + $app->plugin_webserver_base->eventUpdate($event_name, $data, $this->action, 'apache'); //* Unset action to clean it for next processed vhost. $this->action = ''; -- GitLab From e570d9c2e3b80c22eceb72afd4baa557b93e9017 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 16:36:21 +0100 Subject: [PATCH 185/310] - added missing chattr removal on delete --- server/lib/classes/plugin_webserver_base.inc.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index bbe9f6718..e52c16e91 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -1619,7 +1619,7 @@ class plugin_webserver_base { $this->action = ''; } - public function eventDelete($event_name, $data, $server_type = 'apache') { + public function eventDelete($event_name, $data, $server_type = 'apache') { global $app, $conf; // load the server configuration options @@ -1628,7 +1628,10 @@ class plugin_webserver_base { $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + if($data['old']['type'] == 'vhost') { + $app->system->web_folder_protection($data['old']['document_root'], false); + } elseif($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { + $parent_domain_id = intval($data['old']['parent_domain_id']); $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); $app->system->web_folder_protection($tmp['document_root'], false); -- GitLab From c13ab0efa76fdcd21e4f8f22aa5a0441a664c8d5 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 19:27:30 +0100 Subject: [PATCH 186/310] - fixed missing return value for web folder --- server/lib/classes/plugin_webserver_base.inc.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index e52c16e91..0aa6066a7 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -2999,5 +2999,7 @@ class plugin_webserver_base { unset($tmp); } } + + return $folder; } } -- GitLab From 0d99f51698ea0a964565d11cb3e33234c857bf4f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 20:06:13 +0100 Subject: [PATCH 187/310] - fixed LE command not being called --- server/lib/classes/letsencrypt.inc.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index 600c79f34..a353b8206 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -63,6 +63,10 @@ class letsencrypt { $cmd .= (string) " -d " . $domain; } + if($cmd == '') { + return false; + } + $cmd = $letsencrypt . " --issue $cmd -w /usr/local/ispconfig/interface/acme && " . $letsencrypt . " --install-cert " . $cmd . " --key-file " . escapeshellarg($key_file) . " --fullchain-file " . escapeshellarg($bundle_file) . " --cert-file " . escapeshellarg($cert_file) . " --reloadcmd " . escapeshellarg($this->get_reload_command()); return $cmd; @@ -121,6 +125,10 @@ class letsencrypt { $cmd .= (string) " --domains " . $domain; } + if($cmd == '') { + return false; + } + $matches = array(); $ret = null; $val = 0; @@ -375,7 +383,7 @@ class letsencrypt { } $success = false; - if(!empty($cli_domain_arg)) { + if(!$letsencrypt_cmd) { if(!isset($server_config['migration_mode']) || $server_config['migration_mode'] != 'y') { $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); $app->log("Let's Encrypt SSL Cert domains: $cli_domain_arg", LOGLEVEL_DEBUG); -- GitLab From 8dfe49021669c76126574a8bc9dccd0001db419d Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 20:25:43 +0100 Subject: [PATCH 188/310] - fix php fpm pool config --- server/lib/classes/letsencrypt.inc.php | 2 +- server/lib/classes/plugin_webserver_base.inc.php | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index a353b8206..ee7abcdd2 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -383,7 +383,7 @@ class letsencrypt { } $success = false; - if(!$letsencrypt_cmd) { + if($letsencrypt_cmd) { if(!isset($server_config['migration_mode']) || $server_config['migration_mode'] != 'y') { $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); $app->log("Let's Encrypt SSL Cert domains: $cli_domain_arg", LOGLEVEL_DEBUG); diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 0aa6066a7..f409e0b47 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -2328,10 +2328,20 @@ class plugin_webserver_base { $tpl->setVar('apache_version', $app->system->getapacheversion()); $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); } + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $fpm_socket = $socket_dir.$pool_name.'.sock'; $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - $fpm_socket = $socket_dir.$pool_name.'.sock'; $tpl->setVar('fpm_socket', $fpm_socket); $tpl->setVar('fpm_listen_mode', '0660'); -- GitLab From 73e6c724d26d4dfe528e39190431a73515049ead Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 20:33:37 +0100 Subject: [PATCH 189/310] - fixed vhost file gets written too early --- .../lib/classes/plugin_webserver_base.inc.php | 117 +++++++++--------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index f409e0b47..2d162e959 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -1352,6 +1352,64 @@ class plugin_webserver_base { $config_prefix = 'nginx_'; } + /** + * PHP-FPM + */ + // Support for multiple PHP versions + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); + + $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type); + if($server_type === 'nginx') { + $fpm_data = array( + 'use_tcp' => $use_tcp, + 'use_socket' => $use_socket, + 'socket_dir' => $socket_dir, + 'fpm_socket' => $fpm_socket, + 'fpm_port' => $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1 + ); + $app->plugin_webserver_nginx->processCustomDirectives($tpl, $data, $vhost_data, $fpm_data); + } $vhost_file = escapeshellcmd($web_config[$config_prefix.'vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); //* Make a backup copy of vhost file @@ -1461,65 +1519,6 @@ class plugin_webserver_base { $app->plugin_webserver_base->awstats_update($data, $web_config); } - /** - * PHP-FPM - */ - // Support for multiple PHP versions - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir, $server_type); - if($server_type === 'nginx') { - $fpm_data = array( - 'use_tcp' => $use_tcp, - 'use_socket' => $use_socket, - 'socket_dir' => $socket_dir, - 'fpm_socket' => $fpm_socket, - 'fpm_port' => $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1 - ); - $app->plugin_webserver_nginx->processCustomDirectives($tpl, $data, $vhost_data, $fpm_data); - } - if($web_config['check_apache_config'] == 'y') { //* Test if server starts with the new configuration file $online_status_before_restart = $this->_checkTcp('localhost', 80); -- GitLab From 4a95363a94cf259d0c82e4c77a278cb8d998a9fc Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 20:40:11 +0100 Subject: [PATCH 190/310] - allow return code 2 on acme (non-changed domain) --- server/lib/classes/letsencrypt.inc.php | 4 +++- server/lib/classes/system.inc.php | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index ee7abcdd2..9983354c7 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -376,8 +376,10 @@ class letsencrypt { unset($aliasdomains); $letsencrypt_cmd = ''; + $allow_return_codes = null; if($use_acme) { $letsencrypt_cmd = $this->get_acme_command($temp_domains, $key_file, $bundle_file, $crt_file); + $allow_return_codes = array(2); } else { $letsencrypt_cmd = $this->get_certbot_command($temp_domains); } @@ -388,7 +390,7 @@ class letsencrypt { $app->log("Create Let's Encrypt SSL Cert for: $domain", LOGLEVEL_DEBUG); $app->log("Let's Encrypt SSL Cert domains: $cli_domain_arg", LOGLEVEL_DEBUG); - $success = $app->system->_exec($letsencrypt_cmd); + $success = $app->system->_exec($letsencrypt_cmd, $allow_return_codes); } else { $app->log("Migration mode active, skipping Let's Encrypt SSL Cert creation for: $domain", LOGLEVEL_DEBUG); $success = true; diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index 5cd9d3f76..adcc39f84 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -1672,14 +1672,24 @@ class system{ } - function _exec($command) { + function _exec($command, $return_codes_ok = null) { global $app; + + if(!is_null($return_codes_ok) && !is_array($return_codes_ok)) { + $return_codes_ok = array($return_codes_ok); + } + $out = array(); $ret = 0; $app->log('exec: '.$command, LOGLEVEL_DEBUG); exec($command, $out, $ret); - if($ret != 0) return false; - else return true; + if($ret == 0) { + return true; + } elseif(is_array($return_codes_ok) && !empty($return_codes_ok) && in_array($ret, $return_codes_ok)) { + return true; + } else { + return false; + } } //* Check if a application is installed -- GitLab From 5af7908da6acaea2c57e1da24eb4a1d4302bc433 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 21:41:20 +0100 Subject: [PATCH 191/310] - fixed apache vhost and ssl settings - changed some rspamd config to new syntax --- server/conf/rspamd_antivirus.conf.master | 2 +- server/conf/rspamd_metrics.conf.master | 17 -- .../conf/rspamd_metrics_override.conf.master | 159 ------------------ server/conf/rspamd_override_rbl.conf.master | 53 ++++++ server/conf/rspamd_override_surbl.conf.master | 108 ++++++++++++ .../conf/rspamd_symbols_antivirus.conf.master | 15 ++ server/lib/classes/letsencrypt.inc.php | 2 +- .../classes/plugin_webserver_apache.inc.php | 8 +- .../lib/classes/plugin_webserver_base.inc.php | 7 +- .../postfix_server_plugin.inc.php | 18 +- 10 files changed, 195 insertions(+), 194 deletions(-) delete mode 100644 server/conf/rspamd_metrics.conf.master delete mode 100644 server/conf/rspamd_metrics_override.conf.master create mode 100644 server/conf/rspamd_override_rbl.conf.master create mode 100644 server/conf/rspamd_override_surbl.conf.master create mode 100644 server/conf/rspamd_symbols_antivirus.conf.master diff --git a/server/conf/rspamd_antivirus.conf.master b/server/conf/rspamd_antivirus.conf.master index 71427d762..f88d81ac7 100644 --- a/server/conf/rspamd_antivirus.conf.master +++ b/server/conf/rspamd_antivirus.conf.master @@ -2,7 +2,7 @@ clamav { # If set force this action if any virus is found (default unset: no action is forced) #action = "reject"; # if `true` only messages with non-image attachments will be checked (default true) - attachments_only = true; + scan_mime_parts = true; # If `max_size` is set, messages > n bytes in size are not scanned #max_size = 20000000; # symbol to add (add it to metric if you want non-zero weight) diff --git a/server/conf/rspamd_metrics.conf.master b/server/conf/rspamd_metrics.conf.master deleted file mode 100644 index f59eff0f0..000000000 --- a/server/conf/rspamd_metrics.conf.master +++ /dev/null @@ -1,17 +0,0 @@ -subject = "***SPAM*** %s"; - -symbol { - weight = 50; - name = "CLAM_VIRUS"; - description = "Clamav has found a virus."; -} -symbol { - weight = 50; - name = "JUST_EICAR"; - description = "Clamav has found a virus."; -} -symbol { - weight = 0.0; - name = "R_DUMMY"; - description = "Dummy symbol"; -} \ No newline at end of file diff --git a/server/conf/rspamd_metrics_override.conf.master b/server/conf/rspamd_metrics_override.conf.master deleted file mode 100644 index 8e3df15ed..000000000 --- a/server/conf/rspamd_metrics_override.conf.master +++ /dev/null @@ -1,159 +0,0 @@ -# RBL -symbol "RBL_SENDERSCORE" { - weight = 4.0; - description = "From address is listed in senderscore.com BL"; -} -symbol "RBL_SPAMHAUS_SBL" { - weight = 2.0; - description = "From address is listed in zen sbl"; -} -symbol "RBL_SPAMHAUS_CSS" { - weight = 2.0; - description = "From address is listed in zen css"; -} -symbol "RBL_SPAMHAUS_XBL" { - weight = 4.0; - description = "From address is listed in zen xbl"; -} -symbol "RBL_SPAMHAUS_XBL_ANY" { - weight = 4.0; - description = "From or receive address is listed in zen xbl (any list)"; -} -symbol "RBL_SPAMHAUS_PBL" { - weight = 2.0; - description = "From address is listed in zen pbl (ISP list)"; -} -symbol "RBL_SPAMHAUS_DROP" { - weight = 7.0; - description = "From address is listed in zen drop bl"; -} -symbol "RECEIVED_SPAMHAUS_XBL" { - weight = 3.0; - description = "Received address is listed in zen xbl"; - one_shot = true; -} -symbol "RBL_MAILSPIKE_WORST" { - weight = 2.0; - description = "From address is listed in RBL - worst possible reputation"; -} -symbol "RBL_MAILSPIKE_VERYBAD" { - weight = 1.5; - description = "From address is listed in RBL - very bad reputation"; -} -symbol "RBL_MAILSPIKE_BAD" { - weight = 1.0; - description = "From address is listed in RBL - bad reputation"; -} -symbol "RBL_SEM" { - weight = 1.0; - description = "Address is listed in Spameatingmonkey RBL"; -} -# /RBL -# SURBL -symbol "PH_SURBL_MULTI" { - weight = 5.5; - description = "SURBL: Phishing sites"; -} -symbol "MW_SURBL_MULTI" { - weight = 5.5; - description = "SURBL: Malware sites"; -} -symbol "ABUSE_SURBL" { - weight = 5.5; - description = "SURBL: ABUSE"; -} -symbol "CRACKED_SURBL" { - weight = 4.0; - description = "SURBL: cracked site"; -} -symbol "RAMBLER_URIBL" { - weight = 4.5; - description = "Rambler uribl"; - one_shot = true; -} -symbol "RAMBLER_EMAILBL" { - weight = 9.5; - description = "Rambler emailbl"; - one_shot = true; -} -symbol "MSBL_EBL" { - weight = 7.5; - description = "MSBL emailbl"; - one_shot = true; -} -symbol "SEM_URIBL" { - weight = 3.5; - description = "Spameatingmonkey uribl"; -} -symbol "SEM_URIBL_FRESH15" { - weight = 3.0; - description = "Spameatingmonkey uribl. Domains registered in the last 15 days (.AERO,.BIZ,.COM,.INFO,.NAME,.NET,.PRO,.SK,.TEL,.US)"; -} -symbol "DBL" { - weight = 0.0; - description = "DBL unknown result"; -} -symbol "DBL_SPAM" { - weight = 6.5; - description = "DBL uribl spam"; -} -symbol "DBL_PHISH" { - weight = 6.5; - description = "DBL uribl phishing"; -} -symbol "DBL_MALWARE" { - weight = 6.5; - description = "DBL uribl malware"; -} -symbol "DBL_BOTNET" { - weight = 5.5; - description = "DBL uribl botnet C&C domain"; -} -symbol "DBL_ABUSE" { - weight = 6.5; - description = "DBL uribl abused legit spam"; -} -symbol "DBL_ABUSE_REDIR" { - weight = 1.5; - description = "DBL uribl abused spammed redirector domain"; -} -symbol "DBL_ABUSE_PHISH" { - weight = 7.5; - description = "DBL uribl abused legit phish"; -} -symbol "DBL_ABUSE_MALWARE" { - weight = 7.5; - description = "DBL uribl abused legit malware"; -} -symbol "DBL_ABUSE_BOTNET" { - weight = 5.5; - description = "DBL uribl abused legit botnet C&C"; -} -symbol "URIBL_BLACK" { - weight = 7.5; - description = "uribl.com black url"; -} -symbol "URIBL_RED" { - weight = 3.5; - description = "uribl.com red url"; -} -symbol "URIBL_GREY" { - weight = 1.5; - description = "uribl.com grey url"; - one_shot = true; -} -symbol "URIBL_SBL" { - weight = 6.5; - description = "Spamhaus SBL URIBL"; -} -symbol "URIBL_SBL_CSS" { - weight = 6.5; - description = "Spamhaus SBL CSS URIBL"; -} -symbol "RBL_SARBL_BAD" { - weight = 2.5; - description = "A domain listed in the mail is blacklisted in SARBL"; -} -# /SURBL -actions { -} \ No newline at end of file diff --git a/server/conf/rspamd_override_rbl.conf.master b/server/conf/rspamd_override_rbl.conf.master new file mode 100644 index 000000000..310e72283 --- /dev/null +++ b/server/conf/rspamd_override_rbl.conf.master @@ -0,0 +1,53 @@ +# RBL +symbols = { + "RBL_SENDERSCORE" { + weight = 4.0; + description = "From address is listed in senderscore.com BL"; + } + "RBL_SPAMHAUS_SBL" { + weight = 2.0; + description = "From address is listed in zen sbl"; + } + "RBL_SPAMHAUS_CSS" { + weight = 2.0; + description = "From address is listed in zen css"; + } + "RBL_SPAMHAUS_XBL" { + weight = 4.0; + description = "From address is listed in zen xbl"; + } + "RBL_SPAMHAUS_XBL_ANY" { + weight = 4.0; + description = "From or receive address is listed in zen xbl (any list)"; + } + "RBL_SPAMHAUS_PBL" { + weight = 2.0; + description = "From address is listed in zen pbl (ISP list)"; + } + "RBL_SPAMHAUS_DROP" { + weight = 7.0; + description = "From address is listed in zen drop bl"; + } + "RECEIVED_SPAMHAUS_XBL" { + weight = 3.0; + description = "Received address is listed in zen xbl"; + one_shot = true; + } + "RBL_MAILSPIKE_WORST" { + weight = 2.0; + description = "From address is listed in RBL - worst possible reputation"; + } + "RBL_MAILSPIKE_VERYBAD" { + weight = 1.5; + description = "From address is listed in RBL - very bad reputation"; + } + "RBL_MAILSPIKE_BAD" { + weight = 1.0; + description = "From address is listed in RBL - bad reputation"; + } + "RBL_SEM" { + weight = 1.0; + description = "Address is listed in Spameatingmonkey RBL"; + } + # /RBL +} diff --git a/server/conf/rspamd_override_surbl.conf.master b/server/conf/rspamd_override_surbl.conf.master new file mode 100644 index 000000000..30676a46f --- /dev/null +++ b/server/conf/rspamd_override_surbl.conf.master @@ -0,0 +1,108 @@ +symbols = { + # SURBL + "PH_SURBL_MULTI" { + weight = 5.5; + description = "SURBL: Phishing sites"; + } + "MW_SURBL_MULTI" { + weight = 5.5; + description = "SURBL: Malware sites"; + } + "ABUSE_SURBL" { + weight = 5.5; + description = "SURBL: ABUSE"; + } + "CRACKED_SURBL" { + weight = 4.0; + description = "SURBL: cracked site"; + } + "RAMBLER_URIBL" { + weight = 4.5; + description = "Rambler uribl"; + one_shot = true; + } + "RAMBLER_EMAILBL" { + weight = 9.5; + description = "Rambler emailbl"; + one_shot = true; + } + "MSBL_EBL" { + weight = 7.5; + description = "MSBL emailbl"; + one_shot = true; + } + "SEM_URIBL" { + weight = 3.5; + description = "Spameatingmonkey uribl"; + } + "SEM_URIBL_FRESH15" { + weight = 3.0; + description = "Spameatingmonkey uribl. Domains registered in the last 15 days (.AERO,.BIZ,.COM,.INFO,.NAME,.NET,.PRO,.SK,.TEL,.US)"; + } + "DBL" { + weight = 0.0; + description = "DBL unknown result"; + } + "DBL_SPAM" { + weight = 6.5; + description = "DBL uribl spam"; + } + "DBL_PHISH" { + weight = 6.5; + description = "DBL uribl phishing"; + } + "DBL_MALWARE" { + weight = 6.5; + description = "DBL uribl malware"; + } + "DBL_BOTNET" { + weight = 5.5; + description = "DBL uribl botnet C&C domain"; + } + "DBL_ABUSE" { + weight = 6.5; + description = "DBL uribl abused legit spam"; + } + "DBL_ABUSE_REDIR" { + weight = 1.5; + description = "DBL uribl abused spammed redirector domain"; + } + "DBL_ABUSE_PHISH" { + weight = 7.5; + description = "DBL uribl abused legit phish"; + } + "DBL_ABUSE_MALWARE" { + weight = 7.5; + description = "DBL uribl abused legit malware"; + } + "DBL_ABUSE_BOTNET" { + weight = 5.5; + description = "DBL uribl abused legit botnet C&C"; + } + "URIBL_BLACK" { + weight = 7.5; + description = "uribl.com black url"; + } + "URIBL_RED" { + weight = 3.5; + description = "uribl.com red url"; + } + "URIBL_GREY" { + weight = 1.5; + description = "uribl.com grey url"; + one_shot = true; + } + "URIBL_SBL" { + weight = 6.5; + description = "Spamhaus SBL URIBL"; + } + "URIBL_SBL_CSS" { + weight = 6.5; + description = "Spamhaus SBL CSS URIBL"; + } + "RBL_SARBL_BAD" { + weight = 2.5; + description = "A domain listed in the mail is blacklisted in SARBL"; + } + # /SURBL +} diff --git a/server/conf/rspamd_symbols_antivirus.conf.master b/server/conf/rspamd_symbols_antivirus.conf.master new file mode 100644 index 000000000..8c2d93d89 --- /dev/null +++ b/server/conf/rspamd_symbols_antivirus.conf.master @@ -0,0 +1,15 @@ +subject = "***SPAM*** %s"; +symbols = { + "CLAM_VIRUS" { + weight = 50; + description = "Clamav has found a virus."; + } + "JUST_EICAR" { + weight = 50; + description = "Clamav has found a virus."; + } + "R_DUMMY" { + weight = 0.0; + description = "Dummy symbol"; + } +} \ No newline at end of file diff --git a/server/lib/classes/letsencrypt.inc.php b/server/lib/classes/letsencrypt.inc.php index 9983354c7..e38d4df64 100644 --- a/server/lib/classes/letsencrypt.inc.php +++ b/server/lib/classes/letsencrypt.inc.php @@ -67,7 +67,7 @@ class letsencrypt { return false; } - $cmd = $letsencrypt . " --issue $cmd -w /usr/local/ispconfig/interface/acme && " . $letsencrypt . " --install-cert " . $cmd . " --key-file " . escapeshellarg($key_file) . " --fullchain-file " . escapeshellarg($bundle_file) . " --cert-file " . escapeshellarg($cert_file) . " --reloadcmd " . escapeshellarg($this->get_reload_command()); + $cmd = 'R=0 ; C=0 ; ' . $letsencrypt . ' --issue ' . $cmd . ' -w /usr/local/ispconfig/interface/acme ; R=$? ; if [[ $R -eq 0 || $R -eq 2 ]] ; then ' . $letsencrypt . ' --install-cert ' . $cmd . ' --key-file ' . escapeshellarg($key_file) . ' --fullchain-file ' . escapeshellarg($bundle_file) . ' --cert-file ' . escapeshellarg($cert_file) . ' --reloadcmd ' . escapeshellarg($this->get_reload_command()) . '; C=$? ; fi ; if [[ $C -eq 0 ]] ; then exit $R ; else exit $C ; fi'; return $cmd; } diff --git a/server/lib/classes/plugin_webserver_apache.inc.php b/server/lib/classes/plugin_webserver_apache.inc.php index bed651b68..027a8f18a 100644 --- a/server/lib/classes/plugin_webserver_apache.inc.php +++ b/server/lib/classes/plugin_webserver_apache.inc.php @@ -394,7 +394,7 @@ class plugin_webserver_apache { * @param array $data * @param array $vhost_data */ - public function processVhosts(&$tpl, &$data, &$vhost_data, $ssl_data) { + public function processVhosts(&$tpl, &$data, &$vhost_data) { global $app, $conf; $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); @@ -419,7 +419,7 @@ class plugin_webserver_apache { unset($tmp_vhost_arr); //* Add vhost for ipv4 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($vhost_data['ssl_crt_file']) && @is_file($vhost_data['ssl_key_file']) && (@filesize($vhost_data['ssl_crt_file'])>0) && (@filesize($vhost_data['ssl_key_file'])>0)) { $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); $ipv4_ssl_alias_seo_redirects = $this->alias_seo_redirects; @@ -456,7 +456,7 @@ class plugin_webserver_apache { unset($tmp_vhost_arr); //* Add vhost for ipv6 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($ssl_data['crt_file']) && @is_file($ssl_data['key_file']) && (@filesize($ssl_data['crt_file'])>0) && (@filesize($ssl_data['key_file'])>0)) { + if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($vhost_data['ssl_crt_file']) && @is_file($vhost_data['ssl_key_file']) && (@filesize($vhost_data['ssl_crt_file'])>0) && (@filesize($vhost_data['ssl_key_file'])>0)) { $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); if(count($this->rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $this->rewrite_rules); $ipv6_ssl_alias_seo_redirects = $this->alias_seo_redirects; @@ -470,7 +470,7 @@ class plugin_webserver_apache { unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); } } - + //* Set the vhost loop $tpl->setLoop('vhosts', $vhosts); return; diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index 2d162e959..ea9ab8aa5 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -1337,16 +1337,11 @@ class plugin_webserver_base { $config_prefix = ''; if($server_type === 'apache') { - $ssl_data = array( - 'crt_file' => $crt_file, - 'key_file' => $key_file, - ); - $tpl->setVar('apache_version', $app->system->getapacheversion()); $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); $app->plugin_webserver_apache->processRewriteRules($tpl, $data, $vhost_data); $app->plugin_webserver_apache->processPhpStarters($tpl, $data, $vhost_data); - $app->plugin_webserver_apache->processVhosts($tpl, $data, $vhost_data, $ssl_data); + $app->plugin_webserver_apache->processVhosts($tpl, $data, $vhost_data); } elseif($server_type === 'nginx') { $app->plugin_webserver_nginx->processStatsAuth($tpl, $data, $vhost_data); $config_prefix = 'nginx_'; diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index 2d517bd6b..772ce7113 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -228,16 +228,22 @@ class postfix_server_plugin { exec('cp '.$conf['rootpath'].'/conf/rspamd_greylist.conf.master /etc/rspamd/local.d/greylist.conf'); } - if(file_exists($conf['rootpath'].'/conf-custom/rspamd_metrics.conf.master')) { - exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_metrics.conf.master /etc/rspamd/local.d/metrics.conf'); + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_symbols_antivirus.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_symbols_antivirus.conf.master /etc/rspamd/local.d/antivirus_group.conf'); } else { - exec('cp '.$conf['rootpath'].'/conf/rspamd_metrics.conf.master /etc/rspamd/local.d/metrics.conf'); + exec('cp '.$conf['rootpath'].'/conf/rspamd_symbols_antivirus.conf.master /etc/rspamd/local.d/antivirus_group.conf'); } - if(file_exists($conf['rootpath'].'/conf-custom/rspamd_metrics_override.conf.master')) { - exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_metrics_override.conf.master /etc/rspamd/override.d/metrics.conf'); + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_override_rbl.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_rbl.conf.master /etc/rspamd/override.d/group_rbl.conf'); } else { - exec('cp '.$conf['rootpath'].'/conf/rspamd_metrics_override.conf.master /etc/rspamd/override.d/metrics.conf'); + exec('cp '.$conf['rootpath'].'/conf/rspamd_override_rbl.conf.master /etc/rspamd/override.d/group_rbl.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_override_surbl.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_surbl.conf.master /etc/rspamd/override.d/group_surbl.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_override_surbl.conf.master /etc/rspamd/override.d/group_surbl.conf'); } if(file_exists($conf['rootpath'].'/conf-custom/rspamd_mx_check.conf.master')) { -- GitLab From a14360ea5b57a96596878f744db8cb4b6adb8996 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 22:02:04 +0100 Subject: [PATCH 192/310] - rspamd config fixes --- server/conf/rspamd_groups.conf.master | 4 +++ .../postfix_server_plugin.inc.php | 26 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 server/conf/rspamd_groups.conf.master diff --git a/server/conf/rspamd_groups.conf.master b/server/conf/rspamd_groups.conf.master new file mode 100644 index 000000000..62a986533 --- /dev/null +++ b/server/conf/rspamd_groups.conf.master @@ -0,0 +1,4 @@ +group "antivirus" { + .include(try=true; priority=1; duplicate=merge) "$LOCAL_CONFDIR/local.d/antivirus_group.conf" + .include(try=true; priority=10) "$LOCAL_CONFDIR/override.d/antivirus_group.conf" +} diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index 772ce7113..a9ca7e4e1 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -208,8 +208,18 @@ class postfix_server_plugin { $app->system->mkdirpath('/etc/rspamd/local.d/'); } + if(!is_dir('/etc/rspamd/override.d/')){ + $app->system->mkdirpath('/etc/rspamd/override.d/'); + } + $this->server_ip($event_name, $data); + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_groups.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_groups.conf.master /etc/rspamd/local.d/groups.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_groups.conf.master /etc/rspamd/local.d/groups.conf'); + } + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_antivirus.conf.master')) { exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_antivirus.conf.master /etc/rspamd/local.d/antivirus.conf'); } else { @@ -235,15 +245,15 @@ class postfix_server_plugin { } if(file_exists($conf['rootpath'].'/conf-custom/rspamd_override_rbl.conf.master')) { - exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_rbl.conf.master /etc/rspamd/override.d/group_rbl.conf'); + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_rbl.conf.master /etc/rspamd/override.d/rbl_group.conf'); } else { - exec('cp '.$conf['rootpath'].'/conf/rspamd_override_rbl.conf.master /etc/rspamd/override.d/group_rbl.conf'); + exec('cp '.$conf['rootpath'].'/conf/rspamd_override_rbl.conf.master /etc/rspamd/override.d/rbl_group.conf'); } if(file_exists($conf['rootpath'].'/conf-custom/rspamd_override_surbl.conf.master')) { - exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_surbl.conf.master /etc/rspamd/override.d/group_surbl.conf'); + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_override_surbl.conf.master /etc/rspamd/override.d/surbl_group.conf'); } else { - exec('cp '.$conf['rootpath'].'/conf/rspamd_override_surbl.conf.master /etc/rspamd/override.d/group_surbl.conf'); + exec('cp '.$conf['rootpath'].'/conf/rspamd_override_surbl.conf.master /etc/rspamd/override.d/surbl_group.conf'); } if(file_exists($conf['rootpath'].'/conf-custom/rspamd_mx_check.conf.master')) { @@ -252,11 +262,13 @@ class postfix_server_plugin { exec('cp '.$conf['rootpath'].'/conf/rspamd_mx_check.conf.master /etc/rspamd/local.d/mx_check.conf'); } - if(file_exists($conf['rootpath'].'/conf-custom/rspamd.local.lua.master')) { + /*if(file_exists($conf['rootpath'].'/conf-custom/rspamd.local.lua.master')) { exec('cp '.$conf['rootpath'].'/conf-custom/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua'); } else { exec('cp '.$conf['rootpath'].'/conf/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua'); - } + }*/ + + exec('chmod a+r /etc/rspamd/local.d/* /etc/rspamd/override.d/*'); $tpl = new tpl(); $tpl->newTemplate('rspamd_dkim_signing.conf.master'); @@ -289,7 +301,7 @@ class postfix_server_plugin { $tpl->newTemplate('rspamd_worker-controller.inc.master'); $tpl->setVar('rspamd_password', $mail_config['rspamd_password']); $app->system->file_put_contents('/etc/rspamd/local.d/worker-controller.inc', $tpl->grab()); - if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + $app->services->restartServiceDelayed('rspamd', 'reload'); } exec("postconf -e 'mailbox_size_limit = ".intval($mail_config['mailbox_size_limit']*1024*1024)."'"); //TODO : no reload? -- GitLab From 6fab3f150e3d7d94d3d159d42a7954e684bc6fb9 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Tue, 13 Nov 2018 23:25:42 +0100 Subject: [PATCH 193/310] - improved rspamd config --- server/conf/rspamd_milter_headers.conf.master | 2 ++ server/conf/rspamd_options.inc.master | 5 ++++ server/conf/rspamd_redis.conf.master | 1 + server/conf/rspamd_users.conf.master | 12 ++++----- .../postfix_server_plugin.inc.php | 25 ++++++++++++++++--- 5 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 server/conf/rspamd_milter_headers.conf.master create mode 100644 server/conf/rspamd_options.inc.master create mode 100644 server/conf/rspamd_redis.conf.master diff --git a/server/conf/rspamd_milter_headers.conf.master b/server/conf/rspamd_milter_headers.conf.master new file mode 100644 index 000000000..d399bbf4e --- /dev/null +++ b/server/conf/rspamd_milter_headers.conf.master @@ -0,0 +1,2 @@ +use = ["x-spamd-bar", "x-spam-level", "authentication-results"]; +authenticated_headers = ["authentication-results"]; \ No newline at end of file diff --git a/server/conf/rspamd_options.inc.master b/server/conf/rspamd_options.inc.master new file mode 100644 index 000000000..69e40365b --- /dev/null +++ b/server/conf/rspamd_options.inc.master @@ -0,0 +1,5 @@ +local_addrs = "127.0.0.0/8, ::1"; + +dns { + nameserver = ["127.0.0.1:53:10"]; +} diff --git a/server/conf/rspamd_redis.conf.master b/server/conf/rspamd_redis.conf.master new file mode 100644 index 000000000..b908af9f5 --- /dev/null +++ b/server/conf/rspamd_redis.conf.master @@ -0,0 +1 @@ +servers = "127.0.0.1"; \ No newline at end of file diff --git a/server/conf/rspamd_users.conf.master b/server/conf/rspamd_users.conf.master index 975300bf9..bf7ad2830 100644 --- a/server/conf/rspamd_users.conf.master +++ b/server/conf/rspamd_users.conf.master @@ -25,12 +25,12 @@ settings { want_spam = yes; } - whitelist-timmehosting { - priority = 20; - from = "@timmehosting.de"; - from = "@timmehosting.com"; - want_spam = yes; - } +# whitelist-timmehosting { +# priority = 20; +# from = "@xxx"; +# from = "@xxx"; +# want_spam = yes; +# } whitelist-ca { priority = 20; from = "@comodo.com"; diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index a9ca7e4e1..bcb7d1592 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -189,6 +189,7 @@ class postfix_server_plugin { exec("postconf -X 'content_filter'"); exec("postconf -e 'smtpd_milters = inet:localhost:11332'"); + exec("postconf -e 'non_smtpd_milters = inet:localhost:11332'"); exec("postconf -e 'milter_protocol = 6'"); exec("postconf -e 'milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}'"); exec("postconf -e 'milter_default_action = accept'"); @@ -262,6 +263,24 @@ class postfix_server_plugin { exec('cp '.$conf['rootpath'].'/conf/rspamd_mx_check.conf.master /etc/rspamd/local.d/mx_check.conf'); } + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_redis.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_redis.conf.master /etc/rspamd/local.d/redis.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_redis.conf.master /etc/rspamd/local.d/redis.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_milter_headers.conf.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_milter_headers.conf.master /etc/rspamd/local.d/milter_headers.conf'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_milter_headers.conf.master /etc/rspamd/local.d/milter_headers.conf'); + } + + if(file_exists($conf['rootpath'].'/conf-custom/rspamd_options.inc.master')) { + exec('cp '.$conf['rootpath'].'/conf-custom/rspamd_options.inc.master /etc/rspamd/local.d/options.inc'); + } else { + exec('cp '.$conf['rootpath'].'/conf/rspamd_options.inc.master /etc/rspamd/local.d/options.inc'); + } + /*if(file_exists($conf['rootpath'].'/conf-custom/rspamd.local.lua.master')) { exec('cp '.$conf['rootpath'].'/conf-custom/rspamd.local.lua.master /etc/rspamd/rspamd.local.lua'); } else { @@ -304,9 +323,9 @@ class postfix_server_plugin { $app->services->restartServiceDelayed('rspamd', 'reload'); } - exec("postconf -e 'mailbox_size_limit = ".intval($mail_config['mailbox_size_limit']*1024*1024)."'"); //TODO : no reload? - exec("postconf -e 'message_size_limit = ".intval($mail_config['message_size_limit']*1024*1024)."'"); //TODO : no reload? - + exec("postconf -e 'mailbox_size_limit = ".intval($mail_config['mailbox_size_limit']*1024*1024)."'"); + exec("postconf -e 'message_size_limit = ".intval($mail_config['message_size_limit']*1024*1024)."'"); + $app->services->restartServiceDelayed('postfix', 'reload'); } function server_ip($event_name, $data) { -- GitLab From 993470c1568db0f47c10b51b665929fc8d35b0b0 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 11:06:13 +0100 Subject: [PATCH 194/310] - removed duplicate template files and added symlinks --- install/tpl/apache_apps.vhost.master | 59 +--- install/tpl/apache_ispconfig.conf.master | 89 +----- install/tpl/apps_php_fpm_pool.conf.master | 21 +- install/tpl/bastille-firewall.cfg.master | 321 +--------------------- install/tpl/mm_cfg.py.master | 109 +------- install/tpl/nginx_apps.vhost.master | 212 +------------- server/conf/apache_ispconfig.conf.master | 6 +- server/conf/mm_cfg.py.master | 4 +- server/conf/nginx_apps.vhost.master | 11 +- 9 files changed, 20 insertions(+), 812 deletions(-) mode change 100644 => 120000 install/tpl/apache_apps.vhost.master mode change 100644 => 120000 install/tpl/apache_ispconfig.conf.master mode change 100644 => 120000 install/tpl/apps_php_fpm_pool.conf.master mode change 100644 => 120000 install/tpl/bastille-firewall.cfg.master mode change 100644 => 120000 install/tpl/mm_cfg.py.master mode change 100644 => 120000 install/tpl/nginx_apps.vhost.master diff --git a/install/tpl/apache_apps.vhost.master b/install/tpl/apache_apps.vhost.master deleted file mode 100644 index 6ffb1df8a..000000000 --- a/install/tpl/apache_apps.vhost.master +++ /dev/null @@ -1,58 +0,0 @@ - -###################################################### -# This virtual host contains the configuration -# for the ISPConfig apps vhost -###################################################### - -{tmpl_var name='vhost_port_listen'} Listen {tmpl_var name='apps_vhost_port'} -# NameVirtualHost *:{tmpl_var name='apps_vhost_port'} - - - ServerAdmin webmaster@localhost - {tmpl_var name='apps_vhost_servername'} - - - SetHandler None - - - - RequestHeader unset Proxy early - - - - DocumentRoot {tmpl_var name='apps_vhost_dir'} - AddType application/x-httpd-php .php - - Options FollowSymLinks - AllowOverride None - Require all granted - - - - - DocumentRoot {tmpl_var name='apps_vhost_dir'} - AddType application/x-httpd-php .php - - Options FollowSymLinks - AllowOverride None - Require all granted - - - - - DocumentRoot {tmpl_var name='apps_vhost_dir'} - SuexecUserGroup ispapps ispapps - - Options +Indexes +FollowSymLinks +MultiViews +ExecCGI - AllowOverride AuthConfig Indexes Limit Options FileInfo - - SetHandler fcgid-script - - FCGIWrapper {tmpl_var name='apps_vhost_basedir'}/php-fcgi-scripts/apps/.php-fcgi-starter .php - Require all granted - - - - - - diff --git a/install/tpl/apache_apps.vhost.master b/install/tpl/apache_apps.vhost.master new file mode 120000 index 000000000..098d52b9f --- /dev/null +++ b/install/tpl/apache_apps.vhost.master @@ -0,0 +1 @@ +../../server/conf/apache_apps.vhost.master \ No newline at end of file diff --git a/install/tpl/apache_ispconfig.conf.master b/install/tpl/apache_ispconfig.conf.master deleted file mode 100644 index e5a38a3ef..000000000 --- a/install/tpl/apache_ispconfig.conf.master +++ /dev/null @@ -1,88 +0,0 @@ -################################################ -# ISPConfig General Apache Options -################################################ -ServerTokens ProductOnly -ServerSignature Off - - -SSLStaplingCache shmcb:/var/run/ocsp(128000) - - -################################################ -# ISPConfig Logfile configuration for vlogger -################################################ - - -LogFormat '%v %h %l %u %t "%r" %>s %S "%{Referer}i" "%{User-Agent}i"' combined_ispconfig - -LogFormat "%v %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined_ispconfig - - -CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -p -s access.log -t \"%Y%m%d-access.log\" /var/log/ispconfig/httpd" combined_ispconfig env=!dontlog - - -CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -s access.log -t \"%Y%m%d-access.log\" /var/log/ispconfig/httpd" combined_ispconfig env=!dontlog - - - - AllowOverride None - Require all denied - - -# Do not allow access to the root file system of the server for security reasons - - Options -Indexes - AllowOverride None - Require all denied - - - - AllowOverride None - Require all denied - - -# Except of the following directories that contain website scripts - - Require all granted - - - - Require all granted - - - - Require all granted - - - - Require all granted - - -# Allow access to mailman on OpenSuSE - - Require all granted - - - - Require all granted - - - - Options +FollowSymLinks - Require all granted - - -# allow path to awstats and alias for awstats icons - - Require all granted - - -Alias /awstats-icon "/usr/share/awstats/icon" - -Alias /.well-known/acme-challenge /usr/local/ispconfig/interface/acme/.well-known/acme-challenge - - Require all granted - - AssignUserId www-data www-data - - diff --git a/install/tpl/apache_ispconfig.conf.master b/install/tpl/apache_ispconfig.conf.master new file mode 120000 index 000000000..f67719f45 --- /dev/null +++ b/install/tpl/apache_ispconfig.conf.master @@ -0,0 +1 @@ +../../server/conf/apache_ispconfig.conf.master \ No newline at end of file diff --git a/install/tpl/apps_php_fpm_pool.conf.master b/install/tpl/apps_php_fpm_pool.conf.master deleted file mode 100644 index 74597272c..000000000 --- a/install/tpl/apps_php_fpm_pool.conf.master +++ /dev/null @@ -1,20 +0,0 @@ -[{fpm_pool}-{fpm_domain}] - -listen = {fpm_socket} -listen.owner = {fpm_user} -listen.group = {fpm_group} -listen.mode = 0660 - -user = {fpm_user} -group = {fpm_group} - -pm = dynamic -pm.max_children = 500 -pm.start_servers = 2 -pm.min_spare_servers = 1 -pm.max_spare_servers = 5 - -chdir = / - -; php_admin_value[open_basedir] = /var/www/apps:/srv/www/apps:/usr/share -php_admin_flag[magic_quotes_gpc] = off \ No newline at end of file diff --git a/install/tpl/apps_php_fpm_pool.conf.master b/install/tpl/apps_php_fpm_pool.conf.master new file mode 120000 index 000000000..02e5c53cf --- /dev/null +++ b/install/tpl/apps_php_fpm_pool.conf.master @@ -0,0 +1 @@ +../../server/conf/apps_php_fpm_pool.conf.master \ No newline at end of file diff --git a/install/tpl/bastille-firewall.cfg.master b/install/tpl/bastille-firewall.cfg.master deleted file mode 100644 index 408713d74..000000000 --- a/install/tpl/bastille-firewall.cfg.master +++ /dev/null @@ -1,320 +0,0 @@ -# -# /etc/bastille-firewall.cfg -# -# Configuration file for both 2.2/ipchains and 2.4/netfilter scripts -# -# $Source: /cvsroot/bastille-linux/dev/working_tree/Bastille/bastille-firewall.cfg,v $ -# Modified by: $Author: peterw $ -# $Date: 2002/01/04 13:34:18 $ -# $Revision: 1.7 $ -# -# Copyright (C) 1999-2001 Peter Watkins -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# Thanks to David Ranch, Brad A, Don G, and others for their suggestions - -# the configuration values should be whitespace-delimited lists of -# appropriate values, e.g. -# TCP_PUBLIC_SERVICES="80 smtp ssh" -# lists Web (port 80), SMTP mail, and Secure Shell ports -# -# This script is suitable for workstations or simple NAT firewalls; -# you may want to add more "output" restrictions for serious servers - -# 0) DNS servers (Linux 2.2/ipchains only) -# You must list your DNS servers here so that -# the firewall will allow them to service your lookup requests -# -# List of DNS servers/networks to allow "domain" responses from -# This _could_ be nameservers as a list of /32 entries -#DNS_SERVERS="a.b.c.d/32 e.f.g.h/32" -# If you are running a caching nameserver, you'll need to allow from -# "0.0.0.0/0" so named can query any arbitrary nameserver -# (To enable a caching nameserver, you will also probably need to -# add "domain" to the TCP and UDP public service lists.) -#DNS_SERVERS="0.0.0.0/0" -# -# To have the DNS servers parsed from /etc/resolv.conf at runtime, -# as normal workstations will want, make this variable empty -#DNS_SERVERS="" -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -DNS_SERVERS="{DNS_SERVERS}" - - -# 1) define your interfaces (all systems) -# Note a "+" acts as a wildcard, e.g. ppp+ would match any PPP -# interface -# -# list internal/trusted interfaces -# traffic from these interfaces will be allowed -# through the firewall, no restrictions -#TRUSTED_IFACES="lo" # MINIMAL/SAFEST -# -# list external/untrusted interfaces -#PUBLIC_IFACES="eth+ ppp+ slip+" # SAFEST -# -# list internal/partially-trusted interfaces -# e.g. if this acts as a NAT/IP Masq server and you -# don't want clients on those interfaces having -# full network access to services running on this -# server (as the TRUSTED_IFACES allows) -#INTERNAL_IFACES="" # SAFEST -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -TRUSTED_IFACES="lo" # MINIMAL/SAFEST -PUBLIC_IFACES="eth+ ppp+ slip+ venet+ bond+ en+" # SAFEST -INTERNAL_IFACES="" # SAFEST - - -# 2) services for which we want to log access attempts to syslog (all systems) -# Note this only audits connection attempts from public interfaces -# -# Also see item 12, LOG_FAILURES -# -#TCP_AUDIT_SERVICES="telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh" -# anyone probing for BackOrifice? -#UDP_AUDIT_SERVICES="31337" -# how about ICMP? -#ICMP_AUDIT_TYPES="" -#ICMP_AUDIT_TYPES="echo-request" # ping/MS tracert -# -# To enable auditing, you must have syslog configured to log "kern" -# messages of "info" level; typically you'd do this with a line in -# syslog.conf like -# kern.info /var/log/messages -# though the Bastille port monitor will normally want these messages -# logged to a named pipe instead, and the Bastille script normally -# configures syslog for "kern.*" which catches these messages -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -#TCP_AUDIT_SERVICES="telnet ftp imap pop3 finger sunrpc exec login linuxconf ssh" -#UDP_AUDIT_SERVICES="31337" -#ICMP_AUDIT_TYPES="" - - -# 3) services we allow connections to (all systems) -# -# FTP note: -# To allow your machine to service "passive" FTP clients, -# you will need to make allowances for the passive data -# ports; Bastille users should read README.FTP for more -# information -# -# "public" interfaces: -# TCP services that "public" hosts should be allowed to connect to -#TCP_PUBLIC_SERVICES="" # MINIMAL/SAFEST -# -# UDP services that "public" hosts should be allowed to connect to -#UDP_PUBLIC_SERVICES="" # MINIMAL/SAFEST -# -# "internal" interfaces: -# (NB: you will need to repeat the "public" services if you want -# to allow "internal" hosts to reach those services, too.) -# TCP services that internal clients can connect to -#TCP_INTERNAL_SERVICES="" # MINIMAL/SAFEST -# -# UDP services that internal clients can connect to -#UDP_INTERNAL_SERVICES="" # MINIMAL/SAFEST -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -TCP_PUBLIC_SERVICES="{TCP_PUBLIC_SERVICES}" # MINIMAL/SAFEST -UDP_PUBLIC_SERVICES="{UDP_PUBLIC_SERVICES}" # MINIMAL/SAFEST -TCP_INTERNAL_SERVICES="" # MINIMAL/SAFEST -UDP_INTERNAL_SERVICES="" # MINIMAL/SAFEST - -# 4) passive/active FTP (Linux 2.2/ipchains only) -# FTP is a firewall nightmare; if you allow "normal" FTP connections, -# you must be careful to block any TCP services that are listening -# on high ports; it's safer to require your FTP clients to use -# "passive" mode. -# -# Note this will also force clients on machines -# that use this one for NAT/IP Masquerading to use passive mode -# for connections that go through this server (e.g. from the -# internal network to public Internet machines -# -# For more information about FTP, see the Bastille README.FTP doc -# -#FORCE_PASV_FTP="N" -#FORCE_PASV_FTP="Y" # SAFEST -# -FORCE_PASV_FTP="Y" # SAFEST - - -# 5) Services to explicitly block. (Linux 2.2/ipchains only) -# See FTP note above -# Note that ranges of ports are specified with colons, and you -# can specify an open range by using only one number, e.g. -# 1024: means ports >= 1024 and :6000 means ports <= 6000 -# -# TCP services on high ports that should be blocked if not forcing passive FTP -# This should include X (6000:6010) and anything else revealed by 'netstat -an' -# (this does not matter unless you're not forcing "passive" FTP) -#TCP_BLOCKED_SERVICES="6000:6020" -# -# UDP services to block: this should be UDP services on high ports. -# Your only vulnerability from public interfaces are the DNS and -# NTP servers/networks (those with 0.0.0.0 for DNS servers should -# obviously be very careful here!) -#UDP_BLOCKED_SERVICES="2049" -# -# types of ICMP packets to allow -#ICMP_ALLOWED_TYPES="destination-unreachable" # MINIMAL/SAFEST -# the following allows you to ping/traceroute outbound -#ICMP_ALLOWED_TYPES="destination-unreachable echo-reply time-exceeded" -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -TCP_BLOCKED_SERVICES="6000:6020" -UDP_BLOCKED_SERVICES="2049" -ICMP_ALLOWED_TYPES="destination-unreachable echo-reply time-exceeded echo-request" - - -# 6) Source Address Verification (all Linux systems) -# This helps prevent "IP Spoofing" attacks -# -ENABLE_SRC_ADDR_VERIFY="Y" # SAFEST - - -# 7) IP Masquerading / NAT. (all systems) -# List your internal/masq'ed networks here -# -# Also see item 4, FORCE_PASV_FTP, as that setting affects -# clients using IP Masquerading through this machine -# -# Set this variable if you're using IP Masq / NAT for a local network -#IP_MASQ_NETWORK="" # DISABLE/SAFEST -#IP_MASQ_NETWORK="10.0.0.0/8" # example -#IP_MASQ_NETWORK="192.168.0.0/16" # example -# -# Have lots of masq hosts? uncomment the following six lines -# and list the hosts/networks in /etc/firewall-masqhosts -# the script assumes any address without a "/" netmask afterwards -# is an individual address (netmask /255.255.255.255): -#if [ -f /etc/firewall-masqhosts ]; then -# echo "Reading list of masq hosts from /etc/firewall-masqhosts" -# # Read the file, but use 'awk' to strip comments -# # Note the sed bracket phrase includes a space and tab char -# IP_MASQ_NETWORK=`cat /etc/firewall-masqhosts | awk -F\# '/\// {print $1; next} /[0-9]/ {print $1"/32"}' |sed 's:[ ]*::g'` -#fi -# -# Masq modules -# NB: The script will prepend "ip_masq_" to each module name -#IP_MASQ_MODULES="cuseeme ftp irc quake raudio vdolive" # ALL (?) -#IP_MASQ_MODULES="ftp raudio vdolive" # RECOMMENDED -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -IP_MASQ_NETWORK="" # DISABLE/SAFEST -IP_MASQ_MODULES="ftp raudio vdolive" # RECOMMENDED - - -# 8) How to react to disallowed packets (all systems) -# whether to "REJECT" or "DROP" disallowed packets; if you're running any -# public services, you probably ought to use "REJECT"; if in serious stealth -# mode, choose "DROP" so simple probes don't know if there's anything out there -# NOTE: disallowed ICMP packets are discarded with "DROP", as -# it would not make sense to "reject" the packet if you're -# trying to disallow ping/traceroute -# NOTE: the scripts that set up the filter rules will interpret these -# keywords as needed, e.g. "DROP" becomes "DENY" for Linux 2.2/ipchains -# -REJECT_METHOD="DROP" - - -# 9) DHCP (Linux 2.2/ipchains only) -# In case your server needs to get a DHCP address from some other -# machine (e.g. cable modem) -#DHCP_IFACES="eth0" # example, to allow you to query on eth0 -#DHCP_IFACES="" # DISABLED -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -DHCP_IFACES="" # DISABLED - - -# 10) NTP servers (Linux 2.2/ipchains only) -# more UDP fun. List IP addresses or network space of NTP servers -# -#NTP_SERVERS="" # DISABLE NTP QUERIES / SAFEST -#NTP_SERVERS="a.b.c.d/32 e.f.g.h/32" # example, to allow querying 2 servers -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -NTP_SERVERS="" # DISABLE NTP QUERIES / SAFEST - - -# 11) more ICMP. (Linux 2.2/ipchains only) -# Control the outbound ICMP to make yourself invisible to -# traceroute probes -# -#ICMP_OUTBOUND_DISABLED_TYPES="destination-unreachable time-exceeded" -# -# Please make sure variable assignments are on single lines; do NOT -# use the "\" continuation character (so Bastille can change the -# values if it is run more than once) -ICMP_OUTBOUND_DISABLED_TYPES="destination-unreachable time-exceeded" - - -# 12) Logging (all systems) -# With this enabled, ipchains will log all blocked packets. -# ** this could generate huge logs ** -# This is primarily intended for the port mointoring system; -# also note that you probably do not want to "AUDIT" any services -# that you are not allowing, as doing so would mean duplicate -# logging -LOG_FAILURES="N" # do not log blocked packets - -# 13) Block fragmented packets (all systems) -# There's no good reason to allow these -#ALLOW_FRAGMENTS="N" # safest -ALLOW_FRAGMENTS="Y" # old behavior - -# 14) Prevent SMB broadcasts from leaking out NAT setup (all systems) -# Windows machines will poll teh net with SMB broadcasts, -# basically advertising their existence. Most folks agree -# that this traffic should be dropped -#DROP_SMB_NAT_BCAST="N" # allow them (are you sure?) -DROP_SMB_NAT_BCAST="Y" # drop those packets - -# 15) Log level (iptables/netfilter/Linux 2.4 only) -# Control what level of logging is used when the firewall logs -# information. Default is warning (4). Lowest priority is -# debug (7); highest is emergency (0). To prevent syslog -# from copying iptables error messages to the console, set -# this to 6 (7 would also work, but 6 is recommended) -# You can also stop syslogd/klogd from printing kernel -# messages to the console by issuing the command -# setterm -msg off -#IP_LOG_LEVEL=6 # level used in 2.2/ipchains -IP_LOG_LEVEL=4 # iptables/netfilter default - -# 16) Always attempt to use stateful features for inbound connections -# Always using state will allow the firewall to reject invalid -# packets sent to otherwise open TCP services, e.g. XMAS, NULL -# and SIN/FYN scans. The downside to choosing this behavior is that -# services may become unreachable if the packet filter's state -# table becomes full. -IP_ALWAYS_USE_STATE="N" # default, ensures services remain available -#IP_ALWAYS_USE_STATE="Y" # disallow invalid packets \ No newline at end of file diff --git a/install/tpl/bastille-firewall.cfg.master b/install/tpl/bastille-firewall.cfg.master new file mode 120000 index 000000000..42986da0c --- /dev/null +++ b/install/tpl/bastille-firewall.cfg.master @@ -0,0 +1 @@ +../../server/conf/bastille-firewall.cfg.master \ No newline at end of file diff --git a/install/tpl/mm_cfg.py.master b/install/tpl/mm_cfg.py.master deleted file mode 100644 index c0de780e0..000000000 --- a/install/tpl/mm_cfg.py.master +++ /dev/null @@ -1,108 +0,0 @@ -# -*- python -*- - -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA - - -"""This is the module which takes your site-specific settings. - -From a raw distribution it should be copied to mm_cfg.py. If you -already have an mm_cfg.py, be careful to add in only the new settings -you want. The complete set of distributed defaults, with annotation, -are in ./Defaults. In mm_cfg, override only those you want to -change, after the - - from Defaults import * - -line (see below). - -Note that these are just default settings - many can be overridden via the -admin and user interfaces on a per-list or per-user basis. - -Note also that some of the settings are resolved against the active list -setting by using the value as a format string against the -list-instance-object's dictionary - see the distributed value of -DEFAULT_MSG_FOOTER for an example.""" - - -####################################################### -# Here's where we get the distributed defaults. # - -from Defaults import * - -############################################################## -# Put YOUR site-specific configuration below, in mm_cfg.py . # -# See Defaults.py for explanations of the values. # - -#------------------------------------------------------------- -# The name of the list Mailman uses to send password reminders -# and similar. Don't change if you want mailman-owner to be -# a valid local part. -MAILMAN_SITE_LIST = 'mailman' - -#------------------------------------------------------------- -# If you change these, you have to configure your http server -# accordingly (Alias and ScriptAlias directives in most httpds) -DEFAULT_URL_PATTERN = 'https://%s/cgi-bin/mailman/' -PRIVATE_ARCHIVE_URL = '/cgi-bin/mailman/private' -IMAGE_LOGOS = '/images/mailman/' - -#------------------------------------------------------------- -# Default domain for email addresses of newly created MLs -DEFAULT_EMAIL_HOST = '{hostname}' -#------------------------------------------------------------- -# Default host for web interface of newly created MLs -DEFAULT_URL_HOST = '{hostname}' -#------------------------------------------------------------- -# Required when setting any of its arguments. -add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST) - -#------------------------------------------------------------- -# The default language for this server. -DEFAULT_SERVER_LANGUAGE = {default_language} - -#------------------------------------------------------------- -# Iirc this was used in pre 2.1, leave it for now -USE_ENVELOPE_SENDER = 0 # Still used? - -#------------------------------------------------------------- -# Unset send_reminders on newly created lists -DEFAULT_SEND_REMINDERS = 0 - -#------------------------------------------------------------- -# Uncomment this if you configured your MTA such that it -# automatically recognizes newly created lists. -# (see /usr/share/doc/mailman/README.Exim4.Debian or -# /usr/share/mailman/postfix-to-mailman.py) -# MTA=None # Misnomer, suppresses alias output on newlist - -#------------------------------------------------------------- -# Uncomment if you use Postfix virtual domains (but not -# postfix-to-mailman.py), but be sure to see -# /usr/share/doc/mailman/README.Debian first. -MTA='Postfix' -POSTFIX_STYLE_VIRTUAL_DOMAINS = [{virtual_domains}] -#------------------------------------------------------------- -# Uncomment if you want to filter mail with SpamAssassin. For -# more information please visit this website: -# http://www.jamesh.id.au/articles/mailman-spamassassin/ -# GLOBAL_PIPELINE.insert(1, 'SpamAssassin') - -POSTFIX_MAP_CMD = '/etc/mailman/virtual_to_transport.sh' - -# Note - if you're looking for something that is imported from mm_cfg, but you -# didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py. \ No newline at end of file diff --git a/install/tpl/mm_cfg.py.master b/install/tpl/mm_cfg.py.master new file mode 120000 index 000000000..396eb2f2a --- /dev/null +++ b/install/tpl/mm_cfg.py.master @@ -0,0 +1 @@ +../../server/conf/mm_cfg.py.master \ No newline at end of file diff --git a/install/tpl/nginx_apps.vhost.master b/install/tpl/nginx_apps.vhost.master deleted file mode 100644 index 701f3defb..000000000 --- a/install/tpl/nginx_apps.vhost.master +++ /dev/null @@ -1,211 +0,0 @@ -server { - listen {apps_vhost_port}; - listen [::]:{apps_vhost_port} ipv6only=on; - ssl {ssl_on}; - {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - {ssl_comment}ssl_certificate /usr/local/ispconfig/interface/ssl/ispserver.crt; - {ssl_comment}ssl_certificate_key /usr/local/ispconfig/interface/ssl/ispserver.key; - - # redirect to https if accessed with http - {ssl_comment}error_page 497 https://$host:{vhost_port}$request_uri; - - server_name {apps_vhost_servername}; - - root {apps_vhost_dir}; - - client_max_body_size 100M; - - location / { - index index.php index.html; - } - - # serve static files directly - location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { - access_log off; - } - - location ~ \.php$ { - try_files $uri =404; - fastcgi_param QUERY_STRING $query_string; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param SCRIPT_NAME $fastcgi_script_name; - fastcgi_param REQUEST_URI $request_uri; - fastcgi_param DOCUMENT_URI $document_uri; - fastcgi_param DOCUMENT_ROOT $document_root; - fastcgi_param SERVER_PROTOCOL $server_protocol; - - fastcgi_param GATEWAY_INTERFACE CGI/1.1; - fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - fastcgi_param HTTP_PROXY ""; - - fastcgi_param REMOTE_ADDR $remote_addr; - fastcgi_param REMOTE_PORT $remote_port; - fastcgi_param SERVER_ADDR $server_addr; - fastcgi_param SERVER_PORT $server_port; - fastcgi_param SERVER_NAME $server_name; - - fastcgi_param HTTPS $https; - - # PHP only, required if PHP was built with --enable-force-cgi-redirect - fastcgi_param REDIRECT_STATUS 200; - fastcgi_pass unix:{fpm_socket}; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - #fastcgi_param PATH_INFO $fastcgi_script_name; - fastcgi_buffer_size 128k; - fastcgi_buffers 256 4k; - fastcgi_busy_buffers_size 256k; - fastcgi_temp_file_write_size 256k; - } - - location ~ /\. { - deny all; - } - - location /phpmyadmin { - root /usr/share/; - index index.php index.html index.htm; - location ~ ^/phpmyadmin/(.+\.php)$ { - try_files $uri =404; - root /usr/share/; - fastcgi_param QUERY_STRING $query_string; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param SCRIPT_NAME $fastcgi_script_name; - fastcgi_param REQUEST_URI $request_uri; - fastcgi_param DOCUMENT_URI $document_uri; - fastcgi_param DOCUMENT_ROOT $document_root; - fastcgi_param SERVER_PROTOCOL $server_protocol; - - fastcgi_param GATEWAY_INTERFACE CGI/1.1; - fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - - fastcgi_param REMOTE_ADDR $remote_addr; - fastcgi_param REMOTE_PORT $remote_port; - fastcgi_param SERVER_ADDR $server_addr; - fastcgi_param SERVER_PORT $server_port; - fastcgi_param SERVER_NAME $server_name; - - fastcgi_param HTTPS $https; - - # PHP only, required if PHP was built with --enable-force-cgi-redirect - fastcgi_param REDIRECT_STATUS 200; - # To access phpMyAdmin, the default user (like www-data on Debian/Devuan/Ubuntu) must be used - {use_tcp}fastcgi_pass 127.0.0.1:9000; - {use_socket}fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_buffer_size 128k; - fastcgi_buffers 256 4k; - fastcgi_busy_buffers_size 256k; - fastcgi_temp_file_write_size 256k; - fastcgi_read_timeout 1200; - } - location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ { - root /usr/share/; - } - } - location /phpMyAdmin { - rewrite ^/* /phpmyadmin last; - } - - location /squirrelmail { - root /usr/share/; - index index.php index.html index.htm; - location ~ ^/squirrelmail/(.+\.php)$ { - try_files $uri =404; - root /usr/share/; - fastcgi_param QUERY_STRING $query_string; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param SCRIPT_NAME $fastcgi_script_name; - fastcgi_param REQUEST_URI $request_uri; - fastcgi_param DOCUMENT_URI $document_uri; - fastcgi_param DOCUMENT_ROOT $document_root; - fastcgi_param SERVER_PROTOCOL $server_protocol; - - fastcgi_param GATEWAY_INTERFACE CGI/1.1; - fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - - fastcgi_param REMOTE_ADDR $remote_addr; - fastcgi_param REMOTE_PORT $remote_port; - fastcgi_param SERVER_ADDR $server_addr; - fastcgi_param SERVER_PORT $server_port; - fastcgi_param SERVER_NAME $server_name; - - fastcgi_param HTTPS $https; - - # PHP only, required if PHP was built with --enable-force-cgi-redirect - fastcgi_param REDIRECT_STATUS 200; - # To access SquirrelMail, the default user (like www-data on Debian/Devuan/Ubuntu) must be used - {use_tcp}fastcgi_pass 127.0.0.1:9000; - {use_socket}fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_buffer_size 128k; - fastcgi_buffers 256 4k; - fastcgi_busy_buffers_size 256k; - fastcgi_temp_file_write_size 256k; - } - location ~* ^/squirrelmail/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ { - root /usr/share/; - } - } - location /webmail { - rewrite ^/* /squirrelmail last; - } - - location /cgi-bin/mailman { - root /usr/lib/; - fastcgi_split_path_info (^/cgi-bin/mailman/[^/]*)(.*)$; - fastcgi_param QUERY_STRING $query_string; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param SCRIPT_NAME $fastcgi_script_name; - fastcgi_param REQUEST_URI $request_uri; - fastcgi_param DOCUMENT_URI $document_uri; - fastcgi_param DOCUMENT_ROOT $document_root; - fastcgi_param SERVER_PROTOCOL $server_protocol; - - fastcgi_param GATEWAY_INTERFACE CGI/1.1; - fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - - fastcgi_param REMOTE_ADDR $remote_addr; - fastcgi_param REMOTE_PORT $remote_port; - fastcgi_param SERVER_ADDR $server_addr; - fastcgi_param SERVER_PORT $server_port; - fastcgi_param SERVER_NAME $server_name; - - fastcgi_param HTTPS $https; - - # PHP only, required if PHP was built with --enable-force-cgi-redirect - fastcgi_param REDIRECT_STATUS 200; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - fastcgi_intercept_errors on; - fastcgi_pass unix:{cgi_socket}; - } - - location /images/mailman { - alias /usr/share/images/mailman; - } - - location /pipermail { - alias /var/lib/mailman/archives/public; - autoindex on; - } -} diff --git a/install/tpl/nginx_apps.vhost.master b/install/tpl/nginx_apps.vhost.master new file mode 120000 index 000000000..e59b73601 --- /dev/null +++ b/install/tpl/nginx_apps.vhost.master @@ -0,0 +1 @@ +../../server/conf/nginx_apps.vhost.master \ No newline at end of file diff --git a/server/conf/apache_ispconfig.conf.master b/server/conf/apache_ispconfig.conf.master index 1a053fc43..ab85fd22a 100644 --- a/server/conf/apache_ispconfig.conf.master +++ b/server/conf/apache_ispconfig.conf.master @@ -4,11 +4,9 @@ ServerTokens ProductOnly ServerSignature Off - SSLStaplingCache shmcb:/var/run/ocsp(128000) - ################################################ # ISPConfig Logfile configuration for vlogger @@ -85,6 +83,6 @@ Alias /.well-known/acme-challenge /usr/local/ispconfig/interface/acme/.well-know Require all granted - AssignUserId www-data www-data - + AssignUserId www-data www-data + diff --git a/server/conf/mm_cfg.py.master b/server/conf/mm_cfg.py.master index 3dcf5a6a6..f57b76ad1 100644 --- a/server/conf/mm_cfg.py.master +++ b/server/conf/mm_cfg.py.master @@ -57,7 +57,7 @@ MAILMAN_SITE_LIST = 'mailman' #------------------------------------------------------------- # If you change these, you have to configure your http server # accordingly (Alias and ScriptAlias directives in most httpds) -DEFAULT_URL_PATTERN = 'http://%s/cgi-bin/mailman/' +DEFAULT_URL_PATTERN = 'https://%s/cgi-bin/mailman/' PRIVATE_ARCHIVE_URL = '/cgi-bin/mailman/private' IMAGE_LOGOS = '/images/mailman/' @@ -105,4 +105,4 @@ POSTFIX_STYLE_VIRTUAL_DOMAINS = [{virtual_domains}] POSTFIX_MAP_CMD = '/etc/mailman/virtual_to_transport.sh' # Note - if you're looking for something that is imported from mm_cfg, but you -# didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py. \ No newline at end of file +# didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py. diff --git a/server/conf/nginx_apps.vhost.master b/server/conf/nginx_apps.vhost.master index 1c8c4e70a..4003254a2 100644 --- a/server/conf/nginx_apps.vhost.master +++ b/server/conf/nginx_apps.vhost.master @@ -1,5 +1,13 @@ server { listen {apps_vhost_ip}{apps_vhost_port}; + listen [::]:{apps_vhost_port} ipv6only=on; + ssl {ssl_on}; + {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + {ssl_comment}ssl_certificate /usr/local/ispconfig/interface/ssl/ispserver.crt; + {ssl_comment}ssl_certificate_key /usr/local/ispconfig/interface/ssl/ispserver.key; + + # redirect to https if accessed with http + {ssl_comment}error_page 497 https://$host:{vhost_port}$request_uri; server_name {apps_vhost_servername}; @@ -12,7 +20,7 @@ server { } # serve static files directly - location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { + location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { access_log off; } @@ -165,6 +173,7 @@ server { fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; + fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; -- GitLab From 57bbd9f7c963abe8dc2568ebab38f59f35ae4f9f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 12:08:36 +0100 Subject: [PATCH 195/310] - removed deprecated OS --- install/dist/conf/centos52.conf.php | 209 ------------------------- install/dist/conf/centos53.conf.php | 209 ------------------------- install/dist/conf/opensuse110.conf.php | 209 ------------------------- install/dist/lib/centos52.lib.php | 40 ----- install/dist/lib/centos53.lib.php | 40 ----- install/dist/lib/opensuse110.lib.php | 36 ----- install/install.php | 1 + install/lib/install.lib.php | 39 +++++ install/update.php | 1 + 9 files changed, 41 insertions(+), 743 deletions(-) delete mode 100644 install/dist/conf/centos52.conf.php delete mode 100644 install/dist/conf/centos53.conf.php delete mode 100644 install/dist/conf/opensuse110.conf.php delete mode 100644 install/dist/lib/centos52.lib.php delete mode 100644 install/dist/lib/centos53.lib.php delete mode 100644 install/dist/lib/opensuse110.lib.php diff --git a/install/dist/conf/centos52.conf.php b/install/dist/conf/centos52.conf.php deleted file mode 100644 index c738b7ff6..000000000 --- a/install/dist/conf/centos52.conf.php +++ /dev/null @@ -1,209 +0,0 @@ - diff --git a/install/dist/conf/centos53.conf.php b/install/dist/conf/centos53.conf.php deleted file mode 100644 index c738b7ff6..000000000 --- a/install/dist/conf/centos53.conf.php +++ /dev/null @@ -1,209 +0,0 @@ - diff --git a/install/dist/conf/opensuse110.conf.php b/install/dist/conf/opensuse110.conf.php deleted file mode 100644 index eaf7763bb..000000000 --- a/install/dist/conf/opensuse110.conf.php +++ /dev/null @@ -1,209 +0,0 @@ - diff --git a/install/dist/lib/centos52.lib.php b/install/dist/lib/centos52.lib.php deleted file mode 100644 index 2cec3447b..000000000 --- a/install/dist/lib/centos52.lib.php +++ /dev/null @@ -1,40 +0,0 @@ - diff --git a/install/dist/lib/centos53.lib.php b/install/dist/lib/centos53.lib.php deleted file mode 100644 index b7f45bcfb..000000000 --- a/install/dist/lib/centos53.lib.php +++ /dev/null @@ -1,40 +0,0 @@ - diff --git a/install/dist/lib/opensuse110.lib.php b/install/dist/lib/opensuse110.lib.php deleted file mode 100644 index aeda9b9fd..000000000 --- a/install/dist/lib/opensuse110.lib.php +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/install/install.php b/install/install.php index d5578b932..251de72ad 100644 --- a/install/install.php +++ b/install/install.php @@ -106,6 +106,7 @@ if(is_installed('amavisd-new') && !is_installed('patch')) die('The patch command $dist = get_distname(); if($dist['id'] == '') die('Linux distribution or version not recognized.'); +if(!is_supported_dist($dist)) die('This distribution is not supported.'); //** Include the autoinstaller configuration (for non-interactive setups) error_reporting(E_ALL ^ E_NOTICE); diff --git a/install/lib/install.lib.php b/install/lib/install.lib.php index cb31fb28e..8dfe130f7 100644 --- a/install/lib/install.lib.php +++ b/install/lib/install.lib.php @@ -34,6 +34,44 @@ $FILE = realpath('../install.php'); require_once realpath(dirname(__FILE__)) . '/classes/libbashcolor.inc.php'; +function is_supported_dist($dist) { + $name = $dist['name']; + $version = $dist['version']; + + $min_version = false; + if($name === 'Ubuntu') { + $tmp = explode(" ", $version); + $version = reset($tmp); // Dist name is appended on get_distname + $min_version = '16.04'; + $add_versions = array('Testing', 'Unknown'); + } elseif($name === 'Debian') { + $min_version = '8'; + $add_versions = array('Testing', 'Unknown'); + } elseif($name === 'Devuan') { + $min_version = '1.0'; + $add_versions = array('Jessie', 'Ceres'); + } elseif($name === 'openSUSE') { + $min_version = '11.2'; + $add_versions = false; + } elseif($name === 'Fedora') { + $min_version = '11'; + $add_versions = array('Unknown'); + } elseif($name === 'CentOS') { + $min_version = '7.0'; + $add_versions = array('Unknown'); + } elseif($name === 'Gentoo') { + $min_version = '1.0'; + } + + if($version && $min_version && preg_match('/^[0-9]+/', $version)) { + if(version_compare($version, $min_version, '>=')) return true; + } elseif($version && !preg_match('/^[0-9]+/', $version) && !empty($add_versions)) { + if(in_array($version, $add_versions, true)) return true; + } + + return false; +} + //** Get distribution identifier //** IMPORTANT! // This is the same code as in server/lib/classes/monitor_tools.inc.php @@ -347,6 +385,7 @@ function get_distname() { $var=explode(" ", $content); $var=explode(".", $var[3]); $var=$var[0].".".$var[1]; + $distver = $var; if($var=='7.0' || $var=='7.1') { $distid = 'centos70'; } else { diff --git a/install/update.php b/install/update.php index f621e7bd9..24337fbe0 100644 --- a/install/update.php +++ b/install/update.php @@ -109,6 +109,7 @@ $conf_old = $conf; unset($conf); if($dist['id'] == '') die('Linux distribution or version not recognized.'); +if(!is_supported_dist($dist)) die('This distribution is not supported.'); //** Include the autoinstaller configuration (for non-interactive setups) error_reporting(E_ALL ^ E_NOTICE); -- GitLab From 16b9461a9e0de63faa63c7ab85208e820c0a2ec0 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 12:22:26 +0100 Subject: [PATCH 196/310] - removed mlmmj mailinglist manager --- install/dist/conf/centos70.conf.php | 4 - install/dist/conf/centos72.conf.php | 4 - install/dist/conf/debian40.conf.php | 4 - install/dist/conf/debian60.conf.php | 4 - install/dist/conf/debian90.conf.php | 4 - install/dist/conf/debiantesting.conf.php | 4 - install/dist/conf/fedora9.conf.php | 4 - install/dist/conf/gentoo.conf.php | 4 - install/dist/conf/opensuse112.conf.php | 4 - install/dist/conf/ubuntu1604.conf.php | 4 - install/install.php | 8 +- install/lib/installer_base.lib.php | 87 +--- install/tpl/mlmmj.conf.master | 5 - install/tpl/server.ini.master | 2 +- install/update.php | 6 - .../web/admin/form/server_config.tform.php | 2 +- .../web/mail/form/mail_mailinglist.tform.php | 132 ------ interface/web/mail/lib/module.conf.php | 5 - .../web/mail/list/mail_ml_membership.list.php | 93 ---- interface/web/mail/mail_mailinglist_edit.php | 7 - interface/web/mail/mail_ml_membership_del.php | 63 --- .../web/mail/mail_ml_membership_edit.php | 104 ----- .../web/mail/mail_ml_membership_list.php | 40 -- .../templates/mail_mailinglist_digest.htm | 48 --- .../templates/mail_mailinglist_options.htm | 38 -- .../templates/mail_mailinglist_privacy.htm | 44 -- server/plugins-available/mlmmj_plugin.inc.php | 406 ------------------ 27 files changed, 4 insertions(+), 1126 deletions(-) delete mode 100644 install/tpl/mlmmj.conf.master delete mode 100644 interface/web/mail/list/mail_ml_membership.list.php delete mode 100644 interface/web/mail/mail_ml_membership_del.php delete mode 100755 interface/web/mail/mail_ml_membership_edit.php delete mode 100644 interface/web/mail/mail_ml_membership_list.php delete mode 100644 interface/web/mail/templates/mail_mailinglist_digest.htm delete mode 100644 interface/web/mail/templates/mail_mailinglist_options.htm delete mode 100644 interface/web/mail/templates/mail_mailinglist_privacy.htm delete mode 100644 server/plugins-available/mlmmj_plugin.inc.php diff --git a/install/dist/conf/centos70.conf.php b/install/dist/conf/centos70.conf.php index baebbfb7a..8c9b1117f 100644 --- a/install/dist/conf/centos70.conf.php +++ b/install/dist/conf/centos70.conf.php @@ -118,10 +118,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/centos72.conf.php b/install/dist/conf/centos72.conf.php index 70d4c122f..71fa7aad9 100644 --- a/install/dist/conf/centos72.conf.php +++ b/install/dist/conf/centos72.conf.php @@ -118,10 +118,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php index a3170b786..40db346fc 100644 --- a/install/dist/conf/debian40.conf.php +++ b/install/dist/conf/debian40.conf.php @@ -120,10 +120,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index 4f95c60e9..d8146ea8c 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -120,10 +120,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index db741ed8a..f8955f9fd 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -120,10 +120,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index 27d1369e3..a7b5cb66b 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -120,10 +120,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php index 9df56faf8..350cc0690 100644 --- a/install/dist/conf/fedora9.conf.php +++ b/install/dist/conf/fedora9.conf.php @@ -118,10 +118,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index 7a76c13a9..d57323ffd 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -128,10 +128,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['user'] = 'getmail'; diff --git a/install/dist/conf/opensuse112.conf.php b/install/dist/conf/opensuse112.conf.php index 5759faad0..136b8672d 100644 --- a/install/dist/conf/opensuse112.conf.php +++ b/install/dist/conf/opensuse112.conf.php @@ -118,10 +118,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index c18a7c2bf..264227bab 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -120,10 +120,6 @@ $conf['mailman']['installed'] = false; // will be detected automatically during $conf['mailman']['config_dir'] = '/etc/mailman'; $conf['mailman']['init_script'] = 'mailman'; -//* mlmmj -$conf['mlmmj']['installed'] = false; // will be detected automatically during installation -$conf['mlmmj']['config_dir'] = '/etc/mlmmj'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/install.php b/install/install.php index 251de72ad..a7bcfb3a5 100644 --- a/install/install.php +++ b/install/install.php @@ -346,13 +346,7 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Mail $inst->configure_mailman(); } - //* Configure mlmmj - if($conf['mlmmj']['installed'] == true) { - swriteln('Configuring Mlmmj'); - $inst->configure_mlmmj(/*install*/); - } - - //* Check for Dovecot and Courier + //* Check for Dovecot if(!$conf['dovecot']['installed']) { $conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot', ($install_mode == 'expert')); } diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index c9e8391dc..a0690493f 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -157,7 +157,6 @@ class installer_base { if(is_installed('postfix')) $conf['postfix']['installed'] = true; if(is_installed('postgrey')) $conf['postgrey']['installed'] = true; if(is_installed('mailman') || is_installed('mmsitepass')) $conf['mailman']['installed'] = true; - if(is_installed('mlmmj') || is_installed('mlmmj-make-ml')) $conf['mlmmj']['installed'] = true; if(is_installed('apache') || is_installed('apache2') || is_installed('httpd') || is_installed('httpd2')) $conf['apache']['installed'] = true; if(is_installed('getmail')) $conf['getmail']['installed'] = true; if(is_installed('dovecot')) $conf['dovecot']['installed'] = true; @@ -319,7 +318,7 @@ class installer_base { $tpl_ini_array['web']['group'] = $conf['apache']['group']; $tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache']; $tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi']; - $tpl_ini_array['mail']['mailinglist_manager'] = ($conf['mlmmj']['installed'] == true)?'mlmmj':'mailman'; + $tpl_ini_array['mail']['mailinglist_manager'] = 'mailman'; $tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user']; $tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group']; $tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir']; @@ -831,90 +830,6 @@ class installer_base { exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); } - public function configure_mlmmj() { - global $conf; - - $configDir = $conf['mlmmj']['config_dir']; - @mkdir($configDir, 0755, true); - - $configFile = 'mlmmj.conf'; - - //* Backup exiting file - if(is_file("$configDir/$configFile")) { - copy("$configDir/$configFile", "$configDir/$configFile~"); - } - - // load files - if(is_file($conf['ispconfig_install_dir']."/server/conf-custom/install/$configFile.master")) { - copy($conf['ispconfig_install_dir']."/server/conf-custom/install/$configFile.master", "$configDir/$configFile"); - } else { - copy("tpl/$configFile.master", "$configDir/$configFile"); - } - - $mlConfig = @parse_ini_file("$configDir/$configFile"); - // Force PHP7 to use # to mark comments - if(PHP_MAJOR_VERSION >= 7) - $mlConfig = array_filter($mlConfig, function($v){return(substr($v,0,1)!=='#');}, ARRAY_FILTER_USE_KEY); - - $command = 'useradd --system mlmmj --home '.$mlConfig['spool_dir'].' --shell /usr/false'; - if(!is_user('mlmmj')) caselog("$command &> /dev/null", __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command"); - - @mkdir($mlConfig['spool_dir'], 0755, true); - chown($mlConfig['spool_dir'], 'mlmmj'); - chgrp($mlConfig['spool_dir'], 'mlmmj'); - - // Make a backup copy of master.cf and main.cf files - copy($conf['postfix']['config_dir'].'/main.cf', $conf['postfix']['config_dir'].'/main.cf~mlmmj'); - - //* Update postfix main.cf - $content = rf($conf['postfix']['config_dir'].'/main.cf'); - - if(!preg_match("/^alias_maps = .*hash:\/etc\/mlmmj\/aliases.*/m", $content)) { - $content = preg_replace("/^alias_maps = (.*)/m", "$0, hash:$configDir/aliases", $content); - } - - if(!preg_match("/^alias_database = .*hash:\/etc\/mlmmj\/aliases.*/m", $content)) { - $content = preg_replace("/^alias_database = (.*)/m", "$0, hash:$configDir/aliases", $content); - } - - if(!preg_match("/^virtual_alias_maps = .*hash:\/etc\/mlmmj\/virtual.*/m", $content)) { - $content = preg_replace("/^virtual_alias_maps = (.*)/m", "$0, hash:$configDir/virtual", $content); - } - - if(!preg_match("/^transport_maps = .*hash:\/etc\/mlmmj\/transport.*/m", $content)) { - $content = preg_replace("/transport_maps = (.*)/m", "$0, hash:$configDir/transport", $content); - } - - if(!preg_match("/^mlmmj_destination_recipient_limit.*/m", $content)) { - $content .= "\n# Only deliver one message to Mlmmj at a time\nmlmmj_destination_recipient_limit = 1\n"; - } - - wf($conf['postfix']['config_dir'].'/main.cf', $content); - - //* Update postfix master.cf - $content = rf($conf['postfix']['config_dir'].'/master.cf'); - if(!preg_match('/^mlmmj\s+unix\s+-\s+n\s+n\s+-\s+-\s+pipe\s*$/m', $content)) { - copy($conf['postfix']['config_dir'].'/master.cf', $conf['postfix']['config_dir'].'/master.cf~mlmmj'); - $content .= "\n# mlmmj mailing lists\n"; - $content .= "mlmmj unix - n n - - pipe\n"; - $content .= " flags=ORhu user=mlmmj argv=/usr/bin/mlmmj-receive -F -L "; - $content .= $mlConfig['spool_dir']."/\$nexthop\n\n"; - wf($conf['postfix']['config_dir'].'/master.cf', $content); - } - - //* Create aliasaes - touch("$configDir/aliases"); - exec("nohup /usr/sbin/postalias $configDir/aliases >/dev/null 2>&1"); - touch("$configDir/virtual"); - exec("nohup /usr/sbin/postmap $configDir/virtual >/dev/null 2>&1"); - touch("$configDir/transport"); - exec("nohup /usr/sbin/postmap $configDir/transport >/dev/null 2>&1"); - - //* Create/update cron entry - $cronEntry = '0 */2 * * * find /var'.$mlConfig['spool_dir'].'/ -mindepth 1 -maxdepth 1 -type d -exec /usr/bin/mlmmj-maintd -F -d {} \;'; - file_put_contents('/etc/cron.d/mlmmj', $cronEntry); - } - public function get_postfix_service($service, $type) { global $conf; diff --git a/install/tpl/mlmmj.conf.master b/install/tpl/mlmmj.conf.master deleted file mode 100644 index 44ba9e872..000000000 --- a/install/tpl/mlmmj.conf.master +++ /dev/null @@ -1,5 +0,0 @@ -# Path of the skeleton for mailing lists -skel_dir = /usr/share/mlmmj/text.skel - -# Where to store ML data and archive -spool_dir = /var/spool/mlmmj \ No newline at end of file diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 172b68b2f..235054154 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -57,7 +57,7 @@ overquota_notify_client=y overquota_notify_freq=7 overquota_notify_onok=n sendmail_path=/usr/sbin/sendmail -mailinglist_manager=mlmmj +mailinglist_manager=mailman [getmail] getmail_config_dir=/etc/getmail diff --git a/install/update.php b/install/update.php index 24337fbe0..3c3414f28 100644 --- a/install/update.php +++ b/install/update.php @@ -375,12 +375,6 @@ if($reconfigure_services_answer == 'yes' || $reconfigure_services_answer == 'sel $inst->configure_mailman('update'); } - //* Configure mlmmj - if($conf['mlmmj']['installed'] == true && $inst->reconfigure_app('Mlmmj', $reconfigure_services_answer)) { - swriteln('Configuring Mlmmj'); - $inst->configure_mlmmj(/*update*/); - } - //** Configure Spamasassin if($inst->reconfigure_app('Spamassassin', $reconfigure_services_answer)) { swriteln('Configuring Spamassassin'); diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 3eec00e9d..f4c23d617 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -757,7 +757,7 @@ $form["tabs"]['mail'] = array( 'datatype' => 'VARCHAR', 'formtype' => 'SELECT', 'default' => '20', - 'value' => array('mlmmj' => 'Mlmmj', 'mailman' => 'Mailman') + 'value' => array('mailman' => 'Mailman') ), //################################# // ENDE Datatable fields diff --git a/interface/web/mail/form/mail_mailinglist.tform.php b/interface/web/mail/form/mail_mailinglist.tform.php index 2914e42f8..e5152ec47 100644 --- a/interface/web/mail/form/mail_mailinglist.tform.php +++ b/interface/web/mail/form/mail_mailinglist.tform.php @@ -161,135 +161,3 @@ $form["tabs"]['mailinglist'] = array ( ) ); -if($mlManager == 'mlmmj') { - $form["tabs"]['options'] = array ( - 'title' => "Options", - 'width' => 100, - 'template' => "templates/mail_mailinglist_options.htm", - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'admins' => array ( - 'datatype' => 'TEXT', - 'formtype' => 'TEXTAREA', - 'validators' => array ( - 0 => array ( 'type' => 'ISEMAIL', - 'allowempty' => 'y', - 'separator' => "\n", - 'errmsg'=> 'email_error_isemail'), - ), - 'cols' => '30', - 'rows' => '5' - ), - 'subject_prefix' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - ), - 'mail_footer' => array ( - 'datatype' => 'TEXT', - 'formtype' => 'TEXTAREA', - 'cols' => '30', - 'rows' => '5' - ), - 'archive' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - ) - ); - - $form["tabs"]['privacy'] = array ( - 'title' => "Privacy", - 'width' => 100, - 'template' => "templates/mail_mailinglist_privacy.htm", - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'list_type' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'RADIO', - 'regex' => '', - 'errmsg' => '', - 'default' => 'user', - 'value' => array ('open' => 'open_list_txt', 'closed' => 'closed_list_txt'), - 'width' => '30', - 'maxlength' => '255', - 'rows' => '', - 'cols' => '' - ), - 'subscribe_policy' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => 'confirm', - 'value' => array( - 'disabled' => 'sub_disabled_txt', - 'confirm' => 'sub_confirm_txt', - 'approval' => 'sub_approval_txt', - 'both' => 'sub_both_txt', - 'none' => 'sub_none_txt'), - ), - 'posting_policy' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => 'confirm', - 'value' => array( - 'closed' => 'post_closed_txt', - 'moderated' => 'post_moderated_txt', - 'free' => 'post_free_txt'), - ), - ) - ); - - $form["tabs"]['digest'] = array ( - 'title' => "Digest", - 'width' => 100, - 'template' => "templates/mail_mailinglist_digest.htm", - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'digesttext' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'digestsub' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'digestinterval' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '7', - 'validators' => array(0 => array('type' => 'ISINT'), - array('type'=>'RANGE', 'range'=>'1:60') - ), - 'value' => '', - 'width' => '15' - ), - 'digestmaxmails' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '50', - 'validators' => array(0 => array('type' => 'ISINT'), - array('type'=>'RANGE', 'range'=>'10:100') - ), - 'value' => '', - 'width' => '15' - ), - ) - ); - -} -?> diff --git a/interface/web/mail/lib/module.conf.php b/interface/web/mail/lib/module.conf.php index 46cfe4681..eaed5de89 100644 --- a/interface/web/mail/lib/module.conf.php +++ b/interface/web/mail/lib/module.conf.php @@ -87,11 +87,6 @@ if($app->auth->get_client_limit($userid, 'mailmailinglist') != 0) 'html_id' => 'mail_mailinglist_list'); $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - if($mlManager == 'mlmmj') - $items[] = array( 'title' => 'Membership', - 'target' => 'content', - 'link' => 'mail/mail_ml_membership_list.php', - 'html_id' => 'mail_ml_membership_list'); } if(count($items) && $app->system->has_service($userid, 'mail')) diff --git a/interface/web/mail/list/mail_ml_membership.list.php b/interface/web/mail/list/mail_ml_membership.list.php deleted file mode 100644 index d23211817..000000000 --- a/interface/web/mail/list/mail_ml_membership.list.php +++ /dev/null @@ -1,93 +0,0 @@ - "mailinglist_id", - 'datatype' => "INTEGER", - 'formtype' => "SELECT", - 'op' => "like", - 'prefix' => "", - 'suffix' => "", - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT mailinglist_id, CONCAT_WS(\'@\', listname, domain) as listname FROM mail_mailinglist WHERE {AUTHSQL} ORDER BY listname', - 'keyfield'=> 'mailinglist_id', - 'valuefield'=> 'listname' - ), - 'width' => "", - 'value' => ""); - - -$liste["item"][] = array( 'field' => "email", - 'datatype' => "VARCHAR", - 'filters' => array( 0 => array( 'event' => 'SHOW', - 'type' => 'IDNTOUTF8') - ), - 'formtype' => "TEXT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", - 'width' => "", - 'value' => ""); - -$liste["item"][] = array( 'field' => "name", - 'datatype' => "VARCHAR", - 'formtype' => "TEXT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", - 'width' => "", - 'value' => ""); - -$liste["item"][] = array( 'field' => "goodbye_msg", - 'datatype' => "VARCHAR", - 'formtype' => "SELECT", - 'op' => "=", - 'prefix' => "", - 'suffix' => "", - 'width' => "", - 'value' => array('n' => "
".$app->lng('no_txt')."
", 'y' => "
".$app->lng('yes_txt')."
")); diff --git a/interface/web/mail/mail_mailinglist_edit.php b/interface/web/mail/mail_mailinglist_edit.php index 73680c8a1..57d9c77f2 100644 --- a/interface/web/mail/mail_mailinglist_edit.php +++ b/interface/web/mail/mail_mailinglist_edit.php @@ -197,13 +197,6 @@ class page_action extends tform_actions { function onAfterInsert() { global $app, $conf; - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - if($mlManager == 'mlmmj') { - // The following update is usefull to set the prefix of the new mailinglist as the list name - $sql = 'UPDATE mail_mailinglist SET subject_prefix = ? WHERE mailinglist_id = ?'; - $app->db->query($sql, '['.$this->dataRecord['listname'].']', $this->id); - } - // make sure that the record belongs to the client group and not the admin group when a dmin inserts it // also make sure that the user can not delete domain created by a admin if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { diff --git a/interface/web/mail/mail_ml_membership_del.php b/interface/web/mail/mail_ml_membership_del.php deleted file mode 100644 index d2dcaf542..000000000 --- a/interface/web/mail/mail_ml_membership_del.php +++ /dev/null @@ -1,63 +0,0 @@ -auth->check_module_permissions('mail'); - -// Loading classes -$app->uses('tpl,tform,tform_actions'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - function onBeforeDelete() { - global $app; $conf; - - } -} - -$page = new page_action; -$page->onDelete(); - -?> diff --git a/interface/web/mail/mail_ml_membership_edit.php b/interface/web/mail/mail_ml_membership_edit.php deleted file mode 100755 index 60f0f1b21..000000000 --- a/interface/web/mail/mail_ml_membership_edit.php +++ /dev/null @@ -1,104 +0,0 @@ -auth->check_module_permissions('mail'); - -// Loading classes -$app->uses('tpl,tform,tform_actions'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - - function onShowNew() { - global $app, $conf; - - //TODO: Add ml members limit - // we will check only users, not admins -// if($_SESSION["s"]["user"]["typ"] == 'user') { -// if(!$app->tform->checkClientLimit('limit_ml_membership')) { -// $app->error($app->tform->wordbook["limit_ml_membership_txt"]); -// } -// if(!$app->tform->checkResellerLimit('limit_ml_membership')) { -// $app->error('Reseller: '.$app->tform->wordbook["limit_ml_membership_txt"]); -// } -// } - - parent::onShowNew(); - } - - function onShowEnd() { - global $app, $conf; - - if($this->id > 0) { - //* we are editing a existing record - $app->tpl->setVar("edit_disabled", 1); - - - $sql = "SELECT mailinglist_id, email FROM mail_ml_membership WHERE subscriber_id = ?"; - $mlID = $app->db->queryOneRecord($sql, $this->id); - if($mlID['mailinglist_id']) $app->tpl->setVar("mailinglist_id_value", $mlID["mailinglist_id"]); - if($mlID['email']) $app->tpl->setVar("email_value", $mlID["email"]); - } else { - $app->tpl->setVar("edit_disabled", 0); - } - - parent::onShowEnd(); - } - - function onBeforeInsert() { - global $app, $conf; - - // Set the server id of the mailinglist members = server ID of mail domain. - $domain = $app->db->queryOneRecord("SELECT server_id FROM mail_mailinglist WHERE mailinglist_id = ?", $this->dataRecord["mailinglist_id"]); - - $this->dataRecord["server_id"] = $domain['server_id']; - } - -} - -$app->tform_actions = new page_action; -$app->tform_actions->onLoad(); - -?> diff --git a/interface/web/mail/mail_ml_membership_list.php b/interface/web/mail/mail_ml_membership_list.php deleted file mode 100644 index 7d5be8a59..000000000 --- a/interface/web/mail/mail_ml_membership_list.php +++ /dev/null @@ -1,40 +0,0 @@ -auth->check_module_permissions('mail'); - -$app->load('listform_actions'); - -class list_action extends listform_actions { - - function onShow() { - global $app, $conf; - - $app->uses('getconf'); - $global_config = $app->getconf->get_global_config('mail'); - - if($global_config['mailmailinglist_link'] == 'y') { - $app->tpl->setVar('mailmailinglist_link', 1); - } else { - $app->tpl->setVar('mailmailinglist_link', 0); - } - - parent::onShow(); - } - -} - -$list = new list_action; -$list->onLoad(); \ No newline at end of file diff --git a/interface/web/mail/templates/mail_mailinglist_digest.htm b/interface/web/mail/templates/mail_mailinglist_digest.htm deleted file mode 100644 index 57a2c1c66..000000000 --- a/interface/web/mail/templates/mail_mailinglist_digest.htm +++ /dev/null @@ -1,48 +0,0 @@ - -

-Digest - -
- -
- {tmpl_var name='digestsub'} -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- {tmpl_var name='digesttext'} -
-
- - - -
- - -
- - diff --git a/interface/web/mail/templates/mail_mailinglist_options.htm b/interface/web/mail/templates/mail_mailinglist_options.htm deleted file mode 100644 index 9d0489a16..000000000 --- a/interface/web/mail/templates/mail_mailinglist_options.htm +++ /dev/null @@ -1,38 +0,0 @@ - -

- -General Options -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- {tmpl_var name='archive'} -
-
- - - -
- - -
- diff --git a/interface/web/mail/templates/mail_mailinglist_privacy.htm b/interface/web/mail/templates/mail_mailinglist_privacy.htm deleted file mode 100644 index 63fe167ad..000000000 --- a/interface/web/mail/templates/mail_mailinglist_privacy.htm +++ /dev/null @@ -1,44 +0,0 @@ - -

-Privacy - -
- -
- {tmpl_var name='list_type'} -
-
- -
- -
-
- -
- -
-
- - - -
- - -
- - \ No newline at end of file diff --git a/server/plugins-available/mlmmj_plugin.inc.php b/server/plugins-available/mlmmj_plugin.inc.php deleted file mode 100644 index 7f1130e01..000000000 --- a/server/plugins-available/mlmmj_plugin.inc.php +++ /dev/null @@ -1,406 +0,0 @@ - 10100 Srl -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. -*/ - -/* -templates/mail_mailinglist_list.htm -templates/mail_mailinglist_edit.htm - -list/mail_mailinglist.list.php - -form/mail_mailinglist.tform.php - -mailinglist.php -mail_mailinglist_list.php -mail_mailinglist_edit.php -mail_mailinglist_del.php -*/ - -class mlmmj_plugin { - const ML_ALIAS = 0; - const ML_TRANSPORT = 1; - const ML_VIRTUAL = 2; - const SECONDS_IN_DAY = 86400; - - private $plugin_name = 'mlmmj_plugin'; - private $class_name = 'mlmmj_plugin'; - private $mlmmj_config_dir = '/etc/mlmmj/'; - - /* - This function is called during ispconfig installation to determine - if a symlink shall be created for this plugin. - */ - function onInstall() { - global $conf; - - if($conf['services']['mail'] == true) return true; - else return false; - } - - //This function is called when the plugin is loaded - function onLoad() { - global $app; - - // Register for the events - $app->plugins->registerEvent('mail_mailinglist_insert', $this->plugin_name, 'list_insert'); - $app->plugins->registerEvent('mail_mailinglist_update', $this->plugin_name, 'list_update'); - $app->plugins->registerEvent('mail_mailinglist_delete', $this->plugin_name, 'list_delete'); - - $app->plugins->registerEvent('mail_ml_member_insert', $this->plugin_name, 'member_insert'); - $app->plugins->registerEvent('mail_ml_member_update', $this->plugin_name, 'member_update'); - $app->plugins->registerEvent('mail_ml_member_delete', $this->plugin_name, 'member_delete'); - - } - - function list_insert($event_name, $data) { - global $app, $conf; - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - - if($mlManager == 'mlmmj') { - $mlConf = $this->getMlConfig(); - $rec = $data['new']; - $listDomain = $rec['domain']; - $listName = $rec['listname']; - $listDir = $mlConf['spool_dir']."/$listDomain/$listName"; - $lang = 'en'; - $owner = $rec['email']; - - // Creating ML directories structure - mkdir("$listDir/incoming", 0755, true); - mkdir("$listDir/queue/discarded", 0755, true); - mkdir("$listDir/archive", 0755, true); - mkdir("$listDir/text", 0755, true); - mkdir("$listDir/subconf", 0755, true); - mkdir("$listDir/unsubconf", 0755, true); - mkdir("$listDir/bounce", 0755, true); - mkdir("$listDir/control", 0755, true); - mkdir("$listDir/moderation", 0755, true); - mkdir("$listDir/subscribers.d", 0755, true); - mkdir("$listDir/digesters.d", 0755, true); - mkdir("$listDir/requeue", 0755, true); - mkdir("$listDir/nomailsubs.d", 0755, true); - - // Creating ML index file - touch("$listDir/index"); - - // Creating default control files - // WARNING: Edit this section if default DB values will be modified! - touch("$listDir/control/nodigestsub"); - touch("$listDir/control/noarchive"); - file_put_contents("$listDir/control/owner", $owner); - file_put_contents("$listDir/control/listaddress", "$listName@$listDomain"); - file_put_contents("$listDir/control/prefix", "[$listName]"); - - // Copying language translations - if(!is_dir("/usr/share/mlmmj/text.skel/$lang")) $lang = 'en'; - foreach (glob("/usr/share/mlmmj/text.skel/$lang/*") as $filename) - copy($filename, "$listDir/text/".basename($filename)); - - // The mailinglist directory have to be owned by the user running the mailserver - $this->changeOwnership($listDir); - - // Creating alias entry - $this->addMapEntry("$listName: \"|/usr/bin/mlmmj-recieve -L $listDir/\"", self::ML_ALIAS); - - // Creating transport entry - $this->addMapEntry("$listDomain--$listName@localhost.mlmmj mlmmj:$listDomain/$listName", self::ML_TRANSPORT); - - // Creating virtual entry - $this->addMapEntry("$listName@$listDomain $listDomain--$listName@localhost.mlmmj", self::ML_VIRTUAL); - } - } - - // The purpose of this plugin is to rewrite the main.cf file - function list_update($event_name, $data) { - global $app, $conf; - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - - if($mlManager == 'mlmmj') { - $rec = $data['new']; - $mlConf = $this->getMlConfig(); - - $controlDir = "{$mlConf['spool_dir']}/{$rec['domain']}/{$rec['listname']}/control"; - - // Doesn't matter if the list is open or close, members can ALWAYS unsubscribe - if($rec['list_type'] == 'open') { - switch($rec['subscribe_policy']) { - case 'disabled': - touch("$controlDir/closedlistsub"); - @unlink("$controlDir/submod"); - @unlink("$controlDir/nosubconfirm"); - break; - case 'both': - touch("$controlDir/submod"); - case 'approval': - touch("$controlDir/nosubconfirm"); - @unlink("$controlDir/closedlistsub"); - break; - case 'none': - touch("$controlDir/nosubconfirm"); - @unlink("$controlDir/closedlistsub"); - break; - case 'confirm': - @unlink("$controlDir/nosubconfirm"); - @unlink("$controlDir/closedlistsub"); - @unlink("$controlDir/submod"); - break; - } - - switch($rec['posting_policy']) { - case 'closed': - touch("$controlDir/subonlypost"); - break; - case 'moderated': - touch("$controlDir/modnonsubposts"); - break; - case 'free': - @unlink("$controlDir/modnonsubposts"); - @unlink("$controlDir/subonlypost"); - break; - } - } elseif($rec['list_type'] == 'closed') { - touch("$controlDir/closedlistsub"); - touch("$controlDir/subonlypost"); - @unlink("$controlDir/modnonsubposts"); - @unlink("$controlDir/submod"); - @unlink("$controlDir/nosubconfirm"); - } - - if($rec['digestsub'] == 'y') { - @unlink("$controlDir/nodigestsub"); - if($rec['digesttext'] == 'y') @unlink("$controlDir/nodigesttext"); - else touch("$controlDir/nodigesttext"); - file_put_contents("$controlDir/digestinterval", $rec['digestinterval']*self::SECONDS_IN_DAY); - file_put_contents("$controlDir/digestmaxmails", $rec['digestmaxmails']); - } else { - touch("$controlDir/nodigestsub"); - @unlink("$controlDir/nodigesttext"); - @unlink("$controlDir/digestinterval"); - @unlink("$controlDir/digestmaxmails"); - } - - if($rec['subject_prefix']) - file_put_contents("$controlDir/prefix", $rec['subject_prefix']); - else @unlink("$controlDir/prefix"); - - if($rec['mail_footer']) - file_put_contents("$controlDir/footer", $rec['mail_footer']); - else @unlink("$controlDir/footer"); - - if($rec['archive'] == 'y') - @unlink("$controlDir/noarchive"); - else - touch("$controlDir/noarchive"); - - $this->changeOwnership("$controlDir/*"); - } - } - - function list_delete($event_name, $data) { - global $app, $conf; - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - - if($mlManager == 'mlmmj') { - $mlConf = $this->getMlConfig(); - $rec = $data['old']; - $listDomain = $rec['domain']; - $listName = $rec['listname']; - $listDir = $mlConf['spool_dir']."/$listDomain/$listName"; - - // Remove ML directory structure - $this->rmdirR($listDir); - @rmdir($mlConf['spool_dir']."/$listDomain"); - - // Removing alias entry - $this->delMapEntry("$listName: \"|/usr/bin/mlmmj-recieve -L $listDir/\"", self::ML_ALIAS); - - // Removing transport entry - $this->delMapEntry("$listDomain--$listName@localhost.mlmmj mlmmj:$listDomain/$listName", self::ML_TRANSPORT); - - // Removing virtual entry - $this->delMapEntry("$listName@$listDomain $listDomain--$listName@localhost.mlmmj", self::ML_VIRTUAL); - } - } - - function member_insert($event_name, $data) { - global $app, $conf; - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - - if($mlManager == 'mlmmj') { - $mlConf = $this->getMlConfig(); - - $rec = $data['new']; - - $sql = "SELECT * FROM mail_mailinglist WHERE mailinglist_id = ?"; - $ml = $app->db->queryOneRecord($sql, $rec['mailinglist_id']); - if($ml['mailinglist_id']) { - $listDomain = $ml['domain']; - $listName = $ml['listname']; - $listDir = $mlConf['spool_dir']."/$listDomain/$listName"; - } - - $welcome = ($rec['welcome_msg'] == 'y')?'-c':''; - $command = "/usr/bin/mlmmj-sub -q -s -L $listDir $welcome -a ".$rec['email']; - exec("nohup $command>/dev/null 2>&1"); - } - } - - function member_update($event_name, $data) { - //TODO: Implement something usefull on update event (e.g. change to digest subscription) - } - - function member_delete($event_name, $data) { - global $app, $conf; - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - - if($mlManager == 'mlmmj') { - $mlConf = $this->getMlConfig(); - - $rec = $data['old']; - - $sql = "SELECT * FROM mail_mailinglist WHERE mailinglist_id = ?"; - $ml = $app->db->queryOneRecord($sql, $rec['mailinglist_id']); - if($ml['mailinglist_id']) { - $listDomain = $ml['domain']; - $listName = $ml['listname']; - $listDir = $mlConf['spool_dir']."/$listDomain/$listName"; - } - - $goodbye = ($rec['goodbye_msg'] == 'y')?'-c':''; - $command = "/usr/bin/mlmmj-unsub -q -s -L $listDir $goodbye -a ".$rec['email']; - exec("nohup $command>/dev/null 2>&1"); - } - } - - private function getMlConfig() { - $mlConfig = @parse_ini_file($this->mlmmj_config_dir.'mlmmj.conf'); - - // Force PHP7 to use # to mark comments - if(PHP_MAJOR_VERSION >= 7 && is_array($mlConfig)) - $mlConfig = array_filter($mlConfig, function($v){return(substr($v,0,1)!=='#');}, ARRAY_FILTER_USE_KEY); - - return $mlConfig; - } - - private function changeOwnership($path, $recursive=true) { - if(basename($path) == '*') $path = dirname($path); - - if(is_dir($path)) { - if($objs = glob($path."/*")) { - foreach($objs as $obj) { - chown($obj, 'mlmmj'); - chgrp($obj, 'mlmmj'); - if(is_dir($obj) && $recursive) $this->changeOwnership($obj); - } - } - } - - return chown($path, 'mlmmj') && chgrp($path, 'mlmmj'); - } - - private function rmdirR($path) { - if(is_dir($path) === true) { - $files = array_diff(scandir($path), array('.', '..')); - foreach($files as $file) $this->rmdirR(realpath($path) . '/' . $file); - - return rmdir($path); - } elseif(is_file($path) === true) return unlink($path); - - return false; - } - - private function addMapEntry($directive, $type) { - - $destFile = $this->mlmmj_config_dir; - switch($type) { - case self::ML_ALIAS: - $destFile .= 'aliases'; - $command = 'postalias'; - break; - case self::ML_TRANSPORT: - $destFile .= 'transport'; - $command = 'postmap'; - break; - case self::ML_VIRTUAL: - $destFile .= 'virtual'; - $command = 'postmap'; - break; - } - - $lines = file($destFile, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); - $lines[] = $directive; - - file_put_contents($destFile, implode("\n", array_unique($lines))); - exec("nohup /usr/sbin/$command $destFile >/dev/null 2>&1 &"); - } - - private function delMapEntry($directive, $type) { - - $destFile = $this->mlmmj_config_dir; - switch($type) { - case self::ML_ALIAS: - $destFile .= 'aliases'; - $command = 'postalias'; - break; - case self::ML_TRANSPORT: - $destFile .= 'transport'; - $command = 'postmap'; - break; - case self::ML_VIRTUAL: - $destFile .= 'virtual'; - $command = 'postmap'; - break; - } - - $lines = file($destFile, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES); - - foreach(array_keys($lines, $directive) as $key) unset($lines[$key]); - - file_put_contents($destFile, implode("\n", array_unique($lines))); - exec("nohup /usr/sbin/$command $destFile >/dev/null 2>&1 &"); - } - - private function checkSys() { - if(!is_dir($this->mlmmj_config_dir)) mkdir($this->mlmmj_config_dir, 0755); - if(!file_exists($this->mlmmj_config_dir.'mlmmj.conf')) { - file_put_contents($this->mlmmj_config_dir.'mlmmj.conf', 'skel_dir = /usr/share/mlmmj/text.skel'); - file_put_contents($this->mlmmj_config_dir.'mlmmj.conf', 'spool_dir = /var/spool/mlmmj', FILE_APPEND); - } - if(!file_exists($this->mlmmj_config_dir.'aliases')) touch($this->mlmmj_config_dir.'aliases'); - if(!file_exists($this->mlmmj_config_dir.'transport')) touch($this->mlmmj_config_dir.'transport'); - if(!file_exists($this->mlmmj_config_dir.'virtual')) touch($this->mlmmj_config_dir.'virtual'); - } -} // end class - -?> -- GitLab From 877e06a37a8663a963ea795c005eff057b687d5e Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 13:09:23 +0100 Subject: [PATCH 197/310] - removed mailinglist (mailman, rest of ml) --- install/dist/conf/centos70.conf.php | 5 - install/dist/conf/centos72.conf.php | 5 - install/dist/conf/debian40.conf.php | 5 - install/dist/conf/debian60.conf.php | 5 - install/dist/conf/debian90.conf.php | 5 - install/dist/conf/debiantesting.conf.php | 5 - install/dist/conf/fedora9.conf.php | 5 - install/dist/conf/gentoo.conf.php | 5 - install/dist/conf/opensuse112.conf.php | 5 - install/dist/conf/ubuntu1604.conf.php | 5 - install/dist/conf/ubuntu1710.conf.php | 5 - install/dist/conf/ubuntu1804.conf.php | 5 - install/dist/lib/fedora.lib.php | 14 - install/dist/lib/opensuse.lib.php | 11 - install/install.php | 8 - install/lib/installer_base.lib.php | 94 ------- install/sql/incremental/upd_0007.sql | 18 -- install/sql/incremental/upd_0015.sql | 2 +- install/sql/incremental/upd_0017.sql | 2 +- install/sql/incremental/upd_0074.sql | 9 - .../sql/incremental/upd_dev_collection.sql | 11 - install/sql/ispconfig3.sql | 34 --- install/tpl/debian_postfix.conf.master | 6 +- install/tpl/fedora_postfix.conf.master | 4 +- install/tpl/gentoo_postfix.conf.master | 2 +- install/tpl/mm_cfg.py.master | 1 - install/tpl/opensuse_postfix.conf.master | 8 +- install/tpl/server.ini.master | 1 - install/update.php | 7 - interface/lib/classes/remote.d/client.inc.php | 2 +- interface/lib/classes/remote.d/mail.inc.php | 47 ---- .../plugins/mail_mail_domain_plugin.inc.php | 8 - .../web/admin/form/server_config.tform.php | 6 - .../web/admin/form/system_config.tform.php | 18 -- .../templates/server_config_mail_edit.htm | 6 - .../templates/system_config_mail_edit.htm | 9 - interface/web/client/client_del.php | 2 +- interface/web/client/form/client.tform.php | 14 - .../web/client/form/client_template.tform.php | 14 - interface/web/client/form/reseller.tform.php | 14 - .../client/templates/client_edit_limits.htm | 3 - .../templates/client_template_edit_limits.htm | 3 - .../client/templates/reseller_edit_limits.htm | 3 - interface/web/dashboard/ajax_get_json.php | 3 - interface/web/dashboard/dashlets/limits.php | 4 - .../web/mail/form/mail_mailinglist.tform.php | 163 ----------- .../mail/form/mail_ml_membership.tform.php | 131 --------- interface/web/mail/lib/module.conf.php | 20 -- interface/web/mail/lib/remote.conf.php | 1 - .../web/mail/list/mail_mailinglist.list.php | 70 ----- interface/web/mail/mail_domain_del.php | 6 - interface/web/mail/mail_domain_edit.php | 3 - interface/web/mail/mail_mailinglist_del.php | 58 ---- interface/web/mail/mail_mailinglist_edit.php | 254 ------------------ interface/web/mail/mail_mailinglist_list.php | 44 --- interface/web/mail/mailinglist.php | 68 ----- .../mail/templates/mail_mailinglist_edit.htm | 101 ------- .../mail/templates/mail_mailinglist_list.htm | 73 ----- .../templates/mail_ml_membership_edit.htm | 64 ----- .../templates/mail_ml_membership_list.htm | 75 ------ interface/web/tools/import_vpopmail.php | 4 +- interface/web/tools/resync.php | 21 -- interface/web/tools/templates/resync.htm | 7 - .../examples/mail_mailinglist_add.php | 41 --- .../examples/mail_mailinglist_delete.php | 36 --- .../examples/mail_mailinglist_get.php | 34 --- .../examples/mail_mailinglist_update.php | 42 --- server/conf/apache_ispconfig.conf.master | 14 - server/conf/mm_cfg.py.master | 108 -------- server/conf/nginx_apps.vhost.master | 44 --- server/mods-available/mail_module.inc.php | 20 +- .../plugins-available/mailman_plugin.inc.php | 182 ------------- .../server_services_plugin.inc.php | 2 +- 73 files changed, 17 insertions(+), 2117 deletions(-) delete mode 120000 install/tpl/mm_cfg.py.master delete mode 100644 interface/web/mail/form/mail_mailinglist.tform.php delete mode 100755 interface/web/mail/form/mail_ml_membership.tform.php delete mode 100644 interface/web/mail/list/mail_mailinglist.list.php delete mode 100644 interface/web/mail/mail_mailinglist_del.php delete mode 100644 interface/web/mail/mail_mailinglist_edit.php delete mode 100644 interface/web/mail/mail_mailinglist_list.php delete mode 100644 interface/web/mail/mailinglist.php delete mode 100644 interface/web/mail/templates/mail_mailinglist_edit.htm delete mode 100644 interface/web/mail/templates/mail_mailinglist_list.htm delete mode 100644 interface/web/mail/templates/mail_ml_membership_edit.htm delete mode 100644 interface/web/mail/templates/mail_ml_membership_list.htm delete mode 100644 remoting_client/examples/mail_mailinglist_add.php delete mode 100644 remoting_client/examples/mail_mailinglist_delete.php delete mode 100644 remoting_client/examples/mail_mailinglist_get.php delete mode 100644 remoting_client/examples/mail_mailinglist_update.php delete mode 100644 server/conf/mm_cfg.py.master delete mode 100644 server/plugins-available/mailman_plugin.inc.php diff --git a/install/dist/conf/centos70.conf.php b/install/dist/conf/centos70.conf.php index 8c9b1117f..eaf0ba612 100644 --- a/install/dist/conf/centos70.conf.php +++ b/install/dist/conf/centos70.conf.php @@ -113,11 +113,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/centos72.conf.php b/install/dist/conf/centos72.conf.php index 71fa7aad9..0d88bcfb7 100644 --- a/install/dist/conf/centos72.conf.php +++ b/install/dist/conf/centos72.conf.php @@ -113,11 +113,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php index 40db346fc..0dcb1bffb 100644 --- a/install/dist/conf/debian40.conf.php +++ b/install/dist/conf/debian40.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index d8146ea8c..adff0dcc7 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index f8955f9fd..eb3c646f8 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index a7b5cb66b..60030bfdc 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php index 350cc0690..20824f1e7 100644 --- a/install/dist/conf/fedora9.conf.php +++ b/install/dist/conf/fedora9.conf.php @@ -113,11 +113,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index d57323ffd..585c1fc66 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -123,11 +123,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['user'] = 'getmail'; diff --git a/install/dist/conf/opensuse112.conf.php b/install/dist/conf/opensuse112.conf.php index 136b8672d..077f86718 100644 --- a/install/dist/conf/opensuse112.conf.php +++ b/install/dist/conf/opensuse112.conf.php @@ -113,11 +113,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index 264227bab..2ef53324b 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/ubuntu1710.conf.php b/install/dist/conf/ubuntu1710.conf.php index d539ac8ed..555765b3b 100644 --- a/install/dist/conf/ubuntu1710.conf.php +++ b/install/dist/conf/ubuntu1710.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/conf/ubuntu1804.conf.php b/install/dist/conf/ubuntu1804.conf.php index cafd33850..363014a98 100644 --- a/install/dist/conf/ubuntu1804.conf.php +++ b/install/dist/conf/ubuntu1804.conf.php @@ -115,11 +115,6 @@ $conf['postfix']['vmail_groupid'] = '5000'; $conf['postfix']['vmail_groupname'] = 'vmail'; $conf['postfix']['vmail_mailbox_base'] = '/var/vmail'; -//* Mailman -$conf['mailman']['installed'] = false; // will be detected automatically during installation -$conf['mailman']['config_dir'] = '/etc/mailman'; -$conf['mailman']['init_script'] = 'mailman'; - //* Getmail $conf['getmail']['installed'] = false; // will be detected automatically during installation $conf['getmail']['config_dir'] = '/etc/getmail'; diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 699908722..10f6c3bf1 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -29,7 +29,6 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ class installer_dist extends installer_base { - protected $mailman_group = 'mailman'; public function __construct() { //** check apache modules */ @@ -183,19 +182,6 @@ class installer_dist extends installer_base { touch($config_dir.'/nested_header_checks'); touch($config_dir.'/body_checks'); - //* Create the mailman files - if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data'); - //if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases'); - if(is_file('/var/lib/mailman/data/aliases')) unlink('/var/lib/mailman/data/aliases'); - if(!is_link('/var/lib/mailman/data/aliases')) symlink('/etc/mailman/aliases', '/var/lib/mailman/data/aliases'); - if(!is_dir('/etc/mailman')) mkdir('/etc/mailman'); - if(!is_file('/etc/mailman/aliases')) touch('/etc/mailman/aliases'); - exec('postalias /var/lib/mailman/data/aliases'); - if(!is_file('/etc/mailman/virtual-mailman')) touch('/etc/mailman/virtual-mailman'); - exec('postmap /etc/mailman/virtual-mailman'); - if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman'); - exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); - //* Create auxillary postfix conf files $configfile = 'helo_access'; if(is_file($config_dir.'/'.$configfile)) { diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index 7dc63401a..d1866b34e 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -29,8 +29,6 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ class installer_dist extends installer_base { - protected $mailman_group = 'mailman'; - public function __construct() { //** check apache modules */ $mods = getapachemodules(); @@ -194,15 +192,6 @@ class installer_dist extends installer_base { touch($config_dir.'/nested_header_checks'); touch($config_dir.'/body_checks'); - //* Create the mailman files - if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data'); - if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases'); - exec('postalias /var/lib/mailman/data/aliases'); - if(!is_file('/var/lib/mailman/data/virtual-mailman')) touch('/var/lib/mailman/data/virtual-mailman'); - exec('postmap /var/lib/mailman/data/virtual-mailman'); - if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman'); - exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); - //* Create auxillary postfix conf files $configfile = 'helo_access'; if(is_file($config_dir.'/'.$configfile)) { diff --git a/install/install.php b/install/install.php index a7bcfb3a5..adcff706b 100644 --- a/install/install.php +++ b/install/install.php @@ -339,13 +339,6 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Mail } if($conf['services']['mail']) { - //* Configure Mailman - $force = @($conf['mailman']['installed']) ? true : $inst->force_configure_app('Mailman', ($install_mode == 'expert')); - if($force) { - swriteln('Configuring Mailman'); - $inst->configure_mailman(); - } - //* Check for Dovecot if(!$conf['dovecot']['installed']) { $conf['dovecot']['installed'] = $inst->force_configure_app('Dovecot', ($install_mode == 'expert')); @@ -578,7 +571,6 @@ if($conf['postfix']['installed'] == true && $conf['postfix']['init_script'] != ' if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart')); if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart')); if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart')); -if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &'); if($conf['apache']['installed'] == true && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart')); //* Reload is enough for nginx if($conf['nginx']['installed'] == true){ diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index a0690493f..46608c226 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -37,8 +37,6 @@ class installer_base { 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 - protected $mailman_group = 'list'; - public function __construct() { global $conf; //TODO: maybe $conf should be passed to constructor @@ -156,7 +154,6 @@ class installer_base { if(is_installed('mysql') || is_installed('mysqld')) $conf['mysql']['installed'] = true; if(is_installed('postfix')) $conf['postfix']['installed'] = true; if(is_installed('postgrey')) $conf['postgrey']['installed'] = true; - if(is_installed('mailman') || is_installed('mmsitepass')) $conf['mailman']['installed'] = true; if(is_installed('apache') || is_installed('apache2') || is_installed('httpd') || is_installed('httpd2')) $conf['apache']['installed'] = true; if(is_installed('getmail')) $conf['getmail']['installed'] = true; if(is_installed('dovecot')) $conf['dovecot']['installed'] = true; @@ -318,7 +315,6 @@ class installer_base { $tpl_ini_array['web']['group'] = $conf['apache']['group']; $tpl_ini_array['web']['php_ini_path_apache'] = $conf['apache']['php_ini_path_apache']; $tpl_ini_array['web']['php_ini_path_cgi'] = $conf['apache']['php_ini_path_cgi']; - $tpl_ini_array['mail']['mailinglist_manager'] = 'mailman'; $tpl_ini_array['dns']['bind_user'] = $conf['bind']['bind_user']; $tpl_ini_array['dns']['bind_group'] = $conf['bind']['bind_group']; $tpl_ini_array['dns']['bind_zonefiles_dir'] = $conf['bind']['bind_zonefiles_dir']; @@ -749,87 +745,6 @@ class installer_base { } - public function configure_mailman($status = 'insert') { - global $conf; - - $config_dir = $conf['mailman']['config_dir'].'/'; - $full_file_name = $config_dir.'mm_cfg.py'; - //* Backup exiting file - if(is_file($full_file_name)) { - copy($full_file_name, $config_dir.'mm_cfg.py~'); - } - - // load files - $content = rfsel($conf['ispconfig_install_dir'].'/server/conf-custom/install/mm_cfg.py.master', 'tpl/mm_cfg.py.master'); - $old_file = rf($full_file_name); - - $old_options = array(); - $lines = explode("\n", $old_file); - foreach ($lines as $line) - { - if (trim($line) != '' && substr($line, 0, 1) != '#') - { - @list($key, $value) = @explode("=", $line); - if (isset($value) && $value !== '') - { - $key = rtrim($key); - $old_options[$key] = trim($value); - } - } - } - - $virtual_domains = ''; - if($status == 'update') - { - // create virtual_domains list - $domainAll = $this->db->queryAllRecords("SELECT domain FROM mail_mailinglist GROUP BY domain"); - - if(is_array($domainAll)) { - foreach($domainAll as $domain) - { - if ($domainAll[0]['domain'] == $domain['domain']) - $virtual_domains .= "'".$domain['domain']."'"; - else - $virtual_domains .= ", '".$domain['domain']."'"; - } - } - } - else - $virtual_domains = "' '"; - - $content = str_replace('{hostname}', $conf['hostname'], $content); - if(!isset($old_options['DEFAULT_SERVER_LANGUAGE']) || $old_options['DEFAULT_SERVER_LANGUAGE'] == '') $old_options['DEFAULT_SERVER_LANGUAGE'] = "'en'"; - $content = str_replace('{default_language}', $old_options['DEFAULT_SERVER_LANGUAGE'], $content); - $content = str_replace('{virtual_domains}', $virtual_domains, $content); - - wf($full_file_name, $content); - - //* Write virtual_to_transport.sh script - $config_dir = $conf['mailman']['config_dir'].'/'; - $full_file_name = $config_dir.'virtual_to_transport.sh'; - - //* Backup exiting virtual_to_transport.sh script - if(is_file($full_file_name)) { - copy($full_file_name, $config_dir.'virtual_to_transport.sh~'); - } - - if(is_dir('/etc/mailman')) { - if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailman-virtual_to_transport.sh')) { - copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/mailman-virtual_to_transport.sh', $full_file_name); - } else { - copy('tpl/mailman-virtual_to_transport.sh', $full_file_name); - } - chgrp($full_file_name, $this->mailman_group); - chmod($full_file_name, 0755); - } - - //* Create aliasaes - if($status == 'install') exec('/usr/lib/mailman/bin/genaliases 2>/dev/null'); - - if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman'); - exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); - } - public function get_postfix_service($service, $type) { global $conf; @@ -989,15 +904,6 @@ class installer_base { touch($config_dir.'/nested_header_checks'); touch($config_dir.'/body_checks'); - //* Create the mailman files - if(!is_dir('/var/lib/mailman/data')) exec('mkdir -p /var/lib/mailman/data'); - if(!is_file('/var/lib/mailman/data/aliases')) touch('/var/lib/mailman/data/aliases'); - exec('postalias /var/lib/mailman/data/aliases'); - if(!is_file('/var/lib/mailman/data/virtual-mailman')) touch('/var/lib/mailman/data/virtual-mailman'); - exec('postmap /var/lib/mailman/data/virtual-mailman'); - if(!is_file('/var/lib/mailman/data/transport-mailman')) touch('/var/lib/mailman/data/transport-mailman'); - exec('/usr/sbin/postmap /var/lib/mailman/data/transport-mailman'); - //* Create auxillary postfix conf files $configfile = 'helo_access'; if(is_file($config_dir.'/'.$configfile)) { diff --git a/install/sql/incremental/upd_0007.sql b/install/sql/incremental/upd_0007.sql index cea381322..8b1378917 100644 --- a/install/sql/incremental/upd_0007.sql +++ b/install/sql/incremental/upd_0007.sql @@ -1,19 +1 @@ -ALTER TABLE client ADD COLUMN limit_mailmailinglist int(11) NOT NULL default '-1'; -ALTER TABLE client_template ADD COLUMN limit_mailmailinglist int(11) NOT NULL default '-1'; -CREATE TABLE IF NOT EXISTS `mail_mailinglist` ( - `mailinglist_id` int(11) unsigned NOT NULL auto_increment, - `sys_userid` int(11) unsigned NOT NULL default '0', - `sys_groupid` int(11) unsigned NOT NULL default '0', - `sys_perm_user` varchar(5) NOT NULL, - `sys_perm_group` varchar(5) character set ucs2 NOT NULL, - `sys_perm_other` varchar(5) NOT NULL, - `server_id` int(11) unsigned NOT NULL default '0', - `domain` varchar(255) NOT NULL, - `listname` varchar(255) NOT NULL, - `email` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - PRIMARY KEY (`mailinglist_id`) -) ENGINE=MyISAM AUTO_INCREMENT=1; - -DROP TABLE `mail_mailman_domain`; \ No newline at end of file diff --git a/install/sql/incremental/upd_0015.sql b/install/sql/incremental/upd_0015.sql index e0aa23afd..f3d26f93b 100644 --- a/install/sql/incremental/upd_0015.sql +++ b/install/sql/incremental/upd_0015.sql @@ -1,3 +1,3 @@ ALTER TABLE `cron` CHANGE `command` `command` TEXT NOT NULL; -ALTER TABLE `client` ADD `limit_openvz_vm` int(11) NOT NULL DEFAULT '0' AFTER `limit_mailmailinglist` , +ALTER TABLE `client` ADD `limit_openvz_vm` int(11) NOT NULL DEFAULT '0' AFTER `limit_maildomain`, ADD `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0' AFTER `limit_openvz_vm`; \ No newline at end of file diff --git a/install/sql/incremental/upd_0017.sql b/install/sql/incremental/upd_0017.sql index 07a4d7890..1cff2317b 100644 --- a/install/sql/incremental/upd_0017.sql +++ b/install/sql/incremental/upd_0017.sql @@ -1,2 +1,2 @@ -ALTER TABLE `client_template` ADD `limit_openvz_vm` int(11) NOT NULL DEFAULT '0' AFTER `limit_mailmailinglist` , +ALTER TABLE `client_template` ADD `limit_openvz_vm` int(11) NOT NULL DEFAULT '0' AFTER `limit_maildomain` , ADD `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0' AFTER `limit_openvz_vm`; \ No newline at end of file diff --git a/install/sql/incremental/upd_0074.sql b/install/sql/incremental/upd_0074.sql index 05c33a38b..fb02b89f5 100644 --- a/install/sql/incremental/upd_0074.sql +++ b/install/sql/incremental/upd_0074.sql @@ -95,15 +95,6 @@ ALTER TABLE `mail_forwarding` CHANGE `source` `source` varchar(255) NOT NULL DEFAULT '', CHANGE `active` `active` enum('n','y') NOT NULL DEFAULT 'n'; -ALTER TABLE `mail_mailinglist` - CHANGE `sys_perm_user` `sys_perm_user` varchar(5) NOT NULL DEFAULT '', - CHANGE `sys_perm_group` `sys_perm_group` varchar(5) NOT NULL DEFAULT '', - CHANGE `sys_perm_other` `sys_perm_other` varchar(5) NOT NULL DEFAULT '', - CHANGE `domain` `domain` varchar(255) NOT NULL DEFAULT '', - CHANGE `listname` `listname` varchar(255) NOT NULL DEFAULT '', - CHANGE `email` `email` varchar(255) NOT NULL DEFAULT '', - CHANGE `password` `password` varchar(255) NOT NULL DEFAULT ''; - ALTER TABLE `mail_traffic` CHANGE `mailuser_id` `mailuser_id` int(11) unsigned NOT NULL DEFAULT '0', CHANGE `month` `month` char(7) NOT NULL DEFAULT '', diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 351c89936..483a9a4ba 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -1,14 +1,3 @@ -ALTER TABLE `mail_mailinglist` ADD `list_type` enum('open','closed') NOT NULL DEFAULT 'open'; -ALTER TABLE `mail_mailinglist` ADD `subject_prefix` varchar(50) NOT NULL DEFAULT ''; -ALTER TABLE `mail_mailinglist` ADD `admins` mediumtext; -ALTER TABLE `mail_mailinglist` ADD `digestinterval` int(11) NOT NULL DEFAULT '7'; -ALTER TABLE `mail_mailinglist` ADD `digestmaxmails` int(11) NOT NULL DEFAULT '50'; -ALTER TABLE `mail_mailinglist` ADD `archive` enum('n','y') NOT NULL DEFAULT 'n'; -ALTER TABLE `mail_mailinglist` ADD `digesttext` ENUM('n','y') NOT NULL DEFAULT 'n'; -ALTER TABLE `mail_mailinglist` ADD `digestsub` ENUM('n','y') NOT NULL DEFAULT 'n'; -ALTER TABLE `mail_mailinglist` ADD `mail_footer` mediumtext; -ALTER TABLE `mail_mailinglist` ADD `subscribe_policy` enum('disabled','confirm','approval','both','none') NOT NULL DEFAULT 'confirm'; -ALTER TABLE `mail_mailinglist` ADD `posting_policy` enum('closed','moderated','free') NOT NULL DEFAULT 'free'; ALTER TABLE `sys_user` ADD `last_login_ip` VARCHAR(50) NULL AFTER `lost_password_reqtime`; ALTER TABLE `sys_user` ADD `last_login_at` BIGINT(20) NULL AFTER `last_login_ip`; ALTER TABLE `sys_remoteaction` CHANGE `action_state` `action_state` ENUM('pending','processing','ok','warning','error') NOT NULL DEFAULT 'pending'; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 2d86f57ff..c9702b00a 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -226,7 +226,6 @@ CREATE TABLE `client` ( `limit_traffic_quota` int(11) NOT NULL DEFAULT '-1', `limit_client` int(11) NOT NULL DEFAULT '0', `limit_domainmodule` int(11) NOT NULL DEFAULT '0', - `limit_mailmailinglist` int(11) NOT NULL DEFAULT '-1', `limit_openvz_vm` int(11) NOT NULL DEFAULT '0', `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0', `parent_client_id` int(11) unsigned NOT NULL DEFAULT '0', @@ -342,7 +341,6 @@ CREATE TABLE `client_template` ( `limit_traffic_quota` int(11) NOT NULL default '-1', `limit_client` int(11) NOT NULL default '0', `limit_domainmodule` int(11) NOT NULL DEFAULT '0', - `limit_mailmailinglist` int(11) NOT NULL default '-1', `limit_openvz_vm` int(11) NOT NULL DEFAULT '0', `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`template_id`) @@ -915,38 +913,6 @@ CREATE TABLE `mail_get` ( -- -------------------------------------------------------- --- --- Tabellenstruktur für Tabelle `mail_mailinglist` --- - -CREATE TABLE `mail_mailinglist` ( - `mailinglist_id` int(11) unsigned NOT NULL auto_increment, - `sys_userid` int(11) unsigned NOT NULL default '0', - `sys_groupid` int(11) unsigned NOT NULL default '0', - `sys_perm_user` varchar(5) NOT NULL DEFAULT '', - `sys_perm_group` varchar(5) NOT NULL DEFAULT '', - `sys_perm_other` varchar(5) NOT NULL DEFAULT '', - `server_id` int(11) unsigned NOT NULL default '0', - `domain` varchar(255) NOT NULL DEFAULT '', - `listname` varchar(255) NOT NULL DEFAULT '', - `list_type` enum('open','closed') NOT NULL DEFAULT 'open', - `email` varchar(255) NOT NULL DEFAULT '', - `password` varchar(255) NOT NULL DEFAULT '', - `subject_prefix` varchar(50) NOT NULL DEFAULT '', - `admins` mediumtext, - `digestinterval` int(11) NOT NULL DEFAULT '7', - `digestmaxmails` int(11) NOT NULL DEFAULT '50', - `archive` enum('n','y') NOT NULL DEFAULT 'n', - `digesttext` enum('n','y') NOT NULL DEFAULT 'n', - `digestsub` enum('n','y') NOT NULL DEFAULT 'n', - `mail_footer` mediumtext, - `subscribe_policy` enum('disabled','confirm','approval','both','none') NOT NULL DEFAULT 'confirm', - `posting_policy` enum('closed','moderated','free') NOT NULL DEFAULT 'free', - PRIMARY KEY (`mailinglist_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - -- -- Table structure for Table `mail_relay_recipient` -- diff --git a/install/tpl/debian_postfix.conf.master b/install/tpl/debian_postfix.conf.master index 22a9484b1..7549fe53b 100644 --- a/install/tpl/debian_postfix.conf.master +++ b/install/tpl/debian_postfix.conf.master @@ -1,7 +1,5 @@ -alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases -alias_database = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases virtual_alias_domains = -virtual_alias_maps = hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf +virtual_alias_maps = proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf virtual_mailbox_domains = proxy:mysql:{config_dir}/mysql-virtual_domains.cf virtual_mailbox_maps = proxy:mysql:{config_dir}/mysql-virtual_mailboxes.cf virtual_mailbox_base = {vmail_mailbox_base} @@ -20,7 +18,7 @@ smtpd_use_tls = yes smtpd_tls_security_level = may smtpd_tls_cert_file = {config_dir}/smtpd.cert smtpd_tls_key_file = {config_dir}/smtpd.key -transport_maps = hash:/var/lib/mailman/data/transport-mailman, proxy:mysql:{config_dir}/mysql-virtual_transports.cf +transport_maps = proxy:mysql:{config_dir}/mysql-virtual_transports.cf relay_domains = mysql:{config_dir}/mysql-virtual_relaydomains.cf relay_recipient_maps = mysql:{config_dir}/mysql-virtual_relayrecipientmaps.cf smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf diff --git a/install/tpl/fedora_postfix.conf.master b/install/tpl/fedora_postfix.conf.master index f06af8228..f9eff2d64 100644 --- a/install/tpl/fedora_postfix.conf.master +++ b/install/tpl/fedora_postfix.conf.master @@ -1,5 +1,5 @@ virtual_alias_domains = -virtual_alias_maps = hash:/etc/mailman/virtual-mailman, proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf +virtual_alias_maps = proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf virtual_mailbox_domains = proxy:mysql:{config_dir}/mysql-virtual_domains.cf virtual_mailbox_maps = proxy:mysql:{config_dir}/mysql-virtual_mailboxes.cf virtual_mailbox_base = {vmail_mailbox_base} @@ -16,7 +16,7 @@ smtpd_use_tls = yes smtpd_tls_security_level = may smtpd_tls_cert_file = {config_dir}/smtpd.cert smtpd_tls_key_file = {config_dir}/smtpd.key -transport_maps = hash:/var/lib/mailman/data/transport-mailman, proxy:mysql:{config_dir}/mysql-virtual_transports.cf +transport_maps = proxy:mysql:{config_dir}/mysql-virtual_transports.cf relay_domains = mysql:{config_dir}/mysql-virtual_relaydomains.cf relay_recipient_maps = mysql:{config_dir}/mysql-virtual_relayrecipientmaps.cf smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf diff --git a/install/tpl/gentoo_postfix.conf.master b/install/tpl/gentoo_postfix.conf.master index dc20e02c1..1c7f9814b 100644 --- a/install/tpl/gentoo_postfix.conf.master +++ b/install/tpl/gentoo_postfix.conf.master @@ -15,7 +15,7 @@ smtpd_use_tls = yes smtpd_tls_security_level = may smtpd_tls_cert_file = {config_dir}/smtpd.cert smtpd_tls_key_file = {config_dir}/smtpd.key -transport_maps = hash:/var/lib/mailman/data/transport-mailman, proxy:mysql:{config_dir}/mysql-virtual_transports.cf +transport_maps = proxy:mysql:{config_dir}/mysql-virtual_transports.cf relay_domains = mysql:{config_dir}/mysql-virtual_relaydomains.cf relay_recipient_maps = mysql:{config_dir}/mysql-virtual_relayrecipientmaps.cf smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf diff --git a/install/tpl/mm_cfg.py.master b/install/tpl/mm_cfg.py.master deleted file mode 120000 index 396eb2f2a..000000000 --- a/install/tpl/mm_cfg.py.master +++ /dev/null @@ -1 +0,0 @@ -../../server/conf/mm_cfg.py.master \ No newline at end of file diff --git a/install/tpl/opensuse_postfix.conf.master b/install/tpl/opensuse_postfix.conf.master index 4192f988b..4ed16e3dd 100644 --- a/install/tpl/opensuse_postfix.conf.master +++ b/install/tpl/opensuse_postfix.conf.master @@ -1,7 +1,7 @@ -alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases -alias_database = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases +alias_maps = hash:/etc/aliases +alias_database = hash:/etc/aliases virtual_alias_domains = -virtual_alias_maps = hash:/etc/mailman/virtual-mailman, proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf +virtual_alias_maps = proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf virtual_mailbox_domains = proxy:mysql:{config_dir}/mysql-virtual_domains.cf virtual_mailbox_maps = proxy:mysql:{config_dir}/mysql-virtual_mailboxes.cf virtual_mailbox_base = {vmail_mailbox_base} @@ -18,7 +18,7 @@ smtpd_use_tls = yes smtpd_tls_security_level = may smtpd_tls_cert_file = {config_dir}/smtpd.cert smtpd_tls_key_file = {config_dir}/smtpd.key -transport_maps = hash:/var/lib/mailman/data/transport-mailman, proxy:mysql:{config_dir}/mysql-virtual_transports.cf +transport_maps = proxy:mysql:{config_dir}/mysql-virtual_transports.cf relay_domains = mysql:{config_dir}/mysql-virtual_relaydomains.cf relay_recipient_maps = mysql:{config_dir}/mysql-virtual_relayrecipientmaps.cf smtpd_sender_login_maps = proxy:mysql:{config_dir}/mysql-virtual_sender_login_maps.cf diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 235054154..68f786bf5 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -57,7 +57,6 @@ overquota_notify_client=y overquota_notify_freq=7 overquota_notify_onok=n sendmail_path=/usr/sbin/sendmail -mailinglist_manager=mailman [getmail] getmail_config_dir=/etc/getmail diff --git a/install/update.php b/install/update.php index 3c3414f28..01a3799dc 100644 --- a/install/update.php +++ b/install/update.php @@ -369,12 +369,6 @@ if($reconfigure_services_answer == 'yes' || $reconfigure_services_answer == 'sel } - //** Configure mailman - if($conf['mailman']['installed'] == true && $inst->reconfigure_app('Mailman', $reconfigure_services_answer)) { - swriteln('Configuring Mailman'); - $inst->configure_mailman('update'); - } - //** Configure Spamasassin if($inst->reconfigure_app('Spamassassin', $reconfigure_services_answer)) { swriteln('Configuring Spamassassin'); @@ -516,7 +510,6 @@ if($reconfigure_services_answer == 'yes') { if($conf['amavis']['installed'] == true && $conf['amavis']['init_script'] != '') system($inst->getinitcommand($conf['amavis']['init_script'], 'restart')); if($conf['clamav']['installed'] == true && $conf['clamav']['init_script'] != '') system($inst->getinitcommand($conf['clamav']['init_script'], 'restart')); if($conf['dovecot']['installed'] == true && $conf['dovecot']['init_script'] != '') system($inst->getinitcommand($conf['dovecot']['init_script'], 'restart')); - if($conf['mailman']['installed'] == true && $conf['mailman']['init_script'] != '') system('nohup '.$inst->getinitcommand($conf['mailman']['init_script'], 'restart').' >/dev/null 2>&1 &'); } if($conf['services']['web'] || $inst->install_ispconfig_interface) { if($conf['webserver']['server_type'] == 'apache' && $conf['apache']['init_script'] != '') system($inst->getinitcommand($conf['apache']['init_script'], 'restart')); diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php index 5c47c26c7..92adb9af5 100644 --- a/interface/lib/classes/remote.d/client.inc.php +++ b/interface/lib/classes/remote.d/client.inc.php @@ -404,7 +404,7 @@ class remoting_client extends remoting { $app->db->query("DELETE FROM sys_user WHERE client_id = ?", $client_id); //* Delete all records (sub-clients, mail, web, etc....) of this client. - $tables = 'cron,dns_rr,dns_soa,dns_slave,ftp_user,mail_access,mail_content_filter,mail_domain,mail_forwarding,mail_get,mail_user,mail_user_filter,shell_user,spamfilter_users,support_message,web_database,web_database_user,web_domain,web_traffic,domain,mail_mailinglist,client'; + $tables = 'cron,dns_rr,dns_soa,dns_slave,ftp_user,mail_access,mail_content_filter,mail_domain,mail_forwarding,mail_get,mail_user,mail_user_filter,shell_user,spamfilter_users,support_message,web_database,web_database_user,web_domain,web_traffic,domain,client'; $tables_array = explode(',', $tables); $client_group_id = $app->functions->intval($client_group['groupid']); if($client_group_id > 1) { diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php index ef4483bce..955c85d7a 100644 --- a/interface/lib/classes/remote.d/mail.inc.php +++ b/interface/lib/classes/remote.d/mail.inc.php @@ -135,53 +135,6 @@ class remoting_mail extends remoting { return $affected_rows; } - //* Get mail mailinglist details - public function mail_mailinglist_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'mail_mailinglist_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../mail/form/mail_mailinglist.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); - } - - //* Add a mail mailinglist - public function mail_mailinglist_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'mail_mailinglist_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $primary_id = $this->insertQuery('../mail/form/mail_mailinglist.tform.php', $client_id, $params); - return $primary_id; - } - - //* Update a mail mailinglist - public function mail_mailinglist_update($session_id, $client_id, $primary_id, $params) - { - if(!$this->checkPerm($session_id, 'mail_mailinglist_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../mail/form/mail_mailinglist.tform.php', $client_id, $primary_id, $params); - return $affected_rows; - } - - //* Delete a mail mailinglist - public function mail_mailinglist_delete($session_id, $primary_id) - { - if(!$this->checkPerm($session_id, 'mail_mailinglist_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../mail/form/mail_mailinglist.tform.php', $primary_id); - return $affected_rows; - } - //* Get mail user details public function mail_user_get($session_id, $primary_id) { diff --git a/interface/lib/plugins/mail_mail_domain_plugin.inc.php b/interface/lib/plugins/mail_mail_domain_plugin.inc.php index e72c4aa06..f90c6f961 100644 --- a/interface/lib/plugins/mail_mail_domain_plugin.inc.php +++ b/interface/lib/plugins/mail_mail_domain_plugin.inc.php @@ -88,14 +88,6 @@ class mail_mail_domain_plugin { } } - //* Update the mailinglist - $mailing_lists = $app->db->queryAllRecords("SELECT mailinglist_id FROM mail_mailinglist WHERE domain = ?", $page_form->oldDataRecord['domain']); - if(is_array($mailing_lists)) { - foreach($mailing_lists as $rec) { - $app->db->datalogUpdate('mail_mailinglist', array("sys_userid" => $client_user_id, "sys_groupid" => $sys_groupid), 'mailinglist_id', $rec['mailinglist_id']); - } - } - //* Update the mailget records $mail_gets = $app->db->queryAllRecords("SELECT mailget_id, destination FROM mail_get WHERE destination LIKE ?", "%@" . $page_form->oldDataRecord['domain']); if(is_array($mail_gets)) { diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index f4c23d617..9c48d72d0 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -753,12 +753,6 @@ $form["tabs"]['mail'] = array( 'default' => 'n', 'value' => array(0 => 'n', 1 => 'y') ), - 'mailinglist_manager' => array( - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'default' => '20', - 'value' => array('mailman' => 'Mailman') - ), //################################# // ENDE Datatable fields //################################# diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php index ea1ce1aaf..31a9b6bcc 100644 --- a/interface/web/admin/form/system_config.tform.php +++ b/interface/web/admin/form/system_config.tform.php @@ -269,24 +269,6 @@ $form["tabs"]['mail'] = array ( 'width' => '30', 'maxlength' => '255' ), - 'mailmailinglist_link' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'mailmailinglist_url' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'REGEX', - 'regex' => '/^[0-9a-zA-Z\:\/\-\.]{0,255}$/', - 'errmsg'=> 'mailinglist_url_error_regex'), - ), - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255' - ), 'admin_mail' => array ( 'datatype' => 'VARCHAR', 'filters' => array( 0 => array( 'event' => 'SAVE', diff --git a/interface/web/admin/templates/server_config_mail_edit.htm b/interface/web/admin/templates/server_config_mail_edit.htm index 9b12dbc0a..0cbef2902 100644 --- a/interface/web/admin/templates/server_config_mail_edit.htm +++ b/interface/web/admin/templates/server_config_mail_edit.htm @@ -119,12 +119,6 @@ {tmpl_var name='overquota_notify_onok'}
-
- -
-
diff --git a/interface/web/admin/templates/system_config_mail_edit.htm b/interface/web/admin/templates/system_config_mail_edit.htm index e29c5f442..ae5fbc4d0 100644 --- a/interface/web/admin/templates/system_config_mail_edit.htm +++ b/interface/web/admin/templates/system_config_mail_edit.htm @@ -45,15 +45,6 @@
 {tmpl_var name='webmail_url_note_txt'} [SERVERNAME]
-
- -
- {tmpl_var name='mailmailinglist_link'} -
-
-
- -
diff --git a/interface/web/client/client_del.php b/interface/web/client/client_del.php index 2bddd02a0..58ee7cf09 100644 --- a/interface/web/client/client_del.php +++ b/interface/web/client/client_del.php @@ -128,7 +128,7 @@ class page_action extends tform_actions { $app->db->query("DELETE FROM sys_user WHERE client_id = ?", $client_id); // Delete all records (sub-clients, mail, web, etc....) of this client. - $tables = 'cron,client,dns_rr,dns_soa,dns_slave,ftp_user,mail_access,mail_content_filter,mail_domain,mail_forwarding,mail_get,mail_user,mail_user_filter,shell_user,spamfilter_users,support_message,web_database,web_database_user,web_domain,web_folder,web_folder_user,domain,mail_mailinglist,spamfilter_wblist'; + $tables = 'cron,client,dns_rr,dns_soa,dns_slave,ftp_user,mail_access,mail_content_filter,mail_domain,mail_forwarding,mail_get,mail_user,mail_user_filter,shell_user,spamfilter_users,support_message,web_database,web_database_user,web_domain,web_folder,web_folder_user,domain,spamfilter_wblist'; $tables_array = explode(',', $tables); $client_group_id = $app->functions->intval($client_group['groupid']); if($client_group_id > 1) { diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index 23745a69e..dfba3ec36 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -784,20 +784,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_mailmailinglist' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_mailmailinglist_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), 'limit_mailforward' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php index dee369b0a..13c76a598 100644 --- a/interface/web/client/form/client_template.tform.php +++ b/interface/web/client/form/client_template.tform.php @@ -200,20 +200,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_mailmailinglist' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_mailmailinglist_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), 'limit_mailforward' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index e2db8a0f9..7412dbb83 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -740,20 +740,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_mailmailinglist' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_mailmailinglist_error_notint'), - ), - 'default' => '-1', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), 'limit_mailbox' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index 4f4a8f9e1..a260e847e 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -207,9 +207,6 @@
-
- -
diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm index 5ba0eca5d..0f28e2678 100644 --- a/interface/web/client/templates/client_template_edit_limits.htm +++ b/interface/web/client/templates/client_template_edit_limits.htm @@ -165,9 +165,6 @@
-
- -
diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm index d24ab0bf9..3121e2c2e 100644 --- a/interface/web/client/templates/reseller_edit_limits.htm +++ b/interface/web/client/templates/reseller_edit_limits.htm @@ -209,9 +209,6 @@
-
- -
diff --git a/interface/web/dashboard/ajax_get_json.php b/interface/web/dashboard/ajax_get_json.php index 32fc8912e..8d2099b36 100644 --- a/interface/web/dashboard/ajax_get_json.php +++ b/interface/web/dashboard/ajax_get_json.php @@ -102,9 +102,6 @@ if($type == 'globalsearch'){ // email transports $result[] = _search('mail', 'mail_transport'); - // mailinglists - $result[] = _search('mail', 'mail_mailinglist'); - // getmails $result[] = _search('mail', 'mail_get'); diff --git a/interface/web/dashboard/dashlets/limits.php b/interface/web/dashboard/dashlets/limits.php index 9d05dbd9c..3befab5b9 100644 --- a/interface/web/dashboard/dashlets/limits.php +++ b/interface/web/dashboard/dashlets/limits.php @@ -18,10 +18,6 @@ class dashlet_limits { 'db_table' => 'mail_domain', 'db_where' => ''); - $limits[] = array('field' => 'limit_mailmailinglist', - 'db_table' => 'mail_mailinglist', - 'db_where' => ''); - $limits[] = array('field' => 'limit_mailbox', 'db_table' => 'mail_user', 'db_where' => ''); diff --git a/interface/web/mail/form/mail_mailinglist.tform.php b/interface/web/mail/form/mail_mailinglist.tform.php deleted file mode 100644 index e5152ec47..000000000 --- a/interface/web/mail/form/mail_mailinglist.tform.php +++ /dev/null @@ -1,163 +0,0 @@ -uses('getconf'); -$mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - -$form["title"] = "Mailing List"; -$form["description"] = ""; -$form["name"] = "mail_mailinglist"; -$form["action"] = "mail_mailinglist_edit.php"; -$form["db_table"] = "mail_mailinglist"; -$form["db_table_idx"] = "mailinglist_id"; -$form["db_history"] = "yes"; -$form["tab_default"] = "mailinglist"; -$form["list_default"] = "mail_mailinglist_list.php"; -$form["auth"] = 'yes'; // yes / no - -$form["auth_preset"]["userid"] = 0; // 0 = id of the user, > 0 id must match with id of current user -$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user -$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete -$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete -$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete - -$form["tabs"]['mailinglist'] = array ( - 'title' => "Mailing List", - 'width' => 100, - 'template' => "templates/mail_mailinglist_edit.htm", - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'server_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT server_id,server_name FROM server WHERE mail_server = 1 AND mirror_server_id = 0 AND {AUTHSQL} ORDER BY server_name', - 'keyfield'=> 'server_id', - 'valuefield'=> 'server_name' - ), - 'value' => '' - ), - 'domain' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'filters' => array( 0 => array( 'event' => 'SAVE', - 'type' => 'IDNTOASCII'), - 1 => array( 'event' => 'SHOW', - 'type' => 'IDNTOUTF8'), - 2 => array( 'event' => 'SAVE', - 'type' => 'TOLOWER') - ), - 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', - 'errmsg'=> 'domain_error_empty'), - 1 => array ( 'type' => 'REGEX', - 'regex' => '/^[\w\.\-]{2,255}\.[a-zA-Z\-]{2,10}$/', - 'errmsg'=> 'domain_error_regex'), - ), - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 2 - ), - 'listname' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'NOTEMPTY', - 'errmsg'=> 'listname_error_empty'), - 1 => array ( 'type' => 'UNIQUE', - 'errmsg'=> 'listname_error_unique'), - ), - 'filters' => array( - 0 => array( 'event' => 'SAVE', - 'type' => 'STRIPTAGS'), - 1 => array( 'event' => 'SAVE', - 'type' => 'STRIPNL') - ), - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 1 - ), - 'email' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'filters' => array( 0 => array( 'event' => 'SAVE', - 'type' => 'IDNTOASCII'), - 1 => array( 'event' => 'SHOW', - 'type' => 'IDNTOUTF8'), - 2 => array( 'event' => 'SAVE', - 'type' => 'TOLOWER') - ), - 'validators' => array ( 0 => array ( 'type' => 'ISEMAIL', - 'errmsg'=> 'email_error_isemail'), - ), - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 2 - ), - 'password' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'PASSWORD', - 'validators' => array( - 0 => array( - 'type' => 'CUSTOM', - 'class' => 'validate_password', - 'function' => 'password_check', - 'errmsg' => 'weak_password_txt' - ) - ), - 'encryption'=> 'CLEARTEXT', - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255' - ), - //################################# - // ENDE Datatable fields - //################################# - ) -); - diff --git a/interface/web/mail/form/mail_ml_membership.tform.php b/interface/web/mail/form/mail_ml_membership.tform.php deleted file mode 100755 index 4a1832d3d..000000000 --- a/interface/web/mail/form/mail_ml_membership.tform.php +++ /dev/null @@ -1,131 +0,0 @@ -uses('getconf'); -$mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; - -$form["title"] = "Mailing List"; -$form["description"] = ""; -$form["name"] = "mail_ml_membership"; -$form["action"] = "mail_ml_membership_edit.php"; -$form["db_table"] = "mail_ml_membership"; -$form["db_table_idx"] = "subscriber_id"; -$form["db_history"] = "yes"; -$form["tab_default"] = "membership"; -$form["list_default"] = "mail_ml_membership_list.php"; -$form["auth"] = 'yes'; // yes / no - -$form["auth_preset"]["userid"] = 0; // 0 = id of the user, > 0 id must match with id of current user -$form["auth_preset"]["groupid"] = 0; // 0 = default groupid of the user, > 0 id must match with groupid of current user -$form["auth_preset"]["perm_user"] = 'riud'; //r = read, i = insert, u = update, d = delete -$form["auth_preset"]["perm_group"] = 'riud'; //r = read, i = insert, u = update, d = delete -$form["auth_preset"]["perm_other"] = ''; //r = read, i = insert, u = update, d = delete - -$form["tabs"]['membership'] = array ( - 'title' => "Membership", - 'width' => 100, - 'template' => "templates/mail_ml_membership_edit.htm", - 'fields' => array ( - 'server_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT server_id,server_name FROM server WHERE mail_server = 1 AND mirror_server_id = 0 AND {AUTHSQL} ORDER BY server_name', - 'keyfield'=> 'server_id', - 'valuefield'=> 'server_name' - ), - 'value' => '' - ), - 'mailinglist_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT mailinglist_id, CONCAT_WS(\'@\', listname, domain) as listname FROM mail_mailinglist WHERE {AUTHSQL} ORDER BY listname', - 'keyfield'=> 'mailinglist_id', - 'valuefield'=> 'listname' - ), - 'value' => '' - ), - 'email' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'filters' => array( 0 => array( 'event' => 'SAVE', - 'type' => 'IDNTOASCII'), - 1 => array( 'event' => 'SHOW', - 'type' => 'IDNTOUTF8'), - 2 => array( 'event' => 'SAVE', - 'type' => 'TOLOWER') - ), - 'validators' => array ( 0 => array ( 'type' => 'ISEMAIL', - 'errmsg'=> 'email_error_isemail'), - 1 => array ( 'type' => 'UNIQUE', - 'errmsg'=> 'email_error_unique'), - ), - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 1 - ), - 'name' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'TEXT', - 'default' => '', - 'value' => '', - 'width' => '30', - 'maxlength' => '255', - 'searchable' => 2 - ), - 'welcome_msg' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'y', - 'value' => array(0 => 'n', 1 => 'y') - ), - 'goodbye_msg' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'n', - 'value' => array(0 => 'n', 1 => 'y') - ), - ), -); \ No newline at end of file diff --git a/interface/web/mail/lib/module.conf.php b/interface/web/mail/lib/module.conf.php index eaed5de89..1744b5c8a 100644 --- a/interface/web/mail/lib/module.conf.php +++ b/interface/web/mail/lib/module.conf.php @@ -76,26 +76,6 @@ if(count($items) && $app->system->has_service($userid, 'mail')) 'items' => $items); } -//**** Mailinglist menu -$items = array(); - -if($app->auth->get_client_limit($userid, 'mailmailinglist') != 0) -{ - $items[] = array( 'title' => 'Mailing List', - 'target' => 'content', - 'link' => 'mail/mail_mailinglist_list.php', - 'html_id' => 'mail_mailinglist_list'); - - $mlManager = $app->getconf->get_server_config($conf['server_id'], 'mail')['mailinglist_manager']; -} - -if(count($items) && $app->system->has_service($userid, 'mail')) -{ - $module['nav'][] = array( 'title' => 'Mailing List', - 'open' => 1, - 'items' => $items); -} - //**** Spamfilter menu $items = array(); diff --git a/interface/web/mail/lib/remote.conf.php b/interface/web/mail/lib/remote.conf.php index a0249d0a3..cec57655a 100644 --- a/interface/web/mail/lib/remote.conf.php +++ b/interface/web/mail/lib/remote.conf.php @@ -2,7 +2,6 @@ $function_list['mail_domain_get,mail_domain_add,mail_domain_update,mail_domain_delete,mail_domain_set_status,mail_domain_get_by_domain'] = 'Mail domain functions'; $function_list['mail_aliasdomain_get,mail_aliasdomain_add,mail_aliasdomain_update,mail_aliasdomain_delete'] = 'Mail domain alias functions'; -$function_list['mail_mailinglist_get,mail_mailinglist_add,mail_mailinglist_update,mail_mailinglist_delete'] = 'Mail mailinglist functions'; $function_list['mail_user_get,mail_user_add,mail_user_update,mail_user_delete'] = 'Mail user functions'; $function_list['mail_alias_get,mail_alias_add,mail_alias_update,mail_alias_delete'] = 'Mail alias functions'; $function_list['mail_forward_get,mail_forward_add,mail_forward_update,mail_forward_delete'] = 'Mail forward functions'; diff --git a/interface/web/mail/list/mail_mailinglist.list.php b/interface/web/mail/list/mail_mailinglist.list.php deleted file mode 100644 index b72a9ec7b..000000000 --- a/interface/web/mail/list/mail_mailinglist.list.php +++ /dev/null @@ -1,70 +0,0 @@ - "listname", - 'datatype' => "VARCHAR", - 'formtype' => "TEXT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", - 'width' => "", - 'value' => ""); - -$liste["item"][] = array( 'field' => "domain", - 'datatype' => "VARCHAR", - 'filters' => array( 0 => array( 'event' => 'SHOW', - 'type' => 'IDNTOUTF8') - ), - 'formtype' => "TEXT", - 'op' => "like", - 'prefix' => "%", - 'suffix' => "%", - 'width' => "", - 'value' => ""); - -?> diff --git a/interface/web/mail/mail_domain_del.php b/interface/web/mail/mail_domain_del.php index bce89695d..671d135e4 100644 --- a/interface/web/mail/mail_domain_del.php +++ b/interface/web/mail/mail_domain_del.php @@ -83,12 +83,6 @@ class page_action extends tform_actions { $app->db->datalogDelete('spamfilter_users', 'id', $rec['id']); } - // Delete all mailinglists that belong to this domain - $records = $app->db->queryAllRecords("SELECT mailinglist_id FROM mail_mailinglist WHERE domain = ?", $domain); - foreach($records as $rec) { - $app->db->datalogDelete('mail_mailinglist', 'mailinglist_id', $rec['id']); - } - } } diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index 4d7b7d8d3..5cb947ab2 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -414,9 +414,6 @@ class page_action extends tform_actions { } } - //* Update the mailinglist - $app->db->query("UPDATE mail_mailinglist SET sys_userid = ?, sys_groupid = ? WHERE domain = ?", $client_user_id, $sys_groupid, $this->oldDataRecord['domain']); - //* Update fetchmail accounts $fetchmail = $app->db->queryAllRecords("SELECT * FROM mail_get WHERE destination like ?", '%@' . $this->oldDataRecord['domain']); if(is_array($fetchmail)) { diff --git a/interface/web/mail/mail_mailinglist_del.php b/interface/web/mail/mail_mailinglist_del.php deleted file mode 100644 index 2782ec560..000000000 --- a/interface/web/mail/mail_mailinglist_del.php +++ /dev/null @@ -1,58 +0,0 @@ -auth->check_module_permissions('mail'); - -// Loading classes -$app->uses('tpl,tform,tform_actions'); -$app->load('tform_actions'); - -class page_action extends tform_actions { -} - -$page = new page_action; -$page->onDelete(); - -?> diff --git a/interface/web/mail/mail_mailinglist_edit.php b/interface/web/mail/mail_mailinglist_edit.php deleted file mode 100644 index 57d9c77f2..000000000 --- a/interface/web/mail/mail_mailinglist_edit.php +++ /dev/null @@ -1,254 +0,0 @@ -auth->check_module_permissions('mail'); - -// Loading classes -$app->uses('tpl,tform,tform_actions'); -$app->load('tform_actions'); - -class page_action extends tform_actions { - - - function onShowNew() { - global $app, $conf; - - // we will check only users, not admins - if($_SESSION["s"]["user"]["typ"] == 'user') { - if(!$app->tform->checkClientLimit('limit_mailmailinglist')) { - $app->error($app->tform->wordbook["limit_mailmailinglist_txt"]); - } - if(!$app->tform->checkResellerLimit('limit_mailmailinglist')) { - $app->error('Reseller: '.$app->tform->wordbook["limit_mailmailinglist_txt"]); - } - } - - parent::onShowNew(); - } - - function onShowEnd() { - global $app, $conf; - - if($_SESSION["s"]["user"]["typ"] == 'admin') { - // Getting Clients of the user - $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND sys_group.client_id > 0 ORDER BY client.company_name, client.contact_name, sys_group.name"; - $clients = $app->db->queryAllRecords($sql); - $clients = $app->functions->htmlentities($clients); - $client_select = ''; - if($_SESSION["s"]["user"]["typ"] == 'admin') $client_select .= ""; - $tmp_data_record = $app->tform->getDataRecord($this->id); - if(is_array($clients)) { - foreach( $clients as $client) { - $selected = ($client["groupid"] == $tmp_data_record["sys_groupid"])?'SELECTED':''; - $client_select .= "\r\n"; - } - } - $app->tpl->setVar("client_group_id", $client_select); - - } elseif ($_SESSION["s"]["user"]["typ"] != 'admin' && $app->auth->has_clients($_SESSION['s']['user']['userid'])) { - - // Get the limits of the client - $client_group_id = $_SESSION["s"]["user"]["default_group"]; - $client = $app->db->queryOneRecord("SELECT client.client_id, client.contact_name, client.default_mailserver, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname, sys_group.name FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ? order by contact_name", $client_group_id); - $client = $app->functions->htmlentities($client); - - // Fill the client select field - $sql = "SELECT sys_group.groupid, sys_group.name, CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as contactname FROM sys_group, client WHERE sys_group.client_id = client.client_id AND client.parent_client_id = ? ORDER BY client.company_name, client.contact_name, sys_group.name"; - $clients = $app->db->queryAllRecords($sql, $client['client_id']); - $clients = $app->functions->htmlentities($clients); - $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ?", $client['client_id']); - $client_select = ''; - $tmp_data_record = $app->tform->getDataRecord($this->id); - if(is_array($clients)) { - foreach( $clients as $client) { - $selected = @($client["groupid"] == $tmp_data_record["sys_groupid"])?'SELECTED':''; - $client_select .= "\r\n"; - } - } - $app->tpl->setVar("client_group_id", $client_select); - } - - // Getting Domains of the user - $sql = "SELECT domain FROM mail_domain WHERE ".$app->tform->getAuthSQL('r').' ORDER BY domain'; - $domains = $app->db->queryAllRecords($sql); - $domain_select = ''; - if(is_array($domains)) { - foreach( $domains as $domain) { - $selected = ($domain["domain"] == $this->dataRecord["domain"])?'SELECTED':''; - $domain_select .= "\r\n"; - } - } - $app->tpl->setVar("domain_option", $domain_select); - - if($this->id > 0) { - //* we are editing a existing record - $app->tpl->setVar("edit_disabled", 1); - $app->tpl->setVar("listname_value", $this->dataRecord["listname"], true); - $app->tpl->setVar("domain_value", $this->dataRecord["domain"], true); - $app->tpl->setVar("email_value", $this->dataRecord["email"], true); - } else { - $app->tpl->setVar("edit_disabled", 0); - } - - parent::onShowEnd(); - } - - function onSubmit() { - global $app, $conf; - - if($_SESSION["s"]["user"]["typ"] != 'admin') { - - // Get the limits of the client - $client_group_id = intval($_SESSION["s"]["user"]["default_group"]); - $client = $app->db->queryOneRecord("SELECT limit_mailmailinglist, default_mailserver FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = ?", $client_group_id); - - //* Check if Domain belongs to user - if(isset($_POST["domain"])) { - $domain = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain = ? AND ".$app->tform->getAuthSQL('r'), $this->dataRecord["domain"]); - if($domain["domain"] != $this->dataRecord["domain"]) $app->tform->errorMessage .= $app->tform->lng("no_domain_perm"); - } - - // When the record is updated - if($this->id == 0) { - //Check if email is in use - $check = $app->db->queryOneRecord("SELECT count(source) as number FROM mail_forwarding WHERE source = ?", $this->dataRecord["listname"]."@".$this->dataRecord["domain"]); - if($check['number'] != 0) { - $app->error($app->tform->wordbook["email_in_use_txt"]); - } - - $check = $app->db->queryOneRecord("SELECT count(email) as number FROM mail_user WHERE email = ?", $this->dataRecord["listname"]."@".$this->dataRecord["domain"]); - if($check['number'] != 0) { - $app->error($app->tform->wordbook["email_in_use_txt"]); - } - - $check = $app->db->queryOneRecord("SELECT count(mailinglist_id) as number FROM mail_mailinglist WHERE listname = ? AND domain = ?", $this->dataRecord["listname"], $this->dataRecord["domain"]); - if($check['number'] != 0) { - $app->error($app->tform->wordbook["email_in_use_txt"]); - } - - // Check if the user may add another mail_domain - if($client["limit_mailmailinglist"] >= 0) { - $tmp = $app->db->queryOneRecord("SELECT count(mailinglist_id) as number FROM mail_mailinglist WHERE sys_groupid = ?", $client_group_id); - if($tmp["number"] >= $client["limit_mailmailinglist"]) { - $app->error($app->tform->wordbook["limit_mailmailinglist_txt"]); - } - } - } - - // Clients may not set the client_group_id, so we unset them if user is not a admin - if(!$app->auth->has_clients($_SESSION['s']['user']['userid'])) unset($this->dataRecord["client_group_id"]); - } - - //* make sure that the email domain is lowercase - if(isset($this->dataRecord["domain"])) $this->dataRecord["domain"] = strtolower($this->dataRecord["domain"]); - - parent::onSubmit(); - } - - function onBeforeInsert() { - global $app, $conf; - - // Set the server id of the mailinglist = server ID of mail domain. - $domain = $app->db->queryOneRecord("SELECT server_id FROM mail_domain WHERE domain = ?", $this->dataRecord["domain"]); - $this->dataRecord["server_id"] = $domain['server_id']; - } - - function onAfterInsert() { - global $app, $conf; - - // make sure that the record belongs to the client group and not the admin group when a dmin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE mail_mailinglist SET sys_groupid = ?, sys_perm_group = 'ru' WHERE mailinglist_id = ?", $client_group_id, $this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE mail_mailinglist SET sys_groupid = ?, sys_perm_group = 'riud' WHERE mailinglist_id = ?", $client_group_id, $this->id); - } - } - - function onBeforeUpdate() { - global $app, $conf; - - //* Check if the server has been changed - // We do this only for the admin or reseller users, as normal clients can not change the server ID anyway - if($_SESSION["s"]["user"]["typ"] == 'admin' || $app->auth->has_clients($_SESSION['s']['user']['userid'])) { - $rec = $app->db->queryOneRecord("SELECT server_id, domain from mail_mailinglist WHERE mailinglist_id = ?", $this->id); - $this->dataRecord["server_id"] = $rec['server_id']; - unset($rec); - //* If the user is neither admin nor reseller - } else { - //* We do not allow users to change a domain which has been created by the admin - $rec = $app->db->queryOneRecord("SELECT domain from mail_mailinglist WHERE mailinglist_id = ?", $this->id); - if($rec['domain'] != $this->dataRecord["domain"] && $app->tform->checkPerm($this->id, 'u')) { - //* Add a error message and switch back to old server - $app->tform->errorMessage .= $app->lng('The Domain can not be changed. Please ask your Administrator if you want to change the domain name.'); - $this->dataRecord["domain"] = $rec['domain']; - } - unset($rec); - } - } - - function onAfterUpdate() { - global $app, $conf; - - // make sure that the record belongs to the clinet group and not the admin group when admin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE mail_mailinglist SET sys_groupid = ?, sys_perm_group = 'ru' WHERE mailinglist_id = ?", $client_group_id, $this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE mail_mailinglist SET sys_groupid = ?, sys_perm_group = 'riud' WHERE mailinglist_id = ?", $client_group_id, $this->id); - } - } - -} - -$app->tform_actions = new page_action; -$app->tform_actions->onLoad(); - -?> diff --git a/interface/web/mail/mail_mailinglist_list.php b/interface/web/mail/mail_mailinglist_list.php deleted file mode 100644 index e1e2daf91..000000000 --- a/interface/web/mail/mail_mailinglist_list.php +++ /dev/null @@ -1,44 +0,0 @@ -auth->check_module_permissions('mail'); - -$app->load('listform_actions'); - - -class list_action extends listform_actions { - - function onShow() { - global $app, $conf; - - $app->uses('getconf'); - $global_config = $app->getconf->get_global_config('mail'); - - if($global_config['mailmailinglist_link'] == 'y') { - $app->tpl->setVar('mailmailinglist_link', 1); - } else { - $app->tpl->setVar('mailmailinglist_link', 0); - } - - parent::onShow(); - } - -} - -$list = new list_action; -$list->onLoad(); - - -?> diff --git a/interface/web/mail/mailinglist.php b/interface/web/mail/mailinglist.php deleted file mode 100644 index 15f61c939..000000000 --- a/interface/web/mail/mailinglist.php +++ /dev/null @@ -1,68 +0,0 @@ -auth->check_module_permissions('mail'); - -/* get the id of the mail (must be int!) */ -if (!isset($_GET['id'])){ - die ("No List selected!"); -} -$listId = $app->functions->intval($_GET['id']); - -/* - * Get the data to connect to the database - */ -$dbData = $app->db->queryAllRecords("SELECT server_id, listname FROM mail_mailinglist WHERE mailinglist_id = ?", $listId); -$serverId = $app->functions->intval($dbData[0]['server_id']); -if ($serverId == 0){ - die ("No List - Server found!"); -} - -$serverData = $app->db->queryOneRecord("SELECT server_name FROM server WHERE server_id = ?", $serverId); - -$app->uses('getconf'); -$global_config = $app->getconf->get_global_config('mail'); - -if($global_config['mailmailinglist_url'] != '') { - header('Location:' . $global_config['mailmailinglist_url']); -} else { - - /* - * We only redirect to the login-form, so there is no need, to check any rights - */ - isset($_SERVER['HTTPS'])? $http = 'https' : $http = 'http'; - header('Location:' . $http . '://' . $serverData['server_name'] . '/cgi-bin/mailman/admin/' . $dbData[0]['listname']); -} -exit; -?> diff --git a/interface/web/mail/templates/mail_mailinglist_edit.htm b/interface/web/mail/templates/mail_mailinglist_edit.htm deleted file mode 100644 index 8b35adda7..000000000 --- a/interface/web/mail/templates/mail_mailinglist_edit.htm +++ /dev/null @@ -1,101 +0,0 @@ - -

- - - -
- -
-
-
- - -
- -
-
-
- - - -
- -
-
- - @ -
- -
-
- -
-
- -
- -
-
- - - -
- -
-
- - @ -
- -
-
-
-
-
- -
-
- - -
- -
-
- - - - -
-
-
-
- -
-
-   -
-
-
- -
-
-
-
- - -
-
-
- - - -
- - -
\ No newline at end of file diff --git a/interface/web/mail/templates/mail_mailinglist_list.htm b/interface/web/mail/templates/mail_mailinglist_list.htm deleted file mode 100644 index 7e15df3aa..000000000 --- a/interface/web/mail/templates/mail_mailinglist_list.htm +++ /dev/null @@ -1,73 +0,0 @@ - - - - -
-
-
-
- {tmpl_var name="datalog_changes_txt"} -
    - -
  • {tmpl_var name="text"}: {tmpl_var name="count"}
  • -
    -
- {tmpl_var name="datalog_changes_end_txt"} -
-

-
-
-

{tmpl_var name="toolsarea_head_txt"}

- - - - - - -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{tmpl_var name='search_limit'}
- -
{tmpl_var name="listname"}{tmpl_var name="domain"} - - - - -
{tmpl_var name='globalsearch_noresults_text_txt'}
-
- - \ No newline at end of file diff --git a/interface/web/mail/templates/mail_ml_membership_edit.htm b/interface/web/mail/templates/mail_ml_membership_edit.htm deleted file mode 100644 index bc45027ed..000000000 --- a/interface/web/mail/templates/mail_ml_membership_edit.htm +++ /dev/null @@ -1,64 +0,0 @@ - -

- - -
- -
- -
-
- -
- -
-
  {tmpl_var name='name_optional_txt'}
-
-
- -
- -
-
-
- -
- {tmpl_var name='goodbye_msg'} -
-
- -
- -
-
-
- -
- -
-
  {tmpl_var name='name_optional_txt'}
-
-
- -
- -
-
-
- -
- {tmpl_var name='welcome_msg'} -
-
-
- - - -
- - -
\ No newline at end of file diff --git a/interface/web/mail/templates/mail_ml_membership_list.htm b/interface/web/mail/templates/mail_ml_membership_list.htm deleted file mode 100644 index 9142179bc..000000000 --- a/interface/web/mail/templates/mail_ml_membership_list.htm +++ /dev/null @@ -1,75 +0,0 @@ - -

- - - -
-
-
-
- {tmpl_var name="datalog_changes_txt"} -
    - -
  • {tmpl_var name="text"}: {tmpl_var name="count"}
  • -
    -
- {tmpl_var name="datalog_changes_end_txt"} -
-

-
-
-

{tmpl_var name="toolsarea_head_txt"}

- - - - - - -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{tmpl_var name='search_limit'}
  - -
{tmpl_var name="mailinglist_id"}{tmpl_var name="email"}{tmpl_var name="name"}{tmpl_var name="goodbye_msg"} - -
{tmpl_var name='globalsearch_noresults_text_txt'}
-
diff --git a/interface/web/tools/import_vpopmail.php b/interface/web/tools/import_vpopmail.php index d95e405a2..4e572e796 100644 --- a/interface/web/tools/import_vpopmail.php +++ b/interface/web/tools/import_vpopmail.php @@ -110,8 +110,8 @@ function start_import() { $country = 'FI'; //* add client - $sql = "INSERT INTO `client` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `company_name`, `company_id`, `contact_name`, `customer_no`, `vat_id`, `street`, `zip`, `city`, `state`, `country`, `telephone`, `mobile`, `fax`, `email`, `internet`, `icq`, `notes`, `bank_account_owner`, `bank_account_number`, `bank_code`, `bank_name`, `bank_account_iban`, `bank_account_swift`, `default_mailserver`, `limit_maildomain`, `limit_mailbox`, `limit_mailalias`, `limit_mailaliasdomain`, `limit_mailforward`, `limit_mailcatchall`, `limit_mailrouting`, `limit_mailfilter`, `limit_fetchmail`, `limit_mailquota`, `limit_spamfilter_wblist`, `limit_spamfilter_user`, `limit_spamfilter_policy`, `default_webserver`, `limit_web_ip`, `limit_web_domain`, `limit_web_quota`, `web_php_options`, `limit_cgi`, `limit_ssi`, `limit_perl`, `limit_ruby`, `limit_python`, `force_suexec`, `limit_hterror`, `limit_wildcard`, `limit_ssl`, `limit_web_subdomain`, `limit_web_aliasdomain`, `limit_ftp_user`, `limit_shell_user`, `ssh_chroot`, `limit_webdav_user`, `limit_aps`, `default_dnsserver`, `limit_dns_zone`, `limit_dns_slave_zone`, `limit_dns_record`, `default_dbserver`, `limit_database`, `limit_cron`, `limit_cron_type`, `limit_cron_frequency`, `limit_traffic_quota`, `limit_client`, `limit_mailmailinglist`, `limit_openvz_vm`, `limit_openvz_vm_template_id`, `parent_client_id`, `username`, `password`, `language`, `usertheme`, `template_master`, `template_additional`, `created_at`, `id_rsa`, `ssh_rsa`) - VALUES(1, 1, 'riud', 'riud', '', '', '', ?, '', '', '', '', '', '', ?, '', '', '', '', 'http://', '', '', '', '', '', '', '', '', 1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1, NULL, -1, -1, 'no,fast-cgi,mod', 'n', 'n', 'n', 'n', 'n', 'y', 'n', 'n', 'n', -1, -1, -1, 0, 'no,jailkit', 0, 0, 1, -1, -1, -1, 1, -1, 0, 'url', 5, -1, 0, -1, 0, 0, 0, ?, ?, ?, 'default', 0, '', NOW(), '', '')"; + $sql = "INSERT INTO `client` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `company_name`, `company_id`, `contact_name`, `customer_no`, `vat_id`, `street`, `zip`, `city`, `state`, `country`, `telephone`, `mobile`, `fax`, `email`, `internet`, `icq`, `notes`, `bank_account_owner`, `bank_account_number`, `bank_code`, `bank_name`, `bank_account_iban`, `bank_account_swift`, `default_mailserver`, `limit_maildomain`, `limit_mailbox`, `limit_mailalias`, `limit_mailaliasdomain`, `limit_mailforward`, `limit_mailcatchall`, `limit_mailrouting`, `limit_mailfilter`, `limit_fetchmail`, `limit_mailquota`, `limit_spamfilter_wblist`, `limit_spamfilter_user`, `limit_spamfilter_policy`, `default_webserver`, `limit_web_ip`, `limit_web_domain`, `limit_web_quota`, `web_php_options`, `limit_cgi`, `limit_ssi`, `limit_perl`, `limit_ruby`, `limit_python`, `force_suexec`, `limit_hterror`, `limit_wildcard`, `limit_ssl`, `limit_web_subdomain`, `limit_web_aliasdomain`, `limit_ftp_user`, `limit_shell_user`, `ssh_chroot`, `limit_webdav_user`, `limit_aps`, `default_dnsserver`, `limit_dns_zone`, `limit_dns_slave_zone`, `limit_dns_record`, `default_dbserver`, `limit_database`, `limit_cron`, `limit_cron_type`, `limit_cron_frequency`, `limit_traffic_quota`, `limit_client`, `limit_openvz_vm`, `limit_openvz_vm_template_id`, `parent_client_id`, `username`, `password`, `language`, `usertheme`, `template_master`, `template_additional`, `created_at`, `id_rsa`, `ssh_rsa`) + VALUES(1, 1, 'riud', 'riud', '', '', '', ?, '', '', '', '', '', '', ?, '', '', '', '', 'http://', '', '', '', '', '', '', '', '', 1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, 0, 0, 0, 1, NULL, -1, -1, 'no,fast-cgi,mod', 'n', 'n', 'n', 'n', 'n', 'y', 'n', 'n', 'n', -1, -1, -1, 0, 'no,jailkit', 0, 0, 1, -1, -1, -1, 1, -1, 0, 'url', 5, -1, 0, 0, 0, 0, ?, ?, ?, 'default', 0, '', NOW(), '', '')"; $app->db->query($sql, $pw_domain,$country, $pw_domain, $pw_crypt_password, $conf['language']); $client_id = $app->db->insertID(); diff --git a/interface/web/tools/resync.php b/interface/web/tools/resync.php index e5958c064..658750b5d 100644 --- a/interface/web/tools/resync.php +++ b/interface/web/tools/resync.php @@ -103,11 +103,6 @@ class page_action extends tform_actions { 'server_type' => 'mail', 'server_id' => $server_id, ), - 'mail_mailinglist' => array ( - 'index_field' => 'mailinglist_id', - 'server_type' => 'mail', - 'server_id' => $server_id, - ), 'mail_user' => array ( 'index_field' => 'mailuser_id', 'server_type' => 'mail', @@ -291,17 +286,6 @@ class page_action extends tform_actions { unset($options_servers); } - //* mailinglist - $server_list = $this->create_list($mail_server_rec, 'mail', 'mail_mailinglist'); - $options_servers = $server_list[0];$server_count = $server_list[1]; - unset($server_list); - if (isset($options_servers)) { //* server with data found - if ($server_count > 1) $options_servers = "" . $options_servers; - $app->tpl->setVar('mailinglist_server_id', $options_servers); - $app->tpl->setVar('mailinglist_found', 1); - unset($options_servers); - } - //* mailtransport $server_list = $this->create_list($mail_server_rec, 'mail', 'mail_transport'); $options_servers = $server_list[0];$server_count = $server_list[1]; @@ -511,7 +495,6 @@ class page_action extends tform_actions { $this->dataRecord['resync_mailget'] = 1; $this->dataRecord['resync_mailbox'] = 1; $this->dataRecord['resync_mailfilter'] = 1; - $this->dataRecord['resync_mailinglist'] = 1; $this->dataRecord['resync_mailtransport'] = 1; $this->dataRecord['resync_mailrelay'] = 1; $this->dataRecord['resync_vserver'] = 1; @@ -582,10 +565,6 @@ class page_action extends tform_actions { $msg .= $this->do_resync('spamfilter_wblist', 'wblist_id', 'mail', $this->dataRecord['mailbox_server_id'], '', $app->tform->wordbook['do_mail_spamfilter_txt']) ; } - //* mailinglists - if($this->dataRecord['resync_mailinglist'] == 1) - $msg .= $this->do_resync('mail_mailinglist', 'mailinglist_id', 'mail', $this->dataRecord['mail_server_id'], 'listname', $app->tform->wordbook['do_mailinglist_txt'], false); - //* mailtransport if($this->dataRecord['resync_mailtransport'] == 1) $msg .= $this->do_resync('mail_transport', 'transport_id', 'mail', $this->dataRecord['mail_server_id'], 'domain', $app->tform->wordbook['do_mailtransport_txt'], false); diff --git a/interface/web/tools/templates/resync.htm b/interface/web/tools/templates/resync.htm index 3e66290fb..646c96057 100644 --- a/interface/web/tools/templates/resync.htm +++ b/interface/web/tools/templates/resync.htm @@ -89,13 +89,6 @@
- -
- -
-
-
-
diff --git a/remoting_client/examples/mail_mailinglist_add.php b/remoting_client/examples/mail_mailinglist_add.php deleted file mode 100644 index 3d6cd568a..000000000 --- a/remoting_client/examples/mail_mailinglist_add.php +++ /dev/null @@ -1,41 +0,0 @@ - $soap_location, - 'uri' => $soap_uri, - 'trace' => 1, - 'exceptions' => 1)); - - -try { - if($session_id = $client->login($username, $password)) { - echo 'Logged successfull. Session ID:'.$session_id.'
'; - } - - //* Set the function parameters. - $client_id = 1; - $params = array( - 'server_id' => 1, - 'domain' => 'test.int', - 'listname' => 'work', - 'email' => 'hmmnoe@test.int', - 'password' => 'hmmyea' - ); - - $mailinglist_id = $client->mail_mailinglist_add($session_id, $client_id, $params); - - echo "Mailinglist ID: ".$mailinglist_id."
"; - - if($client->logout($session_id)) { - echo 'Logged out.
'; - } - - -} catch (SoapFault $e) { - echo $client->__getLastResponse(); - die('SOAP Error: '.$e->getMessage()); -} - -?> diff --git a/remoting_client/examples/mail_mailinglist_delete.php b/remoting_client/examples/mail_mailinglist_delete.php deleted file mode 100644 index cf76336f2..000000000 --- a/remoting_client/examples/mail_mailinglist_delete.php +++ /dev/null @@ -1,36 +0,0 @@ - $soap_location, - 'uri' => $soap_uri, - 'trace' => 1, - 'exceptions' => 1)); - - -try { - if($session_id = $client->login($username, $password)) { - echo 'Logged successfull. Session ID:'.$session_id.'
'; - } - - //* Parameters - $mailinglist_id = 1; - - - //* Delete the email mailinglist record - $affected_rows = $client->mail_mailinglist_delete($session_id, $mailinglist_id); - - echo "Number of records that have been deleted: ".$affected_rows."
"; - - if($client->logout($session_id)) { - echo 'Logged out.
'; - } - - -} catch (SoapFault $e) { - echo $client->__getLastResponse(); - die('SOAP Error: '.$e->getMessage()); -} - -?> diff --git a/remoting_client/examples/mail_mailinglist_get.php b/remoting_client/examples/mail_mailinglist_get.php deleted file mode 100644 index 7affe57a1..000000000 --- a/remoting_client/examples/mail_mailinglist_get.php +++ /dev/null @@ -1,34 +0,0 @@ - $soap_location, - 'uri' => $soap_uri, - 'trace' => 1, - 'exceptions' => 1)); - - -try { - if($session_id = $client->login($username, $password)) { - echo 'Logged successfull. Session ID:'.$session_id.'
'; - } - - //* Set the function parameters. - $mailinglist_id = 1; - - $mailinglist_record = $client->mail_mailinglist_get($session_id, $mailinglist_id); - - print_r($mailinglist_record); - - if($client->logout($session_id)) { - echo 'Logged out.
'; - } - - -} catch (SoapFault $e) { - echo $client->__getLastResponse(); - die('SOAP Error: '.$e->getMessage()); -} - -?> diff --git a/remoting_client/examples/mail_mailinglist_update.php b/remoting_client/examples/mail_mailinglist_update.php deleted file mode 100644 index c7d6216c1..000000000 --- a/remoting_client/examples/mail_mailinglist_update.php +++ /dev/null @@ -1,42 +0,0 @@ - $soap_location, - 'uri' => $soap_uri, - 'trace' => 1, - 'exceptions' => 1)); - - -try { - if($session_id = $client->login($username, $password)) { - echo 'Logged successfull. Session ID:'.$session_id.'
'; - } - - //* Parameters - $mailinglist_id = 1; - $client_id = 1; - - - //* Get the email mailinglist record - $mailinglist_record = $client->mail_mailinglist_get($session_id, $mailinglist_id); - - //* Change the listname to home - $mailinglist_record['listname'] = 'home'; - - $affected_rows = $client->mail_mailinglist_update($session_id, $client_id, $mailinglist_id, $mailinglist_record); - - echo "Number of records that have been changed in the database: ".$affected_rows."
"; - - if($client->logout($session_id)) { - echo 'Logged out.
'; - } - - -} catch (SoapFault $e) { - echo $client->__getLastResponse(); - die('SOAP Error: '.$e->getMessage()); -} - -?> diff --git a/server/conf/apache_ispconfig.conf.master b/server/conf/apache_ispconfig.conf.master index ab85fd22a..5fb618c13 100644 --- a/server/conf/apache_ispconfig.conf.master +++ b/server/conf/apache_ispconfig.conf.master @@ -58,20 +58,6 @@ CustomLog "| /usr/local/ispconfig/server/scripts/vlogger -s access.log -t \"%Y%m Require all granted -# Allow access to mailman on OpenSuSE - - Require all granted - - - - Require all granted - - - - Options +FollowSymLinks - Require all granted - - # allow path to awstats and alias for awstats icons Require all granted diff --git a/server/conf/mm_cfg.py.master b/server/conf/mm_cfg.py.master deleted file mode 100644 index f57b76ad1..000000000 --- a/server/conf/mm_cfg.py.master +++ /dev/null @@ -1,108 +0,0 @@ -# -*- python -*- - -# Copyright (C) 1998,1999,2000 by the Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301 USA - - -"""This is the module which takes your site-specific settings. - -From a raw distribution it should be copied to mm_cfg.py. If you -already have an mm_cfg.py, be careful to add in only the new settings -you want. The complete set of distributed defaults, with annotation, -are in ./Defaults. In mm_cfg, override only those you want to -change, after the - - from Defaults import * - -line (see below). - -Note that these are just default settings - many can be overridden via the -admin and user interfaces on a per-list or per-user basis. - -Note also that some of the settings are resolved against the active list -setting by using the value as a format string against the -list-instance-object's dictionary - see the distributed value of -DEFAULT_MSG_FOOTER for an example.""" - - -####################################################### -# Here's where we get the distributed defaults. # - -from Defaults import * - -############################################################## -# Put YOUR site-specific configuration below, in mm_cfg.py . # -# See Defaults.py for explanations of the values. # - -#------------------------------------------------------------- -# The name of the list Mailman uses to send password reminders -# and similar. Don't change if you want mailman-owner to be -# a valid local part. -MAILMAN_SITE_LIST = 'mailman' - -#------------------------------------------------------------- -# If you change these, you have to configure your http server -# accordingly (Alias and ScriptAlias directives in most httpds) -DEFAULT_URL_PATTERN = 'https://%s/cgi-bin/mailman/' -PRIVATE_ARCHIVE_URL = '/cgi-bin/mailman/private' -IMAGE_LOGOS = '/images/mailman/' - -#------------------------------------------------------------- -# Default domain for email addresses of newly created MLs -DEFAULT_EMAIL_HOST = '{hostname}' -#------------------------------------------------------------- -# Default host for web interface of newly created MLs -DEFAULT_URL_HOST = '{hostname}' -#------------------------------------------------------------- -# Required when setting any of its arguments. -add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST) - -#------------------------------------------------------------- -# The default language for this server. -DEFAULT_SERVER_LANGUAGE = {default_language} - -#------------------------------------------------------------- -# Iirc this was used in pre 2.1, leave it for now -USE_ENVELOPE_SENDER = 0 # Still used? - -#------------------------------------------------------------- -# Unset send_reminders on newly created lists -DEFAULT_SEND_REMINDERS = 0 - -#------------------------------------------------------------- -# Uncomment this if you configured your MTA such that it -# automatically recognizes newly created lists. -# (see /usr/share/doc/mailman/README.Exim4.Debian or -# /usr/share/mailman/postfix-to-mailman.py) -# MTA=None # Misnomer, suppresses alias output on newlist - -#------------------------------------------------------------- -# Uncomment if you use Postfix virtual domains (but not -# postfix-to-mailman.py), but be sure to see -# /usr/share/doc/mailman/README.Debian first. -MTA='Postfix' -POSTFIX_STYLE_VIRTUAL_DOMAINS = [{virtual_domains}] -#------------------------------------------------------------- -# Uncomment if you want to filter mail with SpamAssassin. For -# more information please visit this website: -# http://www.jamesh.id.au/articles/mailman-spamassassin/ -# GLOBAL_PIPELINE.insert(1, 'SpamAssassin') - -POSTFIX_MAP_CMD = '/etc/mailman/virtual_to_transport.sh' - -# Note - if you're looking for something that is imported from mm_cfg, but you -# didn't find it above, it's probably in /usr/lib/mailman/Mailman/Defaults.py. diff --git a/server/conf/nginx_apps.vhost.master b/server/conf/nginx_apps.vhost.master index 4003254a2..d89faeaa9 100644 --- a/server/conf/nginx_apps.vhost.master +++ b/server/conf/nginx_apps.vhost.master @@ -165,50 +165,6 @@ server { rewrite ^/* /squirrelmail last; } - location /cgi-bin/mailman { - root /usr/lib/; - fastcgi_split_path_info (^/cgi-bin/mailman/[^/]*)(.*)$; - fastcgi_param QUERY_STRING $query_string; - fastcgi_param REQUEST_METHOD $request_method; - fastcgi_param CONTENT_TYPE $content_type; - fastcgi_param CONTENT_LENGTH $content_length; - - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param SCRIPT_NAME $fastcgi_script_name; - fastcgi_param REQUEST_URI $request_uri; - fastcgi_param DOCUMENT_URI $document_uri; - fastcgi_param DOCUMENT_ROOT $document_root; - fastcgi_param SERVER_PROTOCOL $server_protocol; - - fastcgi_param GATEWAY_INTERFACE CGI/1.1; - fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; - - fastcgi_param REMOTE_ADDR $remote_addr; - fastcgi_param REMOTE_PORT $remote_port; - fastcgi_param SERVER_ADDR $server_addr; - fastcgi_param SERVER_PORT $server_port; - fastcgi_param SERVER_NAME $server_name; - - fastcgi_param HTTPS $https; - - # PHP only, required if PHP was built with --enable-force-cgi-redirect - fastcgi_param REDIRECT_STATUS 200; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - fastcgi_intercept_errors on; - fastcgi_pass unix:{cgi_socket}; - } - - location /images/mailman { - alias /usr/share/images/mailman; - } - - location /pipermail { - alias /var/lib/mailman/archives/public; - autoindex on; - } - {use_rspamd}location /rspamd/ { {use_rspamd}proxy_pass http://127.0.0.1:11334/; {use_rspamd}rewrite ^//(.*) /$1; diff --git a/server/mods-available/mail_module.inc.php b/server/mods-available/mail_module.inc.php index ffb72d68f..ded090075 100644 --- a/server/mods-available/mail_module.inc.php +++ b/server/mods-available/mail_module.inc.php @@ -53,18 +53,12 @@ class mail_module { 'mail_content_filter_insert', 'mail_content_filter_update', 'mail_content_filter_delete', - 'mail_mailinglist_insert', - 'mail_mailinglist_update', - 'mail_mailinglist_delete', 'spamfilter_users_insert', 'spamfilter_users_update', 'spamfilter_users_delete', 'spamfilter_wblist_insert', 'spamfilter_wblist_update', - 'spamfilter_wblist_delete', - 'mail_ml_member_insert', - 'mail_ml_member_update', - 'mail_ml_member_delete'); + 'spamfilter_wblist_delete'); //* This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. @@ -110,8 +104,6 @@ class mail_module { $app->modules->registerTableHook('mail_user', 'mail_module', 'process'); $app->modules->registerTableHook('mail_get', 'mail_module', 'process'); $app->modules->registerTableHook('mail_content_filter', 'mail_module', 'process'); - $app->modules->registerTableHook('mail_mailinglist', 'mail_module', 'process'); - $app->modules->registerTableHook('mail_ml_membership', 'mail_module', 'process'); $app->modules->registerTableHook('spamfilter_users', 'mail_module', 'process'); $app->modules->registerTableHook('spamfilter_wblist', 'mail_module', 'process'); @@ -163,16 +155,6 @@ class mail_module { if($action == 'u') $app->plugins->raiseEvent('mail_content_filter_update', $data); if($action == 'd') $app->plugins->raiseEvent('mail_content_filter_delete', $data); break; - case 'mail_mailinglist': - if($action == 'i') $app->plugins->raiseEvent('mail_mailinglist_insert', $data); - if($action == 'u') $app->plugins->raiseEvent('mail_mailinglist_update', $data); - if($action == 'd') $app->plugins->raiseEvent('mail_mailinglist_delete', $data); - break; - case 'mail_ml_membership': - if($action == 'i') $app->plugins->raiseEvent('mail_ml_member_insert', $data); - if($action == 'u') $app->plugins->raiseEvent('mail_ml_member_update', $data); - if($action == 'd') $app->plugins->raiseEvent('mail_ml_member_delete', $data); - break; case 'spamfilter_users': if($action == 'i') $app->plugins->raiseEvent('spamfilter_users_insert', $data); if($action == 'u') $app->plugins->raiseEvent('spamfilter_users_update', $data); diff --git a/server/plugins-available/mailman_plugin.inc.php b/server/plugins-available/mailman_plugin.inc.php deleted file mode 100644 index 99ac9db7d..000000000 --- a/server/plugins-available/mailman_plugin.inc.php +++ /dev/null @@ -1,182 +0,0 @@ -plugins->registerEvent('mail_mailinglist_insert', 'mailman_plugin', 'insert'); - $app->plugins->registerEvent('mail_mailinglist_update', 'mailman_plugin', 'update'); - $app->plugins->registerEvent('mail_mailinglist_delete', 'mailman_plugin', 'delete'); - - - - } - - function insert($event_name, $data) { - global $app, $conf; - - $this->update_config(); - - $pid = exec("nohup /usr/lib/mailman/bin/newlist -u ".escapeshellcmd($data["new"]["domain"])." -e ".escapeshellcmd($data["new"]["domain"])." ".escapeshellcmd($data["new"]["listname"])." ".escapeshellcmd($data["new"]["email"])." ".escapeshellcmd($data["new"]["password"])." >/dev/null 2>&1 & echo $!;"); - // wait for /usr/lib/mailman/bin/newlist-call - $running = true; - do { - exec('ps -p '.intval($pid), $out); - if (count($out) ==1) $running=false; else sleep(1); - unset($out); - } while ($running); - unset($out); - if(is_file('/etc/mailman/virtual-mailman') && !is_link('/var/lib/mailman/data/virtual-mailman')) { - symlink('/etc/mailman/virtual-mailman','/var/lib/mailman/data/virtual-mailman'); - } - if(is_file('/var/lib/mailman/data/virtual-mailman')) exec('postmap /var/lib/mailman/data/virtual-mailman'); - if(is_file('/var/lib/mailman/data/transport-mailman')) exec('postmap /var/lib/mailman/data/transport-mailman'); - - exec('nohup '.$conf['init_scripts'] . '/' . 'mailman reload >/dev/null 2>&1 &'); - - // Fix list URL - exec('/usr/sbin/withlist -l -r fix_url '.escapeshellcmd($data["new"]["listname"])); - - $app->db->query("UPDATE mail_mailinglist SET password = '' WHERE mailinglist_id = ?", $data["new"]['mailinglist_id']); - - } - - // The purpose of this plugin is to rewrite the main.cf file - function update($event_name, $data) { - global $app, $conf; - - $this->update_config(); - - if($data["new"]["password"] != $data["old"]["password"] && $data["new"]["password"] != '') { - exec("nohup /usr/lib/mailman/bin/change_pw -l ".escapeshellcmd($data["new"]["listname"])." -p ".escapeshellcmd($data["new"]["password"])." >/dev/null 2>&1 &"); - exec('nohup '.$conf['init_scripts'] . '/' . 'mailman reload >/dev/null 2>&1 &'); - $app->db->query("UPDATE mail_mailinglist SET password = '' WHERE mailinglist_id = ?", $data["new"]['mailinglist_id']); - } - - if(is_file('/var/lib/mailman/data/virtual-mailman')) exec('postmap /var/lib/mailman/data/virtual-mailman'); - if(is_file('/var/lib/mailman/data/transport-mailman')) exec('postmap /var/lib/mailman/data/transport-mailman'); - } - - function delete($event_name, $data) { - global $app, $conf; - - $this->update_config(); - - exec("nohup /usr/lib/mailman/bin/rmlist -a ".escapeshellcmd($data["old"]["listname"])." >/dev/null 2>&1 &"); - - exec('nohup '.$conf['init_scripts'] . '/' . 'mailman reload >/dev/null 2>&1 &'); - - if(is_file('/var/lib/mailman/data/virtual-mailman')) exec('postmap /var/lib/mailman/data/virtual-mailman'); - if(is_file('/var/lib/mailman/data/transport-mailman')) exec('postmap /var/lib/mailman/data/transport-mailman'); - - } - - function update_config() { - global $app, $conf; - - copy($this->mailman_config_dir.'mm_cfg.py', $this->mailman_config_dir.'mm_cfg.py~'); - - // load the server configuration options - $app->uses('getconf'); - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - - // load files - if(file_exists($conf["rootpath"]."/conf-custom/mm_cfg.py.master")) { - $content = file_get_contents($conf["rootpath"]."/conf-custom/mm_cfg.py.master"); - } else { - $content = file_get_contents($conf["rootpath"]."/conf/mm_cfg.py.master"); - } - $old_file = file_get_contents($this->mailman_config_dir."/mm_cfg.py"); - - $old_options = array(); - $lines = explode("\n", $old_file); - foreach ($lines as $line) - { - if (strlen($line) && substr($line, 0, 1) != '#') - { - list($key, $value) = explode("=", $line); - if ($value && $value !== '') - { - $key = rtrim($key); - $old_options[$key] = trim($value); - } - } - } - - // create virtual_domains list - $domainAll = $app->db->queryAllRecords("SELECT domain FROM mail_mailinglist GROUP BY domain"); - $virtual_domains = ''; - foreach($domainAll as $domain) - { - if ($domainAll[0]['domain'] == $domain['domain']) - $virtual_domains .= "'".$domain['domain']."'"; - else - $virtual_domains .= ", '".$domain['domain']."'"; - } - - $content = str_replace('{hostname}', $server_config['hostname'], $content); - $content = str_replace('{default_language}', $old_options['DEFAULT_SERVER_LANGUAGE'], $content); - $content = str_replace('{virtual_domains}', $virtual_domains, $content); - - file_put_contents($this->mailman_config_dir."/mm_cfg.py", $content); - } - -} // end class - -?> diff --git a/server/plugins-available/server_services_plugin.inc.php b/server/plugins-available/server_services_plugin.inc.php index bb75ac55b..90e229f81 100644 --- a/server/plugins-available/server_services_plugin.inc.php +++ b/server/plugins-available/server_services_plugin.inc.php @@ -38,7 +38,7 @@ class server_services_plugin { var $services = array('mail_server', 'web_server', 'dns_server', 'db_server', 'vserver_server'); - var $mail_plugins = array('getmail_plugin', 'mail_plugin', 'mail_plugin_dkim', 'mailman_plugin', 'postfix_filter_plugin', 'postfix_server_plugin'); + var $mail_plugins = array('getmail_plugin', 'mail_plugin', 'mail_plugin_dkim', 'postfix_filter_plugin', 'postfix_server_plugin'); var $dovecot_plugins = array('maildeliver_plugin'); var $web_plugins = array('aps_plugin', 'cron_plugin', 'cron_jailkit_plugin', 'ftpuser_base_plugin', 'shelluser_base_plugin', 'shelluser_jailkit_plugin', 'webserver_plugin'); -- GitLab From 7511fd3e8765af6eb0c30ff966d8e7a0294a190c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 13:12:01 +0100 Subject: [PATCH 198/310] - change incremental sql to not drop existing data --- .../sql/incremental/upd_dev_collection.sql | 41 ++----------------- 1 file changed, 4 insertions(+), 37 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 483a9a4ba..02a10ebfd 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -96,44 +96,7 @@ ALTER TABLE `xmpp_domain` -- STRIPDOWN! -ALTER TABLE `web_backup` CHANGE `backup_type` `backup_type` enum('web','mysql') NOT NULL DEFAULT 'web'; -ALTER TABLE `web_database_user` DROP COLUMN `database_password_mongo`; ALTER TABLE `client` CHANGE `web_php_options` `web_php_options` VARCHAR(255) NOT NULL DEFAULT 'no,fast-cgi,mod,php-fpm'; -ALTER TABLE `client_template` - DROP COLUMN `default_xmppserver`, - DROP COLUMN `xmpp_servers`, - DROP COLUMN `limit_xmpp_domain`, - DROP COLUMN `limit_xmpp_user`, - DROP COLUMN `limit_xmpp_muc`, - DROP COLUMN `limit_xmpp_anon`, - DROP COLUMN `limit_xmpp_vjud`, - DROP COLUMN `limit_xmpp_proxy`, - DROP COLUMN `limit_xmpp_status`, - DROP COLUMN `limit_xmpp_pastebin`, - DROP COLUMN `limit_xmpp_httparchive`, - DROP COLUMN `limit_xmpp_webpresence`, - DROP COLUMN `limit_xmpp_http_upload`; - -ALTER TABLE `server` DROP COLUMN `xmpp_server`; - -ALTER TABLE `client` - DROP COLUMN `default_xmppserver` int(11) unsigned NOT NULL DEFAULT '1', - DROP COLUMN `xmpp_servers`, - DROP COLUMN `limit_xmpp_domain`, - DROP COLUMN `limit_xmpp_user`, - DROP COLUMN `limit_xmpp_muc`, - DROP COLUMN `limit_xmpp_anon`, - DROP COLUMN `limit_xmpp_auth_options`, - DROP COLUMN `limit_xmpp_vjud`, - DROP COLUMN `limit_xmpp_proxy`, - DROP COLUMN `limit_xmpp_status`, - DROP COLUMN `limit_xmpp_pastebin`, - DROP COLUMN `limit_xmpp_httparchive`, - DROP COLUMN `limit_xmpp_webpresence`, - DROP COLUMN `limit_xmpp_http_upload`; - -DROP TABLE `xmpp_domain`; -DROP TABLE `xmpp_user`; -- only on nginx UPDATE `web_domain` as d INNER JOIN `server` as s ON (s.server_id = d.server_id) SET d.php = 'php-fpm' WHERE d.php = 'fast-cgi' AND s.config LIKE '%\nserver_type=nginx\n%' AND s.config NOT LIKE '%\nserver_type=apache\n%'; @@ -142,6 +105,10 @@ UPDATE `web_domain` SET `php` = 'php-fpm' WHERE `php` = 'hhvm'; UPDATE `web_domain` SET `php` = 'fast-cgi' WHERE `php` = 'cgi'; UPDATE `web_domain` SET `php` = 'mod' WHERE `php` = 'suphp'; +-- we do not drop columns or tables here to avoid deleting user data on existing servers! + +-- END OF STRIPDOWN! + -- rspamd ALTER TABLE `spamfilter_policy` ADD `rspamd_greylisting` ENUM('n','y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'n' AFTER `policyd_greylist`; ALTER TABLE `spamfilter_policy` ADD `rspamd_spam_greylisting_level` DECIMAL(5,2) NULL DEFAULT NULL AFTER `rspamd_greylisting`; -- GitLab From e126d3adb60e2905711e49232c6c094b7d4c43c9 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 13:14:21 +0100 Subject: [PATCH 199/310] - removed spare mailinglist language files --- install/tpl/mailman-virtual_to_transport.sh | 3 - .../web/mail/lib/lang/ar_mail_mailinglist.lng | 22 ------ .../lib/lang/ar_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/bg_mail_mailinglist.lng | 22 ------ .../lib/lang/bg_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/br_mail_mailinglist.lng | 22 ------ .../lib/lang/br_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/ca_mail_mailinglist.lng | 22 ------ .../lib/lang/ca_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/cz_mail_mailinglist.lng | 22 ------ .../lib/lang/cz_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/de_mail_mailinglist.lng | 22 ------ .../lib/lang/de_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/dk_mail_mailinglist.lng | 22 ------ .../lib/lang/dk_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/el_mail_mailinglist.lng | 22 ------ .../lib/lang/el_mail_mailinglist_list.lng | 5 -- .../lib/lang/en_imail_ml_membership_list.lng | 5 -- .../web/mail/lib/lang/en_mail_mailinglist.lng | 71 ------------------ .../lib/lang/en_mail_mailinglist_list.lng | 5 -- .../mail/lib/lang/en_mail_ml_membership.lng | 10 --- .../lib/lang/en_mail_ml_membership_list.lng | 5 -- .../web/mail/lib/lang/es_mail_mailinglist.lng | 22 ------ .../lib/lang/es_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/fi_mail_mailinglist.lng | 22 ------ .../lib/lang/fi_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/fr_mail_mailinglist.lng | 22 ------ .../lib/lang/fr_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/hr_mail_mailinglist.lng | 22 ------ .../lib/lang/hr_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/hu_mail_mailinglist.lng | 22 ------ .../lib/lang/hu_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/id_mail_mailinglist.lng | 22 ------ .../lib/lang/id_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/it_mail_mailinglist.lng | 74 ------------------- .../lib/lang/it_mail_mailinglist_list.lng | 5 -- .../mail/lib/lang/it_mail_ml_membership.lng | 8 -- .../lib/lang/it_mail_ml_membership_list.lng | 16 ---- .../web/mail/lib/lang/ja_mail_mailinglist.lng | 22 ------ .../lib/lang/ja_mail_mailinglist_list.lng | 5 -- .../lib/lang/nl_imail_ml_membership_list.lng | 5 -- .../web/mail/lib/lang/nl_mail_mailinglist.lng | 58 --------------- .../lib/lang/nl_mail_mailinglist_list.lng | 5 -- .../mail/lib/lang/nl_mail_ml_membership.lng | 9 --- .../lib/lang/nl_mail_ml_membership_list.lng | 5 -- .../web/mail/lib/lang/pl_mail_mailinglist.lng | 22 ------ .../lib/lang/pl_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/pt_mail_mailinglist.lng | 22 ------ .../lib/lang/pt_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/ro_mail_mailinglist.lng | 22 ------ .../lib/lang/ro_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/ru_mail_mailinglist.lng | 22 ------ .../lib/lang/ru_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/se_mail_mailinglist.lng | 22 ------ .../lib/lang/se_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/sk_mail_mailinglist.lng | 22 ------ .../lib/lang/sk_mail_mailinglist_list.lng | 5 -- .../web/mail/lib/lang/tr_mail_mailinglist.lng | 22 ------ .../lib/lang/tr_mail_mailinglist_list.lng | 5 -- 59 files changed, 878 deletions(-) delete mode 100644 install/tpl/mailman-virtual_to_transport.sh delete mode 100644 interface/web/mail/lib/lang/ar_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/ar_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/bg_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/bg_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/br_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/br_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/ca_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/ca_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/cz_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/cz_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/de_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/de_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/dk_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/dk_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/el_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/el_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/en_imail_ml_membership_list.lng delete mode 100644 interface/web/mail/lib/lang/en_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/en_mail_mailinglist_list.lng delete mode 100755 interface/web/mail/lib/lang/en_mail_ml_membership.lng delete mode 100644 interface/web/mail/lib/lang/en_mail_ml_membership_list.lng delete mode 100755 interface/web/mail/lib/lang/es_mail_mailinglist.lng delete mode 100755 interface/web/mail/lib/lang/es_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/fi_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/fi_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/fr_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/fr_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/hr_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/hr_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/hu_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/hu_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/id_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/id_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/it_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/it_mail_mailinglist_list.lng delete mode 100755 interface/web/mail/lib/lang/it_mail_ml_membership.lng delete mode 100644 interface/web/mail/lib/lang/it_mail_ml_membership_list.lng delete mode 100644 interface/web/mail/lib/lang/ja_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/ja_mail_mailinglist_list.lng delete mode 100755 interface/web/mail/lib/lang/nl_imail_ml_membership_list.lng delete mode 100644 interface/web/mail/lib/lang/nl_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/nl_mail_mailinglist_list.lng delete mode 100755 interface/web/mail/lib/lang/nl_mail_ml_membership.lng delete mode 100755 interface/web/mail/lib/lang/nl_mail_ml_membership_list.lng delete mode 100644 interface/web/mail/lib/lang/pl_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/pl_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/pt_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/pt_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/ro_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/ro_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/ru_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/ru_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/se_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/se_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/sk_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/sk_mail_mailinglist_list.lng delete mode 100644 interface/web/mail/lib/lang/tr_mail_mailinglist.lng delete mode 100644 interface/web/mail/lib/lang/tr_mail_mailinglist_list.lng diff --git a/install/tpl/mailman-virtual_to_transport.sh b/install/tpl/mailman-virtual_to_transport.sh deleted file mode 100644 index 6c57d25c0..000000000 --- a/install/tpl/mailman-virtual_to_transport.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -sed -r -e 's/(^[^#]\S+\s+).+$/\1local/' $1 > /var/lib/mailman/data/transport-mailman -/usr/sbin/postmap /var/lib/mailman/data/transport-mailman \ No newline at end of file diff --git a/interface/web/mail/lib/lang/ar_mail_mailinglist.lng b/interface/web/mail/lib/lang/ar_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/ar_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ar_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/ar_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/ar_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_mail_mailinglist.lng b/interface/web/mail/lib/lang/bg_mail_mailinglist.lng deleted file mode 100644 index 74db3ed6f..000000000 --- a/interface/web/mail/lib/lang/bg_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/bg_mail_mailinglist_list.lng deleted file mode 100644 index 9f64b1234..000000000 --- a/interface/web/mail/lib/lang/bg_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_mail_mailinglist.lng b/interface/web/mail/lib/lang/br_mail_mailinglist.lng deleted file mode 100644 index a34dca7f3..000000000 --- a/interface/web/mail/lib/lang/br_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/br_mail_mailinglist_list.lng deleted file mode 100644 index 08fd204fb..000000000 --- a/interface/web/mail/lib/lang/br_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_mail_mailinglist.lng b/interface/web/mail/lib/lang/ca_mail_mailinglist.lng deleted file mode 100644 index 919e7079e..000000000 --- a/interface/web/mail/lib/lang/ca_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/ca_mail_mailinglist_list.lng deleted file mode 100644 index bf25d31c3..000000000 --- a/interface/web/mail/lib/lang/ca_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_mail_mailinglist.lng b/interface/web/mail/lib/lang/cz_mail_mailinglist.lng deleted file mode 100644 index e1f7dfbfa..000000000 --- a/interface/web/mail/lib/lang/cz_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/cz_mail_mailinglist_list.lng deleted file mode 100644 index db31273f5..000000000 --- a/interface/web/mail/lib/lang/cz_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_mail_mailinglist.lng b/interface/web/mail/lib/lang/de_mail_mailinglist.lng deleted file mode 100644 index 1d143b690..000000000 --- a/interface/web/mail/lib/lang/de_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/de_mail_mailinglist_list.lng deleted file mode 100644 index 3eee785f2..000000000 --- a/interface/web/mail/lib/lang/de_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_mail_mailinglist.lng b/interface/web/mail/lib/lang/dk_mail_mailinglist.lng deleted file mode 100644 index 0868d38e6..000000000 --- a/interface/web/mail/lib/lang/dk_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/dk_mail_mailinglist_list.lng deleted file mode 100644 index 1a0612274..000000000 --- a/interface/web/mail/lib/lang/dk_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_mail_mailinglist.lng b/interface/web/mail/lib/lang/el_mail_mailinglist.lng deleted file mode 100644 index 5f5e0ffc7..000000000 --- a/interface/web/mail/lib/lang/el_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/el_mail_mailinglist_list.lng deleted file mode 100644 index 8fc67cb11..000000000 --- a/interface/web/mail/lib/lang/el_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/en_imail_ml_membership_list.lng b/interface/web/mail/lib/lang/en_imail_ml_membership_list.lng deleted file mode 100644 index 4c2c4671f..000000000 --- a/interface/web/mail/lib/lang/en_imail_ml_membership_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_mail_mailinglist.lng b/interface/web/mail/lib/lang/en_mail_mailinglist.lng deleted file mode 100644 index 2c7f947eb..000000000 --- a/interface/web/mail/lib/lang/en_mail_mailinglist.lng +++ /dev/null @@ -1,71 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/en_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/en_mail_mailinglist_list.lng deleted file mode 100644 index 0f8858971..000000000 --- a/interface/web/mail/lib/lang/en_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_mail_ml_membership.lng b/interface/web/mail/lib/lang/en_mail_ml_membership.lng deleted file mode 100755 index 1c39d8452..000000000 --- a/interface/web/mail/lib/lang/en_mail_ml_membership.lng +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_mail_mailinglist.lng b/interface/web/mail/lib/lang/es_mail_mailinglist.lng deleted file mode 100755 index 5a41780df..000000000 --- a/interface/web/mail/lib/lang/es_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/es_mail_mailinglist_list.lng deleted file mode 100755 index ba25baf3c..000000000 --- a/interface/web/mail/lib/lang/es_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_mail_mailinglist.lng b/interface/web/mail/lib/lang/fi_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/fi_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/fi_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/fi_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_mail_mailinglist.lng b/interface/web/mail/lib/lang/fr_mail_mailinglist.lng deleted file mode 100644 index 107b39817..000000000 --- a/interface/web/mail/lib/lang/fr_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/fr_mail_mailinglist_list.lng deleted file mode 100644 index d04d99ae0..000000000 --- a/interface/web/mail/lib/lang/fr_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_mail_mailinglist.lng b/interface/web/mail/lib/lang/hr_mail_mailinglist.lng deleted file mode 100644 index 04d3095e7..000000000 --- a/interface/web/mail/lib/lang/hr_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/hr_mail_mailinglist_list.lng deleted file mode 100644 index 48b8c8b32..000000000 --- a/interface/web/mail/lib/lang/hr_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_mail_mailinglist.lng b/interface/web/mail/lib/lang/hu_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/hu_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/hu_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/hu_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_mail_mailinglist.lng b/interface/web/mail/lib/lang/id_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/id_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/id_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/id_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_mail_mailinglist.lng b/interface/web/mail/lib/lang/it_mail_mailinglist.lng deleted file mode 100644 index 235469fb8..000000000 --- a/interface/web/mail/lib/lang/it_mail_mailinglist.lng +++ /dev/null @@ -1,74 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_mail_ml_membership.lng b/interface/web/mail/lib/lang/it_mail_ml_membership.lng deleted file mode 100755 index b44d8a19f..000000000 --- a/interface/web/mail/lib/lang/it_mail_ml_membership.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/ja_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/ja_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_imail_ml_membership_list.lng b/interface/web/mail/lib/lang/nl_imail_ml_membership_list.lng deleted file mode 100755 index a145fb9e5..000000000 --- a/interface/web/mail/lib/lang/nl_imail_ml_membership_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_mail_mailinglist.lng b/interface/web/mail/lib/lang/nl_mail_mailinglist.lng deleted file mode 100644 index 5a27977df..000000000 --- a/interface/web/mail/lib/lang/nl_mail_mailinglist.lng +++ /dev/null @@ -1,58 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/nl_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/nl_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_mail_ml_membership.lng b/interface/web/mail/lib/lang/nl_mail_ml_membership.lng deleted file mode 100755 index 392354507..000000000 --- a/interface/web/mail/lib/lang/nl_mail_ml_membership.lng +++ /dev/null @@ -1,9 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_mail_ml_membership_list.lng b/interface/web/mail/lib/lang/nl_mail_ml_membership_list.lng deleted file mode 100755 index 33d286ed1..000000000 --- a/interface/web/mail/lib/lang/nl_mail_ml_membership_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_mail_mailinglist.lng b/interface/web/mail/lib/lang/pl_mail_mailinglist.lng deleted file mode 100644 index f285b1eae..000000000 --- a/interface/web/mail/lib/lang/pl_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/pl_mail_mailinglist_list.lng deleted file mode 100644 index 649db47bd..000000000 --- a/interface/web/mail/lib/lang/pl_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_mail_mailinglist.lng b/interface/web/mail/lib/lang/pt_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/pt_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/pt_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/pt_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_mail_mailinglist.lng b/interface/web/mail/lib/lang/ro_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/ro_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/ro_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/ro_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_mail_mailinglist.lng b/interface/web/mail/lib/lang/ru_mail_mailinglist.lng deleted file mode 100644 index 30b78ff3c..000000000 --- a/interface/web/mail/lib/lang/ru_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/ru_mail_mailinglist_list.lng deleted file mode 100644 index e5782d1f9..000000000 --- a/interface/web/mail/lib/lang/ru_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_mail_mailinglist.lng b/interface/web/mail/lib/lang/se_mail_mailinglist.lng deleted file mode 100644 index ef65e449d..000000000 --- a/interface/web/mail/lib/lang/se_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/se_mail_mailinglist_list.lng deleted file mode 100644 index 2e9f36441..000000000 --- a/interface/web/mail/lib/lang/se_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_mail_mailinglist.lng b/interface/web/mail/lib/lang/sk_mail_mailinglist.lng deleted file mode 100644 index 5e16270b9..000000000 --- a/interface/web/mail/lib/lang/sk_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/sk_mail_mailinglist_list.lng deleted file mode 100644 index dac225ad9..000000000 --- a/interface/web/mail/lib/lang/sk_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_mail_mailinglist.lng b/interface/web/mail/lib/lang/tr_mail_mailinglist.lng deleted file mode 100644 index 17bfab31d..000000000 --- a/interface/web/mail/lib/lang/tr_mail_mailinglist.lng +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_mail_mailinglist_list.lng b/interface/web/mail/lib/lang/tr_mail_mailinglist_list.lng deleted file mode 100644 index c605dd244..000000000 --- a/interface/web/mail/lib/lang/tr_mail_mailinglist_list.lng +++ /dev/null @@ -1,5 +0,0 @@ - -- GitLab From 2bc5766e1ec94e3988def669bab81fc33485c666 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 13:15:34 +0100 Subject: [PATCH 200/310] - removed spare language files from xmpp --- interface/web/js/xmpp_domain_muc.js | 26 -------- interface/web/js/xmpp_domain_registration.js | 29 --------- .../web/mail/lib/lang/ar_xmpp_domain.lng | 62 ------------------ .../lib/lang/ar_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/ar_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/ar_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/ar_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/bg_xmpp_domain.lng | 62 ------------------ .../lib/lang/bg_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/bg_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/bg_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/bg_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/br_xmpp_domain.lng | 62 ------------------ .../lib/lang/br_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/br_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/br_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/br_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/ca_xmpp_domain.lng | 62 ------------------ .../lib/lang/ca_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/ca_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/ca_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/ca_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/cz_xmpp_domain.lng | 62 ------------------ .../lib/lang/cz_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/cz_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/cz_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/cz_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/de_xmpp_domain.lng | 62 ------------------ .../lib/lang/de_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/de_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/de_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/de_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/dk_xmpp_domain.lng | 62 ------------------ .../lib/lang/dk_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/dk_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/dk_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/dk_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/el_xmpp_domain.lng | 62 ------------------ .../lib/lang/el_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/el_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/el_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/el_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/en_xmpp_domain.lng | 64 ------------------- .../lib/lang/en_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/en_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/en_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/en_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/es_xmpp_domain.lng | 62 ------------------ .../lib/lang/es_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/es_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/es_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/es_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/fi_xmpp_domain.lng | 62 ------------------ .../lib/lang/fi_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/fi_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/fi_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/fi_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/fr_xmpp_domain.lng | 62 ------------------ .../lib/lang/fr_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/fr_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/fr_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/fr_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/hr_xmpp_domain.lng | 62 ------------------ .../lib/lang/hr_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/hr_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/hr_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/hr_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/hu_xmpp_domain.lng | 62 ------------------ .../lib/lang/hu_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/hu_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/hu_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/hu_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/id_xmpp_domain.lng | 62 ------------------ .../lib/lang/id_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/id_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/id_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/id_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/it_xmpp_domain.lng | 62 ------------------ .../lib/lang/it_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/it_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/it_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/it_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/ja_xmpp_domain.lng | 62 ------------------ .../lib/lang/ja_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/ja_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/ja_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/ja_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/nl_xmpp_domain.lng | 62 ------------------ .../lib/lang/nl_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/nl_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/nl_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/nl_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/pl_xmpp_domain.lng | 62 ------------------ .../lib/lang/pl_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/pl_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/pl_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/pl_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/pt_xmpp_domain.lng | 62 ------------------ .../lib/lang/pt_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/pt_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/pt_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/pt_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/ro_xmpp_domain.lng | 62 ------------------ .../lib/lang/ro_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/ro_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/ro_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/ro_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/ru_xmpp_domain.lng | 62 ------------------ .../lib/lang/ru_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/ru_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/ru_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/ru_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/se_xmpp_domain.lng | 62 ------------------ .../lib/lang/se_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/se_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/se_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/se_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/sk_xmpp_domain.lng | 62 ------------------ .../lib/lang/sk_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/sk_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/sk_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/sk_xmpp_user_list.lng | 8 --- .../web/mail/lib/lang/tr_xmpp_domain.lng | 62 ------------------ .../lib/lang/tr_xmpp_domain_admin_list.lng | 8 --- .../web/mail/lib/lang/tr_xmpp_domain_list.lng | 7 -- interface/web/mail/lib/lang/tr_xmpp_user.lng | 15 ----- .../web/mail/lib/lang/tr_xmpp_user_list.lng | 8 --- 127 files changed, 2557 deletions(-) delete mode 100644 interface/web/js/xmpp_domain_muc.js delete mode 100644 interface/web/js/xmpp_domain_registration.js delete mode 100644 interface/web/mail/lib/lang/ar_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/ar_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/ar_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/ar_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/ar_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/bg_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/bg_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/bg_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/bg_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/bg_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/br_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/br_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/br_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/br_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/br_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/ca_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/ca_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/ca_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/ca_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/ca_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/cz_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/cz_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/cz_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/cz_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/cz_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/de_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/de_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/de_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/de_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/de_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/dk_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/dk_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/dk_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/dk_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/dk_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/el_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/el_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/el_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/el_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/el_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/en_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/en_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/en_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/en_xmpp_user_list.lng delete mode 100755 interface/web/mail/lib/lang/es_xmpp_domain.lng delete mode 100755 interface/web/mail/lib/lang/es_xmpp_domain_admin_list.lng delete mode 100755 interface/web/mail/lib/lang/es_xmpp_domain_list.lng delete mode 100755 interface/web/mail/lib/lang/es_xmpp_user.lng delete mode 100755 interface/web/mail/lib/lang/es_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/fi_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/fi_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/fi_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/fi_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/fi_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/fr_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/fr_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/fr_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/fr_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/fr_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/hr_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/hr_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/hr_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/hr_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/hr_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/hu_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/hu_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/hu_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/hu_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/hu_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/id_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/id_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/id_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/id_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/id_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/it_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/it_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/it_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/it_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/it_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/ja_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/ja_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/ja_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/ja_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/ja_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/nl_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/nl_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/nl_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/nl_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/nl_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/pl_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/pl_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/pl_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/pl_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/pl_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/pt_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/pt_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/pt_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/pt_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/pt_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/ro_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/ro_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/ro_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/ro_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/ro_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/ru_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/ru_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/ru_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/ru_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/ru_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/se_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/se_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/se_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/se_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/se_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/sk_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/sk_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/sk_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/sk_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/sk_xmpp_user_list.lng delete mode 100644 interface/web/mail/lib/lang/tr_xmpp_domain.lng delete mode 100644 interface/web/mail/lib/lang/tr_xmpp_domain_admin_list.lng delete mode 100644 interface/web/mail/lib/lang/tr_xmpp_domain_list.lng delete mode 100644 interface/web/mail/lib/lang/tr_xmpp_user.lng delete mode 100644 interface/web/mail/lib/lang/tr_xmpp_user_list.lng diff --git a/interface/web/js/xmpp_domain_muc.js b/interface/web/js/xmpp_domain_muc.js deleted file mode 100644 index 90189288e..000000000 --- a/interface/web/js/xmpp_domain_muc.js +++ /dev/null @@ -1,26 +0,0 @@ -$('document').ready(function(){ - $('#use_muc_host').on('change', function(e){ - if($(this).is(':checked')){ - $('#toggle-use-muc').addClass('in'); - $('#use_pastebin').trigger('change'); - $('#use_http_archive').trigger('change'); - }else{ - $('#toggle-use-muc').removeClass('in'); - } - }); - $('#use_pastebin').on('change', function(e){ - if($(this).is(':checked')){ - $('#toggle-use-pastebin').addClass('in'); - }else{ - $('#toggle-use-pastebin').removeClass('in'); - } - }); - $('#use_http_archive').on('change', function(e){ - if($(this).is(':checked')){ - $('#toggle-use-archive').addClass('in'); - }else{ - $('#toggle-use-archive').removeClass('in'); - } - }); - $('#use_muc_host').trigger('change'); -}) \ No newline at end of file diff --git a/interface/web/js/xmpp_domain_registration.js b/interface/web/js/xmpp_domain_registration.js deleted file mode 100644 index 1ce239e8c..000000000 --- a/interface/web/js/xmpp_domain_registration.js +++ /dev/null @@ -1,29 +0,0 @@ -$('document').ready(function(){ - // Not needed as long as maildomain hook is not implemented - return; - $('#management_method').on('select2-selecting', function(e){ - val = e.choice ? e.choice.id : e.target.selectedIndex; - if(val == 0){ - //normal - $('#toggle-management-normal').addClass('in'); - $('#toggle-registration-closed').addClass('in'); - $('#public_registration').trigger('change'); - }else if(val != undefined){ - //maildomain - $('#toggle-management-normal').removeClass('in'); - $('#toggle-registration-closed').removeClass('in'); - }else{ - $('#toggle-management-normal').removeClass('in'); - $('#toggle-registration-closed').removeClass('in'); - } - }); - $('#public_registration').on('change', function(e){ - if($(this).is(':checked')){ - $('#toggle-registration-closed').removeClass('in'); - }else{ - $('#toggle-registration-closed').addClass('in'); - } - }); - $('#public_registration').trigger('change'); - $('#management_method').trigger('select2-selecting'); -}) \ No newline at end of file diff --git a/interface/web/mail/lib/lang/ar_xmpp_domain.lng b/interface/web/mail/lib/lang/ar_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/ar_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ar_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/ar_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/ar_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ar_xmpp_domain_list.lng b/interface/web/mail/lib/lang/ar_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/ar_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ar_xmpp_user.lng b/interface/web/mail/lib/lang/ar_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/ar_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ar_xmpp_user_list.lng b/interface/web/mail/lib/lang/ar_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/ar_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_xmpp_domain.lng b/interface/web/mail/lib/lang/bg_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/bg_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/bg_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/bg_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_xmpp_domain_list.lng b/interface/web/mail/lib/lang/bg_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/bg_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_xmpp_user.lng b/interface/web/mail/lib/lang/bg_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/bg_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/bg_xmpp_user_list.lng b/interface/web/mail/lib/lang/bg_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/bg_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_xmpp_domain.lng b/interface/web/mail/lib/lang/br_xmpp_domain.lng deleted file mode 100644 index 1a9a42f0c..000000000 --- a/interface/web/mail/lib/lang/br_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/br_xmpp_domain_admin_list.lng deleted file mode 100644 index b8d220897..000000000 --- a/interface/web/mail/lib/lang/br_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_xmpp_domain_list.lng b/interface/web/mail/lib/lang/br_xmpp_domain_list.lng deleted file mode 100644 index ab8f3a908..000000000 --- a/interface/web/mail/lib/lang/br_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_xmpp_user.lng b/interface/web/mail/lib/lang/br_xmpp_user.lng deleted file mode 100644 index 8f2306814..000000000 --- a/interface/web/mail/lib/lang/br_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/br_xmpp_user_list.lng b/interface/web/mail/lib/lang/br_xmpp_user_list.lng deleted file mode 100644 index 13d71a05a..000000000 --- a/interface/web/mail/lib/lang/br_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_xmpp_domain.lng b/interface/web/mail/lib/lang/ca_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/ca_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/ca_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/ca_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_xmpp_domain_list.lng b/interface/web/mail/lib/lang/ca_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/ca_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_xmpp_user.lng b/interface/web/mail/lib/lang/ca_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/ca_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ca_xmpp_user_list.lng b/interface/web/mail/lib/lang/ca_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/ca_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_xmpp_domain.lng b/interface/web/mail/lib/lang/cz_xmpp_domain.lng deleted file mode 100644 index 8f04fe801..000000000 --- a/interface/web/mail/lib/lang/cz_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/cz_xmpp_domain_admin_list.lng deleted file mode 100644 index 9a4885fa9..000000000 --- a/interface/web/mail/lib/lang/cz_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_xmpp_domain_list.lng b/interface/web/mail/lib/lang/cz_xmpp_domain_list.lng deleted file mode 100644 index c031c3084..000000000 --- a/interface/web/mail/lib/lang/cz_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_xmpp_user.lng b/interface/web/mail/lib/lang/cz_xmpp_user.lng deleted file mode 100644 index eaa73b08a..000000000 --- a/interface/web/mail/lib/lang/cz_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/cz_xmpp_user_list.lng b/interface/web/mail/lib/lang/cz_xmpp_user_list.lng deleted file mode 100644 index f611f1c4f..000000000 --- a/interface/web/mail/lib/lang/cz_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_xmpp_domain.lng b/interface/web/mail/lib/lang/de_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/de_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/de_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/de_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_xmpp_domain_list.lng b/interface/web/mail/lib/lang/de_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/de_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_xmpp_user.lng b/interface/web/mail/lib/lang/de_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/de_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/de_xmpp_user_list.lng b/interface/web/mail/lib/lang/de_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/de_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_xmpp_domain.lng b/interface/web/mail/lib/lang/dk_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/dk_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/dk_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/dk_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_xmpp_domain_list.lng b/interface/web/mail/lib/lang/dk_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/dk_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_xmpp_user.lng b/interface/web/mail/lib/lang/dk_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/dk_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/dk_xmpp_user_list.lng b/interface/web/mail/lib/lang/dk_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/dk_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_xmpp_domain.lng b/interface/web/mail/lib/lang/el_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/el_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/el_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/el_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_xmpp_domain_list.lng b/interface/web/mail/lib/lang/el_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/el_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_xmpp_user.lng b/interface/web/mail/lib/lang/el_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/el_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/el_xmpp_user_list.lng b/interface/web/mail/lib/lang/el_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/el_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/en_xmpp_domain.lng b/interface/web/mail/lib/lang/en_xmpp_domain.lng deleted file mode 100644 index 70afe1e87..000000000 --- a/interface/web/mail/lib/lang/en_xmpp_domain.lng +++ /dev/null @@ -1,64 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng deleted file mode 100644 index a3d1736d7..000000000 --- a/interface/web/mail/lib/lang/en_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_xmpp_domain_list.lng b/interface/web/mail/lib/lang/en_xmpp_domain_list.lng deleted file mode 100644 index f8c2fb9b8..000000000 --- a/interface/web/mail/lib/lang/en_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_xmpp_user.lng b/interface/web/mail/lib/lang/en_xmpp_user.lng deleted file mode 100644 index 1cc852e3c..000000000 --- a/interface/web/mail/lib/lang/en_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/en_xmpp_user_list.lng b/interface/web/mail/lib/lang/en_xmpp_user_list.lng deleted file mode 100644 index db88b0d7e..000000000 --- a/interface/web/mail/lib/lang/en_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - \ No newline at end of file diff --git a/interface/web/mail/lib/lang/es_xmpp_domain.lng b/interface/web/mail/lib/lang/es_xmpp_domain.lng deleted file mode 100755 index 8020157d9..000000000 --- a/interface/web/mail/lib/lang/es_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/es_xmpp_domain_admin_list.lng deleted file mode 100755 index 82465fa49..000000000 --- a/interface/web/mail/lib/lang/es_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_xmpp_domain_list.lng b/interface/web/mail/lib/lang/es_xmpp_domain_list.lng deleted file mode 100755 index 205eb4b23..000000000 --- a/interface/web/mail/lib/lang/es_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_xmpp_user.lng b/interface/web/mail/lib/lang/es_xmpp_user.lng deleted file mode 100755 index 8129b7a1c..000000000 --- a/interface/web/mail/lib/lang/es_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/es_xmpp_user_list.lng b/interface/web/mail/lib/lang/es_xmpp_user_list.lng deleted file mode 100755 index e29369b34..000000000 --- a/interface/web/mail/lib/lang/es_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_xmpp_domain.lng b/interface/web/mail/lib/lang/fi_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/fi_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/fi_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/fi_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_xmpp_domain_list.lng b/interface/web/mail/lib/lang/fi_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/fi_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_xmpp_user.lng b/interface/web/mail/lib/lang/fi_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/fi_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fi_xmpp_user_list.lng b/interface/web/mail/lib/lang/fi_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/fi_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_xmpp_domain.lng b/interface/web/mail/lib/lang/fr_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/fr_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/fr_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/fr_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_xmpp_domain_list.lng b/interface/web/mail/lib/lang/fr_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/fr_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_xmpp_user.lng b/interface/web/mail/lib/lang/fr_xmpp_user.lng deleted file mode 100644 index c70aba47a..000000000 --- a/interface/web/mail/lib/lang/fr_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/fr_xmpp_user_list.lng b/interface/web/mail/lib/lang/fr_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/fr_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_xmpp_domain.lng b/interface/web/mail/lib/lang/hr_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/hr_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/hr_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/hr_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_xmpp_domain_list.lng b/interface/web/mail/lib/lang/hr_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/hr_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_xmpp_user.lng b/interface/web/mail/lib/lang/hr_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/hr_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hr_xmpp_user_list.lng b/interface/web/mail/lib/lang/hr_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/hr_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_xmpp_domain.lng b/interface/web/mail/lib/lang/hu_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/hu_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/hu_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/hu_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_xmpp_domain_list.lng b/interface/web/mail/lib/lang/hu_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/hu_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_xmpp_user.lng b/interface/web/mail/lib/lang/hu_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/hu_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/hu_xmpp_user_list.lng b/interface/web/mail/lib/lang/hu_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/hu_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_xmpp_domain.lng b/interface/web/mail/lib/lang/id_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/id_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/id_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/id_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_xmpp_domain_list.lng b/interface/web/mail/lib/lang/id_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/id_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_xmpp_user.lng b/interface/web/mail/lib/lang/id_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/id_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/id_xmpp_user_list.lng b/interface/web/mail/lib/lang/id_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/id_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_xmpp_domain.lng b/interface/web/mail/lib/lang/it_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/it_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/it_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/it_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_xmpp_domain_list.lng b/interface/web/mail/lib/lang/it_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/it_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_xmpp_user.lng b/interface/web/mail/lib/lang/it_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/it_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/it_xmpp_user_list.lng b/interface/web/mail/lib/lang/it_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/it_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_xmpp_domain.lng b/interface/web/mail/lib/lang/ja_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/ja_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/ja_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/ja_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_xmpp_domain_list.lng b/interface/web/mail/lib/lang/ja_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/ja_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_xmpp_user.lng b/interface/web/mail/lib/lang/ja_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/ja_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ja_xmpp_user_list.lng b/interface/web/mail/lib/lang/ja_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/ja_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_xmpp_domain.lng b/interface/web/mail/lib/lang/nl_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/nl_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/nl_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/nl_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_xmpp_domain_list.lng b/interface/web/mail/lib/lang/nl_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/nl_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_xmpp_user.lng b/interface/web/mail/lib/lang/nl_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/nl_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/nl_xmpp_user_list.lng b/interface/web/mail/lib/lang/nl_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/nl_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_xmpp_domain.lng b/interface/web/mail/lib/lang/pl_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/pl_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/pl_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/pl_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_xmpp_domain_list.lng b/interface/web/mail/lib/lang/pl_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/pl_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_xmpp_user.lng b/interface/web/mail/lib/lang/pl_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/pl_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pl_xmpp_user_list.lng b/interface/web/mail/lib/lang/pl_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/pl_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_xmpp_domain.lng b/interface/web/mail/lib/lang/pt_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/pt_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/pt_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/pt_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_xmpp_domain_list.lng b/interface/web/mail/lib/lang/pt_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/pt_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_xmpp_user.lng b/interface/web/mail/lib/lang/pt_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/pt_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/pt_xmpp_user_list.lng b/interface/web/mail/lib/lang/pt_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/pt_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_xmpp_domain.lng b/interface/web/mail/lib/lang/ro_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/ro_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/ro_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/ro_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_xmpp_domain_list.lng b/interface/web/mail/lib/lang/ro_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/ro_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_xmpp_user.lng b/interface/web/mail/lib/lang/ro_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/ro_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ro_xmpp_user_list.lng b/interface/web/mail/lib/lang/ro_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/ro_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_xmpp_domain.lng b/interface/web/mail/lib/lang/ru_xmpp_domain.lng deleted file mode 100644 index 9654a0a02..000000000 --- a/interface/web/mail/lib/lang/ru_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/ru_xmpp_domain_admin_list.lng deleted file mode 100644 index 31e321602..000000000 --- a/interface/web/mail/lib/lang/ru_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_xmpp_domain_list.lng b/interface/web/mail/lib/lang/ru_xmpp_domain_list.lng deleted file mode 100644 index fd3a2641c..000000000 --- a/interface/web/mail/lib/lang/ru_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_xmpp_user.lng b/interface/web/mail/lib/lang/ru_xmpp_user.lng deleted file mode 100644 index a687b3579..000000000 --- a/interface/web/mail/lib/lang/ru_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/ru_xmpp_user_list.lng b/interface/web/mail/lib/lang/ru_xmpp_user_list.lng deleted file mode 100644 index 15b2c43eb..000000000 --- a/interface/web/mail/lib/lang/ru_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_xmpp_domain.lng b/interface/web/mail/lib/lang/se_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/se_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/se_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/se_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_xmpp_domain_list.lng b/interface/web/mail/lib/lang/se_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/se_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_xmpp_user.lng b/interface/web/mail/lib/lang/se_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/se_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/se_xmpp_user_list.lng b/interface/web/mail/lib/lang/se_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/se_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_xmpp_domain.lng b/interface/web/mail/lib/lang/sk_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/sk_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/sk_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/sk_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_xmpp_domain_list.lng b/interface/web/mail/lib/lang/sk_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/sk_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_xmpp_user.lng b/interface/web/mail/lib/lang/sk_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/sk_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/sk_xmpp_user_list.lng b/interface/web/mail/lib/lang/sk_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/sk_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_xmpp_domain.lng b/interface/web/mail/lib/lang/tr_xmpp_domain.lng deleted file mode 100644 index 0541203b2..000000000 --- a/interface/web/mail/lib/lang/tr_xmpp_domain.lng +++ /dev/null @@ -1,62 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_xmpp_domain_admin_list.lng b/interface/web/mail/lib/lang/tr_xmpp_domain_admin_list.lng deleted file mode 100644 index af643eab5..000000000 --- a/interface/web/mail/lib/lang/tr_xmpp_domain_admin_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_xmpp_domain_list.lng b/interface/web/mail/lib/lang/tr_xmpp_domain_list.lng deleted file mode 100644 index ebfebab7d..000000000 --- a/interface/web/mail/lib/lang/tr_xmpp_domain_list.lng +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_xmpp_user.lng b/interface/web/mail/lib/lang/tr_xmpp_user.lng deleted file mode 100644 index 6ab739d98..000000000 --- a/interface/web/mail/lib/lang/tr_xmpp_user.lng +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/interface/web/mail/lib/lang/tr_xmpp_user_list.lng b/interface/web/mail/lib/lang/tr_xmpp_user_list.lng deleted file mode 100644 index f2651cb62..000000000 --- a/interface/web/mail/lib/lang/tr_xmpp_user_list.lng +++ /dev/null @@ -1,8 +0,0 @@ - -- GitLab From a83198e13bccb6501b887312431ab8edafd427ec Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 14 Nov 2018 13:50:09 +0100 Subject: [PATCH 201/310] - removed openvz management --- .../autoinstall.conf_sample.php | 1 - .../setup_in_openvz/diff_openssl.cnf | 25 - .../setup_in_openvz/install_server.sh | 61 -- .../recreate_ssh_and_hostname.sh | 18 - install/dist/conf/centos70.conf.php | 6 - install/dist/conf/centos72.conf.php | 6 - install/dist/conf/debian40.conf.php | 7 - install/dist/conf/debian60.conf.php | 4 - install/dist/conf/debian90.conf.php | 4 - install/dist/conf/debiantesting.conf.php | 4 - install/dist/conf/fedora9.conf.php | 6 - install/dist/conf/gentoo.conf.php | 6 - install/dist/conf/opensuse112.conf.php | 6 - install/dist/conf/ubuntu1604.conf.php | 4 - install/dist/conf/ubuntu1710.conf.php | 4 - install/dist/conf/ubuntu1804.conf.php | 4 - install/dist/lib/fedora.lib.php | 7 +- install/dist/lib/gentoo.lib.php | 7 +- install/dist/lib/opensuse.lib.php | 7 +- install/install.php | 8 - install/lib/installer_base.lib.php | 17 +- install/lib/update.lib.php | 1 - install/sql/ispconfig3.sql | 187 ------- install/update.php | 7 +- .../lib/classes/custom_datasource.inc.php | 3 - interface/lib/classes/functions.inc.php | 6 - interface/lib/classes/remote.d/openvz.inc.php | 480 ---------------- interface/lib/classes/remote.d/server.inc.php | 2 +- interface/lib/classes/validate_openvz.inc.php | 66 --- .../lib/plugins/vm_openvz_plugin.inc.php | 298 ---------- interface/lib/server_conf.master | 3 - interface/web/admin/form/server.tform.php | 6 - interface/web/admin/list/server.list.php | 11 - .../admin/templates/server_edit_services.htm | 6 - interface/web/admin/templates/server_list.htm | 7 +- interface/web/client/client_edit.php | 1 - interface/web/client/form/client.tform.php | 25 - .../web/client/form/client_template.tform.php | 25 - interface/web/client/form/reseller.tform.php | 25 - .../client/templates/client_edit_limits.htm | 22 - .../templates/client_template_edit_limits.htm | 22 - .../client/templates/reseller_edit_limits.htm | 22 - interface/web/dashboard/ajax_get_json.php | 12 - interface/web/nav.php | 4 - interface/web/tools/import_vpopmail.php | 4 +- interface/web/tools/resync.php | 31 -- interface/web/tools/templates/resync.htm | 10 - interface/web/vm/ajax_get_ip.php | 55 -- interface/web/vm/form/openvz_ip.tform.php | 117 ---- .../web/vm/form/openvz_ostemplate.tform.php | 148 ----- .../web/vm/form/openvz_template.tform.php | 523 ------------------ interface/web/vm/form/openvz_vm.tform.php | 375 ------------- interface/web/vm/lib/admin.conf.php | 2 - interface/web/vm/lib/lang/ar.lng | 7 - .../web/vm/lib/lang/ar_openvz_action.lng | 16 - interface/web/vm/lib/lang/ar_openvz_ip.lng | 9 - .../web/vm/lib/lang/ar_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/ar_openvz_ostemplate.lng | 11 - .../vm/lib/lang/ar_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/ar_openvz_template.lng | 97 ---- .../vm/lib/lang/ar_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/ar_openvz_vm.lng | 45 -- .../web/vm/lib/lang/ar_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/bg.lng | 7 - .../web/vm/lib/lang/bg_openvz_action.lng | 16 - interface/web/vm/lib/lang/bg_openvz_ip.lng | 9 - .../web/vm/lib/lang/bg_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/bg_openvz_ostemplate.lng | 11 - .../vm/lib/lang/bg_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/bg_openvz_template.lng | 97 ---- .../vm/lib/lang/bg_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/bg_openvz_vm.lng | 45 -- .../web/vm/lib/lang/bg_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/br.lng | 7 - .../web/vm/lib/lang/br_openvz_action.lng | 16 - interface/web/vm/lib/lang/br_openvz_ip.lng | 9 - .../web/vm/lib/lang/br_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/br_openvz_ostemplate.lng | 11 - .../vm/lib/lang/br_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/br_openvz_template.lng | 97 ---- .../vm/lib/lang/br_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/br_openvz_vm.lng | 45 -- .../web/vm/lib/lang/br_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/ca.lng | 7 - .../web/vm/lib/lang/ca_openvz_action.lng | 16 - interface/web/vm/lib/lang/ca_openvz_ip.lng | 9 - .../web/vm/lib/lang/ca_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/ca_openvz_ostemplate.lng | 11 - .../vm/lib/lang/ca_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/ca_openvz_template.lng | 97 ---- .../vm/lib/lang/ca_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/ca_openvz_vm.lng | 45 -- .../web/vm/lib/lang/ca_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/cz.lng | 7 - .../web/vm/lib/lang/cz_openvz_action.lng | 16 - interface/web/vm/lib/lang/cz_openvz_ip.lng | 9 - .../web/vm/lib/lang/cz_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/cz_openvz_ostemplate.lng | 11 - .../vm/lib/lang/cz_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/cz_openvz_template.lng | 97 ---- .../vm/lib/lang/cz_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/cz_openvz_vm.lng | 45 -- .../web/vm/lib/lang/cz_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/de.lng | 7 - .../web/vm/lib/lang/de_openvz_action.lng | 16 - interface/web/vm/lib/lang/de_openvz_ip.lng | 9 - .../web/vm/lib/lang/de_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/de_openvz_ostemplate.lng | 11 - .../vm/lib/lang/de_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/de_openvz_template.lng | 97 ---- .../vm/lib/lang/de_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/de_openvz_vm.lng | 45 -- .../web/vm/lib/lang/de_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/dk.lng | 7 - .../web/vm/lib/lang/dk_openvz_action.lng | 16 - interface/web/vm/lib/lang/dk_openvz_ip.lng | 9 - .../web/vm/lib/lang/dk_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/dk_openvz_ostemplate.lng | 11 - .../vm/lib/lang/dk_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/dk_openvz_template.lng | 97 ---- .../vm/lib/lang/dk_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/dk_openvz_vm.lng | 45 -- .../web/vm/lib/lang/dk_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/el.lng | 7 - .../web/vm/lib/lang/el_openvz_action.lng | 16 - interface/web/vm/lib/lang/el_openvz_ip.lng | 9 - .../web/vm/lib/lang/el_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/el_openvz_ostemplate.lng | 11 - .../vm/lib/lang/el_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/el_openvz_template.lng | 97 ---- .../vm/lib/lang/el_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/el_openvz_vm.lng | 45 -- .../web/vm/lib/lang/el_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/en.lng | 7 - .../web/vm/lib/lang/en_openvz_action.lng | 17 - interface/web/vm/lib/lang/en_openvz_ip.lng | 9 - .../web/vm/lib/lang/en_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/en_openvz_ostemplate.lng | 11 - .../vm/lib/lang/en_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/en_openvz_template.lng | 97 ---- .../vm/lib/lang/en_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/en_openvz_vm.lng | 45 -- .../web/vm/lib/lang/en_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/es.lng | 7 - .../web/vm/lib/lang/es_openvz_action.lng | 16 - interface/web/vm/lib/lang/es_openvz_ip.lng | 9 - .../web/vm/lib/lang/es_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/es_openvz_ostemplate.lng | 11 - .../vm/lib/lang/es_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/es_openvz_template.lng | 97 ---- .../vm/lib/lang/es_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/es_openvz_vm.lng | 45 -- .../web/vm/lib/lang/es_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/fi.lng | 7 - .../web/vm/lib/lang/fi_openvz_action.lng | 16 - interface/web/vm/lib/lang/fi_openvz_ip.lng | 9 - .../web/vm/lib/lang/fi_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/fi_openvz_ostemplate.lng | 11 - .../vm/lib/lang/fi_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/fi_openvz_template.lng | 97 ---- .../vm/lib/lang/fi_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/fi_openvz_vm.lng | 45 -- .../web/vm/lib/lang/fi_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/fr.lng | 7 - .../web/vm/lib/lang/fr_openvz_action.lng | 16 - interface/web/vm/lib/lang/fr_openvz_ip.lng | 9 - .../web/vm/lib/lang/fr_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/fr_openvz_ostemplate.lng | 11 - .../vm/lib/lang/fr_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/fr_openvz_template.lng | 97 ---- .../vm/lib/lang/fr_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/fr_openvz_vm.lng | 45 -- .../web/vm/lib/lang/fr_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/hr.lng | 7 - .../web/vm/lib/lang/hr_openvz_action.lng | 16 - interface/web/vm/lib/lang/hr_openvz_ip.lng | 9 - .../web/vm/lib/lang/hr_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/hr_openvz_ostemplate.lng | 11 - .../vm/lib/lang/hr_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/hr_openvz_template.lng | 97 ---- .../vm/lib/lang/hr_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/hr_openvz_vm.lng | 45 -- .../web/vm/lib/lang/hr_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/hu.lng | 7 - .../web/vm/lib/lang/hu_openvz_action.lng | 16 - interface/web/vm/lib/lang/hu_openvz_ip.lng | 9 - .../web/vm/lib/lang/hu_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/hu_openvz_ostemplate.lng | 11 - .../vm/lib/lang/hu_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/hu_openvz_template.lng | 97 ---- .../vm/lib/lang/hu_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/hu_openvz_vm.lng | 45 -- .../web/vm/lib/lang/hu_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/id.lng | 7 - .../web/vm/lib/lang/id_openvz_action.lng | 16 - interface/web/vm/lib/lang/id_openvz_ip.lng | 9 - .../web/vm/lib/lang/id_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/id_openvz_ostemplate.lng | 11 - .../vm/lib/lang/id_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/id_openvz_template.lng | 97 ---- .../vm/lib/lang/id_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/id_openvz_vm.lng | 45 -- .../web/vm/lib/lang/id_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/it.lng | 7 - .../web/vm/lib/lang/it_openvz_action.lng | 16 - interface/web/vm/lib/lang/it_openvz_ip.lng | 9 - .../web/vm/lib/lang/it_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/it_openvz_ostemplate.lng | 11 - .../vm/lib/lang/it_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/it_openvz_template.lng | 97 ---- .../vm/lib/lang/it_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/it_openvz_vm.lng | 45 -- .../web/vm/lib/lang/it_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/ja.lng | 7 - .../web/vm/lib/lang/ja_openvz_action.lng | 16 - interface/web/vm/lib/lang/ja_openvz_ip.lng | 9 - .../web/vm/lib/lang/ja_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/ja_openvz_ostemplate.lng | 11 - .../vm/lib/lang/ja_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/ja_openvz_template.lng | 97 ---- .../vm/lib/lang/ja_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/ja_openvz_vm.lng | 45 -- .../web/vm/lib/lang/ja_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/nl.lng | 7 - .../web/vm/lib/lang/nl_openvz_action.lng | 16 - interface/web/vm/lib/lang/nl_openvz_ip.lng | 9 - .../web/vm/lib/lang/nl_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/nl_openvz_ostemplate.lng | 11 - .../vm/lib/lang/nl_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/nl_openvz_template.lng | 97 ---- .../vm/lib/lang/nl_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/nl_openvz_vm.lng | 45 -- .../web/vm/lib/lang/nl_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/pl.lng | 7 - .../web/vm/lib/lang/pl_openvz_action.lng | 16 - interface/web/vm/lib/lang/pl_openvz_ip.lng | 9 - .../web/vm/lib/lang/pl_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/pl_openvz_ostemplate.lng | 11 - .../vm/lib/lang/pl_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/pl_openvz_template.lng | 97 ---- .../vm/lib/lang/pl_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/pl_openvz_vm.lng | 45 -- .../web/vm/lib/lang/pl_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/pt.lng | 7 - .../web/vm/lib/lang/pt_openvz_action.lng | 16 - interface/web/vm/lib/lang/pt_openvz_ip.lng | 9 - .../web/vm/lib/lang/pt_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/pt_openvz_ostemplate.lng | 11 - .../vm/lib/lang/pt_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/pt_openvz_template.lng | 97 ---- .../vm/lib/lang/pt_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/pt_openvz_vm.lng | 45 -- .../web/vm/lib/lang/pt_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/ro.lng | 7 - .../web/vm/lib/lang/ro_openvz_action.lng | 16 - interface/web/vm/lib/lang/ro_openvz_ip.lng | 9 - .../web/vm/lib/lang/ro_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/ro_openvz_ostemplate.lng | 11 - .../vm/lib/lang/ro_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/ro_openvz_template.lng | 97 ---- .../vm/lib/lang/ro_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/ro_openvz_vm.lng | 45 -- .../web/vm/lib/lang/ro_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/ru.lng | 7 - .../web/vm/lib/lang/ru_openvz_action.lng | 16 - interface/web/vm/lib/lang/ru_openvz_ip.lng | 9 - .../web/vm/lib/lang/ru_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/ru_openvz_ostemplate.lng | 11 - .../vm/lib/lang/ru_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/ru_openvz_template.lng | 97 ---- .../vm/lib/lang/ru_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/ru_openvz_vm.lng | 45 -- .../web/vm/lib/lang/ru_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/se.lng | 7 - .../web/vm/lib/lang/se_openvz_action.lng | 16 - interface/web/vm/lib/lang/se_openvz_ip.lng | 9 - .../web/vm/lib/lang/se_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/se_openvz_ostemplate.lng | 11 - .../vm/lib/lang/se_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/se_openvz_template.lng | 97 ---- .../vm/lib/lang/se_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/se_openvz_vm.lng | 45 -- .../web/vm/lib/lang/se_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/sk.lng | 7 - .../web/vm/lib/lang/sk_openvz_action.lng | 16 - interface/web/vm/lib/lang/sk_openvz_ip.lng | 9 - .../web/vm/lib/lang/sk_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/sk_openvz_ostemplate.lng | 11 - .../vm/lib/lang/sk_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/sk_openvz_template.lng | 97 ---- .../vm/lib/lang/sk_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/sk_openvz_vm.lng | 45 -- .../web/vm/lib/lang/sk_openvz_vm_list.lng | 10 - interface/web/vm/lib/lang/tr.lng | 7 - .../web/vm/lib/lang/tr_openvz_action.lng | 16 - interface/web/vm/lib/lang/tr_openvz_ip.lng | 9 - .../web/vm/lib/lang/tr_openvz_ip_list.lng | 7 - .../web/vm/lib/lang/tr_openvz_ostemplate.lng | 11 - .../vm/lib/lang/tr_openvz_ostemplate_list.lng | 8 - .../web/vm/lib/lang/tr_openvz_template.lng | 97 ---- .../vm/lib/lang/tr_openvz_template_list.lng | 5 - interface/web/vm/lib/lang/tr_openvz_vm.lng | 45 -- .../web/vm/lib/lang/tr_openvz_vm_list.lng | 10 - interface/web/vm/lib/module.conf.php | 69 --- interface/web/vm/lib/remote.conf.php | 5 - interface/web/vm/list/openvz_ip.list.php | 100 ---- .../web/vm/list/openvz_ostemplate.list.php | 103 ---- .../web/vm/list/openvz_template.list.php | 70 --- interface/web/vm/list/openvz_vm.list.php | 132 ----- interface/web/vm/openvz_action.php | 129 ----- interface/web/vm/openvz_ip_del.php | 59 -- interface/web/vm/openvz_ip_edit.php | 59 -- interface/web/vm/openvz_ip_list.php | 55 -- interface/web/vm/openvz_ostemplate_del.php | 59 -- interface/web/vm/openvz_ostemplate_edit.php | 59 -- interface/web/vm/openvz_ostemplate_list.php | 55 -- interface/web/vm/openvz_template_del.php | 59 -- interface/web/vm/openvz_template_edit.php | 74 --- interface/web/vm/openvz_template_list.php | 55 -- interface/web/vm/openvz_vm_del.php | 58 -- interface/web/vm/openvz_vm_edit.php | 263 --------- interface/web/vm/openvz_vm_list.php | 54 -- interface/web/vm/templates/openvz.conf.tpl | 120 ---- interface/web/vm/templates/openvz_action.htm | 42 -- interface/web/vm/templates/openvz_ip_edit.htm | 42 -- interface/web/vm/templates/openvz_ip_list.htm | 60 -- .../vm/templates/openvz_ostemplate_edit.htm | 43 -- .../vm/templates/openvz_ostemplate_list.htm | 63 --- .../openvz_template_advanced_edit.htm | 92 --- .../web/vm/templates/openvz_template_edit.htm | 69 --- .../web/vm/templates/openvz_template_list.htm | 54 -- .../openvz_vm_additional_ip_edit.htm | 19 - .../vm/templates/openvz_vm_advanced_edit.htm | 72 --- interface/web/vm/templates/openvz_vm_edit.htm | 101 ---- interface/web/vm/templates/openvz_vm_list.htm | 70 --- .../examples/openvz_get_free_ip.php | 34 -- remoting_client/examples/openvz_ip_add.php | 40 -- remoting_client/examples/openvz_ip_delete.php | 36 -- remoting_client/examples/openvz_ip_get.php | 34 -- remoting_client/examples/openvz_ip_update.php | 42 -- .../examples/openvz_ostemplate_add.php | 42 -- .../examples/openvz_ostemplate_delete.php | 36 -- .../examples/openvz_ostemplate_get.php | 34 -- .../examples/openvz_ostemplate_update.php | 42 -- .../examples/openvz_template_add.php | 74 --- .../examples/openvz_template_delete.php | 36 -- .../examples/openvz_template_get.php | 34 -- .../examples/openvz_template_update.php | 42 -- remoting_client/examples/openvz_vm_add.php | 60 -- .../examples/openvz_vm_add_from_template.php | 45 -- remoting_client/examples/openvz_vm_delete.php | 36 -- remoting_client/examples/openvz_vm_get.php | 34 -- .../examples/openvz_vm_get_by_client.php | 34 -- remoting_client/examples/openvz_vm_update.php | 42 -- .../classes/cron.d/100-monitor_openvz.inc.php | 173 ------ server/lib/classes/cron.d/400-openvz.inc.php | 81 --- server/lib/classes/functions.inc.php | 6 - server/lib/classes/openvz_tools.inc.php | 153 ----- .../remoteaction_core_module.inc.php | 39 -- server/mods-available/vm_module.inc.php | 118 ---- .../plugins-available/openvz_plugin.inc.php | 212 ------- .../server_services_plugin.inc.php | 7 +- 362 files changed, 25 insertions(+), 11999 deletions(-) delete mode 100644 helper_scripts/setup_in_openvz/diff_openssl.cnf delete mode 100644 helper_scripts/setup_in_openvz/install_server.sh delete mode 100644 helper_scripts/setup_in_openvz/recreate_ssh_and_hostname.sh delete mode 100644 interface/lib/classes/remote.d/openvz.inc.php delete mode 100644 interface/lib/classes/validate_openvz.inc.php delete mode 100644 interface/lib/plugins/vm_openvz_plugin.inc.php delete mode 100644 interface/web/vm/ajax_get_ip.php delete mode 100644 interface/web/vm/form/openvz_ip.tform.php delete mode 100644 interface/web/vm/form/openvz_ostemplate.tform.php delete mode 100644 interface/web/vm/form/openvz_template.tform.php delete mode 100644 interface/web/vm/form/openvz_vm.tform.php delete mode 100644 interface/web/vm/lib/admin.conf.php delete mode 100644 interface/web/vm/lib/lang/ar.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/ar_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/bg.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/bg_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/br.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/br_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/ca.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/ca_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/cz.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/cz_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/de.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/de_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/dk.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/dk_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/el.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/el_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/en.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/en_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/es.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/es_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/fi.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/fi_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/fr.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/fr_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/hr.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/hr_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/hu.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/hu_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/id.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/id_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/it.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/it_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/ja.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/ja_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/nl.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/nl_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/pl.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/pl_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/pt.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/pt_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/ro.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/ro_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/ru.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/ru_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/se.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/se_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/sk.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/sk_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/lang/tr.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_action.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_ip.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_ip_list.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_ostemplate.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_ostemplate_list.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_template.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_template_list.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_vm.lng delete mode 100644 interface/web/vm/lib/lang/tr_openvz_vm_list.lng delete mode 100644 interface/web/vm/lib/module.conf.php delete mode 100644 interface/web/vm/lib/remote.conf.php delete mode 100644 interface/web/vm/list/openvz_ip.list.php delete mode 100644 interface/web/vm/list/openvz_ostemplate.list.php delete mode 100644 interface/web/vm/list/openvz_template.list.php delete mode 100644 interface/web/vm/list/openvz_vm.list.php delete mode 100644 interface/web/vm/openvz_action.php delete mode 100644 interface/web/vm/openvz_ip_del.php delete mode 100644 interface/web/vm/openvz_ip_edit.php delete mode 100644 interface/web/vm/openvz_ip_list.php delete mode 100644 interface/web/vm/openvz_ostemplate_del.php delete mode 100644 interface/web/vm/openvz_ostemplate_edit.php delete mode 100644 interface/web/vm/openvz_ostemplate_list.php delete mode 100644 interface/web/vm/openvz_template_del.php delete mode 100644 interface/web/vm/openvz_template_edit.php delete mode 100644 interface/web/vm/openvz_template_list.php delete mode 100644 interface/web/vm/openvz_vm_del.php delete mode 100644 interface/web/vm/openvz_vm_edit.php delete mode 100644 interface/web/vm/openvz_vm_list.php delete mode 100644 interface/web/vm/templates/openvz.conf.tpl delete mode 100644 interface/web/vm/templates/openvz_action.htm delete mode 100644 interface/web/vm/templates/openvz_ip_edit.htm delete mode 100644 interface/web/vm/templates/openvz_ip_list.htm delete mode 100644 interface/web/vm/templates/openvz_ostemplate_edit.htm delete mode 100644 interface/web/vm/templates/openvz_ostemplate_list.htm delete mode 100644 interface/web/vm/templates/openvz_template_advanced_edit.htm delete mode 100644 interface/web/vm/templates/openvz_template_edit.htm delete mode 100644 interface/web/vm/templates/openvz_template_list.htm delete mode 100644 interface/web/vm/templates/openvz_vm_additional_ip_edit.htm delete mode 100644 interface/web/vm/templates/openvz_vm_advanced_edit.htm delete mode 100644 interface/web/vm/templates/openvz_vm_edit.htm delete mode 100644 interface/web/vm/templates/openvz_vm_list.htm delete mode 100644 remoting_client/examples/openvz_get_free_ip.php delete mode 100644 remoting_client/examples/openvz_ip_add.php delete mode 100644 remoting_client/examples/openvz_ip_delete.php delete mode 100644 remoting_client/examples/openvz_ip_get.php delete mode 100644 remoting_client/examples/openvz_ip_update.php delete mode 100644 remoting_client/examples/openvz_ostemplate_add.php delete mode 100644 remoting_client/examples/openvz_ostemplate_delete.php delete mode 100644 remoting_client/examples/openvz_ostemplate_get.php delete mode 100644 remoting_client/examples/openvz_ostemplate_update.php delete mode 100644 remoting_client/examples/openvz_template_add.php delete mode 100644 remoting_client/examples/openvz_template_delete.php delete mode 100644 remoting_client/examples/openvz_template_get.php delete mode 100644 remoting_client/examples/openvz_template_update.php delete mode 100644 remoting_client/examples/openvz_vm_add.php delete mode 100644 remoting_client/examples/openvz_vm_add_from_template.php delete mode 100644 remoting_client/examples/openvz_vm_delete.php delete mode 100644 remoting_client/examples/openvz_vm_get.php delete mode 100644 remoting_client/examples/openvz_vm_get_by_client.php delete mode 100644 remoting_client/examples/openvz_vm_update.php delete mode 100644 server/lib/classes/cron.d/100-monitor_openvz.inc.php delete mode 100644 server/lib/classes/cron.d/400-openvz.inc.php delete mode 100644 server/lib/classes/openvz_tools.inc.php delete mode 100644 server/mods-available/vm_module.inc.php delete mode 100644 server/plugins-available/openvz_plugin.inc.php diff --git a/docs/autoinstall_samples/autoinstall.conf_sample.php b/docs/autoinstall_samples/autoinstall.conf_sample.php index c7b539375..922664629 100644 --- a/docs/autoinstall_samples/autoinstall.conf_sample.php +++ b/docs/autoinstall_samples/autoinstall.conf_sample.php @@ -58,7 +58,6 @@ $autoupdate['svc_detect_change_mail_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_web_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_dns_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_firewall_server'] = 'yes'; // yes (default), no -$autoupdate['svc_detect_change_vserver_server'] = 'yes'; // yes (default), no $autoupdate['svc_detect_change_db_server'] = 'yes'; // yes (default), no ?> \ No newline at end of file diff --git a/helper_scripts/setup_in_openvz/diff_openssl.cnf b/helper_scripts/setup_in_openvz/diff_openssl.cnf deleted file mode 100644 index 4a3c7e6aa..000000000 --- a/helper_scripts/setup_in_openvz/diff_openssl.cnf +++ /dev/null @@ -1,25 +0,0 @@ -# diff openssl.cnf /usr/lib/ssl/openssl.cnf -68c68 -< default_days = 3653 # how long to certify for ---- -> default_days = 365 # how long to certify for -125c125 -< countryName_default = YOURCOUNTRY ---- -> countryName_default = AU -130c130 -< stateOrProvinceName_default = YOURPROVINCE ---- -> stateOrProvinceName_default = Some-State -135c135 -< 0.organizationName_default = YOURDOMAIN ---- -> 0.organizationName_default = Internet Widgits Pty Ltd -142c142 -< organizationalUnitName_default = ISP ---- -> #organizationalUnitName_default = -145d144 -< commonName_default = YOURHOSTNAME -149d147 -< emailAddress_default = postmaster@YOURDOMAIN diff --git a/helper_scripts/setup_in_openvz/install_server.sh b/helper_scripts/setup_in_openvz/install_server.sh deleted file mode 100644 index 1cc058417..000000000 --- a/helper_scripts/setup_in_openvz/install_server.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# Script to configuring an ispconfig3 server in a Debian VPS -# by calocen [at] gmail [dot] com - -# getting some enviromment values -myhostname=`hostname -f` -mydomain=`hostname -d` -myip=`hostname -i` -[ ! -x /usr/bin/geoiplookup ] && apt-get --assume-yes install geoip-bin -mycountry=`geoiplookup $myip | cut -f4 -d" " | cut -f1 -d","` -myprovince=`geoiplookup $myip | cut -f5 -d" "` - -# reconfiguring webalizer, postfix -# could be cool to modify here webalizer values -dpkg-reconfigure -u webalizer -postconf -e "myhostname = $myhostname" -postconf -e "mydestination = $myhostname, localhost" -echo $myhostname > /etc/mailname -dpkg-reconfigure -u postfix - -# request new password -oldpwd=`grep password /root/.my.cnf | tr "\t" " " | tr -s " " | cut -f3 -d" "` -read -p "mysql password: [$oldpwd] " mysqlpwd -[ -z $mysqlpwd ] && mysqlpwd=$oldpwd -echo $mysqlpwd -#read -p "Are you sure? (y/n) " sure -## who said fear ## -set -x -mysqladmin -u root -p$oldpwd password $mysqlpwd -mysqladmin -u root -p$mysqlpwd -h localhost password $mysqlpwd -cat << EOF > /root/.my.cnf -[client] -password = $mysqlpwd -EOF -chmod 600 /root/.my.cnf - -# changing mydns password -mysql -e "SET PASSWORD FOR 'mydns'@'%' = PASSWORD( '$mysqlpwd' )" -mysql -e "SET PASSWORD FOR 'mydns'@'localhost' = PASSWORD( '$mysqlpwd' )" -cp -ax /etc/mydns.conf /etc/mydns.conf~ -sed s/$oldpwd/$mysqlpwd/g < /etc/mydns.conf~ > /etc/mydns.conf - -# enabling mydns -mydns --create-tables > /tmp/mydns.sql -mysql -e "CREATE DATABASE IF NOT EXISTS mydns ; USE mydns ; SOURCE /tmp/mydns.sql;" -rm /tmp/mydns.* -invoke-rc.d mydns restart - -# preparing server installation -mv /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf~ -sed s/"YOURHOSTNAME"/"$myhostname"/g < /usr/local/bin/openssl.cnf | -sed s/"YOURDOMAIN"/"$mydomain"/g | \ -sed s/"YOURCOUNTRY"/"$mycountry"/g | \ -sed s/"YOURPROVINCE"/"$myprovince"/g > /etc/ssl/openssl.cnf - -tar xfz /root/downloads/ISPConfig-3.0.0.7-beta.tar.gz -C /usr/local/src -# here would be some stuff to update from SVN -cd /usr/local/src/ispconfig3_install/install/ -php -q install.php - - diff --git a/helper_scripts/setup_in_openvz/recreate_ssh_and_hostname.sh b/helper_scripts/setup_in_openvz/recreate_ssh_and_hostname.sh deleted file mode 100644 index 72c2ab61a..000000000 --- a/helper_scripts/setup_in_openvz/recreate_ssh_and_hostname.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -set -x -echo "" > /etc/resolv.conf -echo "" > /etc/hostname -echo "" > /etc/mailname -rm -f /etc/ssh/ssh_host_* -cat << EOF > /etc/rc2.d/S15ssh_gen_host_keys -#!/bin/bash -ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N '' -ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t dsa -N '' -dpkg-reconfigure -u webalizer -postconf -e "myhostname = $(hostname -f)" -postconf -e "mydestination = $(hostname -f), localhost" -echo $(hostname -f) > /etc/mailname -dpkg-reconfigure -u postfix -rm -f \$0 -EOF -chmod a+x /etc/rc2.d/S15ssh_gen_host_keys diff --git a/install/dist/conf/centos70.conf.php b/install/dist/conf/centos70.conf.php index eaf0ba612..638c19239 100644 --- a/install/dist/conf/centos70.conf.php +++ b/install/dist/conf/centos70.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -193,8 +192,3 @@ $conf['vlogger']['config_dir'] = '/etc'; $conf['cron']['init_script'] = 'crond'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - -?> diff --git a/install/dist/conf/centos72.conf.php b/install/dist/conf/centos72.conf.php index 0d88bcfb7..0e1bbec10 100644 --- a/install/dist/conf/centos72.conf.php +++ b/install/dist/conf/centos72.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -193,8 +192,3 @@ $conf['vlogger']['config_dir'] = '/etc'; $conf['cron']['init_script'] = 'crond'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - -?> diff --git a/install/dist/conf/debian40.conf.php b/install/dist/conf/debian40.conf.php index 0dcb1bffb..9957c8ff5 100644 --- a/install/dist/conf/debian40.conf.php +++ b/install/dist/conf/debian40.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -200,9 +199,3 @@ $conf['vlogger']['config_dir'] = '/etc'; $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - - -?> diff --git a/install/dist/conf/debian60.conf.php b/install/dist/conf/debian60.conf.php index adff0dcc7..ba5073415 100644 --- a/install/dist/conf/debian60.conf.php +++ b/install/dist/conf/debian60.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php5/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php5-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/conf/debian90.conf.php b/install/dist/conf/debian90.conf.php index eb3c646f8..cea999b17 100644 --- a/install/dist/conf/debian90.conf.php +++ b/install/dist/conf/debian90.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.0/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.0-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/conf/debiantesting.conf.php b/install/dist/conf/debiantesting.conf.php index 60030bfdc..f531b972e 100644 --- a/install/dist/conf/debiantesting.conf.php +++ b/install/dist/conf/debiantesting.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.0/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.0-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/conf/fedora9.conf.php b/install/dist/conf/fedora9.conf.php index 20824f1e7..ced8eca83 100644 --- a/install/dist/conf/fedora9.conf.php +++ b/install/dist/conf/fedora9.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -193,8 +192,3 @@ $conf['vlogger']['config_dir'] = '/etc'; $conf['cron']['init_script'] = 'crond'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - -?> diff --git a/install/dist/conf/gentoo.conf.php b/install/dist/conf/gentoo.conf.php index 585c1fc66..657bb4a64 100644 --- a/install/dist/conf/gentoo.conf.php +++ b/install/dist/conf/gentoo.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -206,8 +205,3 @@ $conf['cron']['init_script'] = 'vixie-cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['group'] = 'cron'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - -?> diff --git a/install/dist/conf/opensuse112.conf.php b/install/dist/conf/opensuse112.conf.php index 077f86718..323ed28df 100644 --- a/install/dist/conf/opensuse112.conf.php +++ b/install/dist/conf/opensuse112.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; //* MySQL $conf['mysql']['installed'] = false; // will be detected automatically during installation @@ -193,8 +192,3 @@ $conf['vlogger']['config_dir'] = '/etc'; $conf['cron']['init_script'] = 'cron'; $conf['cron']['crontab_dir'] = '/etc/cron.d'; $conf['cron']['wget'] = '/usr/bin/wget'; - -//* OpenVZ -$conf['openvz']['installed'] = false; - -?> diff --git a/install/dist/conf/ubuntu1604.conf.php b/install/dist/conf/ubuntu1604.conf.php index 2ef53324b..c65216ab6 100644 --- a/install/dist/conf/ubuntu1604.conf.php +++ b/install/dist/conf/ubuntu1604.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.0/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.0-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/conf/ubuntu1710.conf.php b/install/dist/conf/ubuntu1710.conf.php index 555765b3b..490ee2868 100644 --- a/install/dist/conf/ubuntu1710.conf.php +++ b/install/dist/conf/ubuntu1710.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.1/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.1-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/conf/ubuntu1804.conf.php b/install/dist/conf/ubuntu1804.conf.php index 363014a98..dfae088e7 100644 --- a/install/dist/conf/ubuntu1804.conf.php +++ b/install/dist/conf/ubuntu1804.conf.php @@ -50,7 +50,6 @@ $conf['services']['web'] = true; $conf['services']['dns'] = true; $conf['services']['file'] = true; $conf['services']['db'] = true; -$conf['services']['vserver'] = true; $conf['services']['proxy'] = false; $conf['services']['firewall'] = false; @@ -188,9 +187,6 @@ $conf['nginx']['php_fpm_pool_dir'] = '/etc/php/7.2/fpm/pool.d'; $conf['nginx']['php_fpm_start_port'] = 9010; $conf['nginx']['php_fpm_socket_dir'] = '/var/lib/php7.2-fpm'; -//* OpenVZ -$conf['openvz']['installed'] = false; - //*Bastille-Firwall $conf['bastille']['installed'] = false; $conf['bastille']['config_dir'] = '/etc/Bastille'; diff --git a/install/dist/lib/fedora.lib.php b/install/dist/lib/fedora.lib.php index 10f6c3bf1..a6b23e384 100644 --- a/install/dist/lib/fedora.lib.php +++ b/install/dist/lib/fedora.lib.php @@ -972,12 +972,11 @@ class installer_dist extends installer_base { $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['services']['vserver'])?1:0; - $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ?, vserver_server = ? WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ? WHERE server_id = ?"; - $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { - $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); } // chown install dir to root and chmod 755 diff --git a/install/dist/lib/gentoo.lib.php b/install/dist/lib/gentoo.lib.php index af936e886..511ed6971 100644 --- a/install/dist/lib/gentoo.lib.php +++ b/install/dist/lib/gentoo.lib.php @@ -905,13 +905,12 @@ class installer extends installer_base $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['services']['vserver'])?1:0; - $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ?, vserver_server = ? WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ? WHERE server_id = ?"; - $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { - $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); } // chown install dir to root and chmod 755 diff --git a/install/dist/lib/opensuse.lib.php b/install/dist/lib/opensuse.lib.php index d1866b34e..0688471cd 100644 --- a/install/dist/lib/opensuse.lib.php +++ b/install/dist/lib/opensuse.lib.php @@ -980,12 +980,11 @@ class installer_dist extends installer_base { $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['services']['vserver'])?1:0; - $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ?, vserver_server = ? WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = ?, web_server = ?, dns_server = ?, file_server = ?, db_server = ? WHERE server_id = ?"; - $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->db->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { - $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $conf['server_id']); + $this->dbmaster->query($sql, $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $conf['server_id']); } // chown install dir to root and chmod 755 diff --git a/install/install.php b/install/install.php index adcff706b..1199dedab 100644 --- a/install/install.php +++ b/install/install.php @@ -253,7 +253,6 @@ $conf['services']['web'] = false; $conf['services']['dns'] = false; $conf['services']['file'] = false; $conf['services']['db'] = true; -$conf['services']['vserver'] = false; $conf['services']['firewall'] = false; $conf['services']['proxy'] = false; @@ -451,13 +450,6 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Web } } -//* Configure OpenVZ -$force = @($conf['openvz']['installed']) ? true : $inst->force_configure_app('OpenVZ', ($install_mode == 'expert')); -if($force) { - $conf['services']['vserver'] = true; - swriteln('Configuring OpenVZ'); -} - if($install_mode == 'standard' || strtolower($inst->simple_query('Configure Firewall Server', array('y', 'n'), 'y','configure_firewall')) == 'y') { //* Check for Firewall if(!$conf['ufw']['installed'] && !$conf['firewall']['installed']) { diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 46608c226..3a7a4ebea 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -172,7 +172,6 @@ class installer_base { $conf['firewall']['installed'] = true; } if(is_installed('fail2ban-server')) $conf['fail2ban']['installed'] = true; - if(is_installed('vzctl')) $conf['openvz']['installed'] = true; if(is_installed('metronome') && is_installed('metronomectl')) $conf['metronome']['installed'] = true; if(is_installed('prosody') && is_installed('prosodyctl')) $conf['prosody']['installed'] = true; if(is_installed('spamassassin')) $conf['spamassassin']['installed'] = true; @@ -350,7 +349,6 @@ class installer_base { $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['openvz']['installed'])?1:0; $proxy_server_enabled = (isset($conf['services']['proxy']) && $conf['services']['proxy'])?1:0; $firewall_server_enabled = (isset($conf['services']['firewall']) && $conf['services']['firewall'])?1:0; @@ -372,14 +370,14 @@ class installer_base { if($conf['mysql']['master_slave_setup'] == 'y') { //* Insert the server record in master DB - $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; - $this->dbmaster->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); + $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; + $this->dbmaster->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); $conf['server_id'] = $this->dbmaster->insertID(); $conf['server_id'] = $conf['server_id']; //* Insert the same record in the local DB - $sql = "INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (?,1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; - $this->db->query($sql, $conf['server_id'], $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); + $sql = "INSERT INTO `server` (`server_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server``, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (?,1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; + $this->db->query($sql, $conf['server_id'], $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); //* username for the ispconfig user $conf['mysql']['master_ispconfig_user'] = 'ispcsrv'.$conf['server_id']; @@ -388,8 +386,8 @@ class installer_base { } else { //* Insert the server, if its not a mster / slave setup - $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `vserver_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; - $this->db->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $vserver_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); + $sql = "INSERT INTO `server` (`sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `server_name`, `mail_server`, `web_server`, `dns_server`, `file_server`, `db_server`, `config`, `updated`, `active`, `dbversion`,`firewall_server`,`proxy_server`) VALUES (1, 1, 'riud', 'riud', 'r', ?, ?, ?, ?, ?, ?, ?, ?, 0, 1, ?, ?, ?);"; + $this->db->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); $conf['server_id'] = $this->db->insertID(); $conf['server_id'] = $conf['server_id']; } @@ -2087,11 +2085,10 @@ class installer_base { $dns_server_enabled = ($conf['services']['dns'])?1:0; $file_server_enabled = ($conf['services']['file'])?1:0; $db_server_enabled = ($conf['services']['db'])?1:0; - $vserver_server_enabled = ($conf['openvz']['installed'])?1:0; $proxy_server_enabled = ($conf['services']['proxy'])?1:0; $firewall_server_enabled = ($conf['services']['firewall'])?1:0; - $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', vserver_server = '$vserver_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled WHERE server_id = ?"; + $sql = "UPDATE `server` SET mail_server = '$mail_server_enabled', web_server = '$web_server_enabled', dns_server = '$dns_server_enabled', file_server = '$file_server_enabled', db_server = '$db_server_enabled', proxy_server = '$proxy_server_enabled', firewall_server = '$firewall_server_enabled WHERE server_id = ?"; $this->db->query($sql, $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index 2342291ab..74b3b2063 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -154,7 +154,6 @@ function updateDbAndIni() { $conf['services']['dns'] = ($tmp['dns_server'] == 1)?true:false; $conf['services']['file'] = ($tmp['file_server'] == 1)?true:false; $conf['services']['db'] = ($tmp['db_server'] == 1)?true:false; - $conf['services']['vserver'] = ($tmp['vserver_server'] == 1)?true:false; $conf['services']['proxy'] = (isset($tmp['proxy_server']) && $tmp['proxy_server'] == 1)?true:false; $conf['services']['firewall'] = (isset($tmp['firewall_server']) && $tmp['firewall_server'] == 1)?true:false; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index c9702b00a..bed58a44f 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -226,8 +226,6 @@ CREATE TABLE `client` ( `limit_traffic_quota` int(11) NOT NULL DEFAULT '-1', `limit_client` int(11) NOT NULL DEFAULT '0', `limit_domainmodule` int(11) NOT NULL DEFAULT '0', - `limit_openvz_vm` int(11) NOT NULL DEFAULT '0', - `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0', `parent_client_id` int(11) unsigned NOT NULL DEFAULT '0', `username` varchar(64) DEFAULT NULL, `password` varchar(64) DEFAULT NULL, @@ -341,8 +339,6 @@ CREATE TABLE `client_template` ( `limit_traffic_quota` int(11) NOT NULL default '-1', `limit_client` int(11) NOT NULL default '0', `limit_domainmodule` int(11) NOT NULL DEFAULT '0', - `limit_openvz_vm` int(11) NOT NULL DEFAULT '0', - `limit_openvz_vm_template_id` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`template_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; @@ -1063,188 +1059,6 @@ CREATE TABLE `monitor_data` ( -- -------------------------------------------------------- --- --- Table structure for table `openvz_ip` --- - -CREATE TABLE IF NOT EXISTS `openvz_ip` ( - `ip_address_id` bigint(20) NOT NULL AUTO_INCREMENT, - `sys_userid` int(11) NOT NULL DEFAULT '0', - `sys_groupid` int(11) NOT NULL DEFAULT '0', - `sys_perm_user` varchar(5) DEFAULT NULL, - `sys_perm_group` varchar(5) DEFAULT NULL, - `sys_perm_other` varchar(5) DEFAULT NULL, - `server_id` int(11) NOT NULL DEFAULT '0', - `ip_address` varchar(39) DEFAULT NULL, - `vm_id` int(11) NOT NULL DEFAULT '0', - `reserved` varchar(255) NOT NULL DEFAULT 'n', - `additional` varchar(255) NOT NULL DEFAULT 'n', - PRIMARY KEY (`ip_address_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; - --- --- Dumping data for table `openvz_ip` --- - --- -------------------------------------------------------- - --- --- Table structure for table `openvz_ostemplate` --- - -CREATE TABLE IF NOT EXISTS `openvz_ostemplate` ( - `ostemplate_id` bigint(20) NOT NULL AUTO_INCREMENT, - `sys_userid` int(11) NOT NULL DEFAULT '0', - `sys_groupid` int(11) NOT NULL DEFAULT '0', - `sys_perm_user` varchar(5) DEFAULT NULL, - `sys_perm_group` varchar(5) DEFAULT NULL, - `sys_perm_other` varchar(5) DEFAULT NULL, - `template_name` varchar(255) DEFAULT NULL, - `template_file` varchar(255) NOT NULL DEFAULT '', - `server_id` int(11) NOT NULL DEFAULT '0', - `allservers` varchar(255) NOT NULL DEFAULT 'y', - `active` varchar(255) NOT NULL DEFAULT 'y', - `description` text, - PRIMARY KEY (`ostemplate_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; - --- --- Dumping data for table `openvz_ostemplate` --- - -INSERT INTO `openvz_ostemplate` (`ostemplate_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `template_name`, `template_file`, `server_id`, `allservers`, `active`, `description`) VALUES(1, 1, 1, 'riud', 'riud', '', 'Debian minimal', 'debian-minimal-x86', 1, 'y', 'y', 'Debian minimal image.'); - --- -------------------------------------------------------- - --- --- Table structure for table `openvz_template` --- - -CREATE TABLE IF NOT EXISTS `openvz_template` ( - `template_id` bigint(20) NOT NULL AUTO_INCREMENT, - `sys_userid` int(11) NOT NULL DEFAULT '0', - `sys_groupid` int(11) NOT NULL DEFAULT '0', - `sys_perm_user` varchar(5) DEFAULT NULL, - `sys_perm_group` varchar(5) DEFAULT NULL, - `sys_perm_other` varchar(5) DEFAULT NULL, - `template_name` varchar(255) DEFAULT NULL, - `diskspace` int(11) NOT NULL DEFAULT '0', - `traffic` int(11) NOT NULL DEFAULT '-1', - `bandwidth` int(11) NOT NULL DEFAULT '-1', - `ram` int(11) NOT NULL DEFAULT '0', - `ram_burst` int(11) NOT NULL DEFAULT '0', - `cpu_units` int(11) NOT NULL DEFAULT '1000', - `cpu_num` int(11) NOT NULL DEFAULT '4', - `cpu_limit` int(11) NOT NULL DEFAULT '400', - `io_priority` int(11) NOT NULL DEFAULT '4', - `active` varchar(255) NOT NULL DEFAULT 'y', - `description` text, - `numproc` varchar(255) DEFAULT NULL, - `numtcpsock` varchar(255) DEFAULT NULL, - `numothersock` varchar(255) DEFAULT NULL, - `vmguarpages` varchar(255) DEFAULT NULL, - `kmemsize` varchar(255) DEFAULT NULL, - `tcpsndbuf` varchar(255) DEFAULT NULL, - `tcprcvbuf` varchar(255) DEFAULT NULL, - `othersockbuf` varchar(255) DEFAULT NULL, - `dgramrcvbuf` varchar(255) DEFAULT NULL, - `oomguarpages` varchar(255) DEFAULT NULL, - `privvmpages` varchar(255) DEFAULT NULL, - `lockedpages` varchar(255) DEFAULT NULL, - `shmpages` varchar(255) DEFAULT NULL, - `physpages` varchar(255) DEFAULT NULL, - `numfile` varchar(255) DEFAULT NULL, - `avnumproc` varchar(255) DEFAULT NULL, - `numflock` varchar(255) DEFAULT NULL, - `numpty` varchar(255) DEFAULT NULL, - `numsiginfo` varchar(255) DEFAULT NULL, - `dcachesize` varchar(255) DEFAULT NULL, - `numiptent` varchar(255) DEFAULT NULL, - `swappages` varchar(255) DEFAULT NULL, - `hostname` varchar(255) DEFAULT NULL, - `nameserver` varchar(255) DEFAULT NULL, - `create_dns` varchar(1) NOT NULL DEFAULT 'n', - `capability` varchar(255) DEFAULT NULL, - `features` varchar(255) DEFAULT NULL, - `iptables` varchar(255) DEFAULT NULL, - `custom` text, - PRIMARY KEY (`template_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; - --- --- Dumping data for table `openvz_template` --- - -INSERT INTO `openvz_template` (`template_id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `sys_perm_group`, `sys_perm_other`, `template_name`, `diskspace`, `traffic`, `bandwidth`, `ram`, `ram_burst`, `cpu_units`, `cpu_num`, `cpu_limit`, `io_priority`, `active`, `description`, `numproc`, `numtcpsock`, `numothersock`, `vmguarpages`, `kmemsize`, `tcpsndbuf`, `tcprcvbuf`, `othersockbuf`, `dgramrcvbuf`, `oomguarpages`, `privvmpages`, `lockedpages`, `shmpages`, `physpages`, `numfile`, `avnumproc`, `numflock`, `numpty`, `numsiginfo`, `dcachesize`, `numiptent`, `swappages`, `hostname`, `nameserver`, `create_dns`, `capability`, `features`, `iptables`, `custom`) VALUES(1, 1, 1, 'riud', 'riud', '', 'small', 10, -1, -1, 256, 512, 1000, 4, 400, 4, 'y', '', '999999:999999', '7999992:7999992', '7999992:7999992', '65536:unlimited', '2147483646:2147483646', '214748160:396774400', '214748160:396774400', '214748160:396774400', '214748160:396774400', '65536:65536', '131072:139264', '999999:999999', '65536:65536', '0:2147483647', '23999976:23999976', '180:180', '999999:999999', '500000:500000', '999999:999999', '2147483646:2147483646', '999999:999999', '256000:256000', 'v{VEID}.test.tld', '8.8.8.8 8.8.4.4', 'n', '', '', '', ''); - --- -------------------------------------------------------- - --- --- Table structure for table `openvz_traffic` --- - -CREATE TABLE IF NOT EXISTS `openvz_traffic` ( - `veid` int(11) NOT NULL DEFAULT '0', - `traffic_date` date NULL DEFAULT NULL, - `traffic_bytes` bigint(32) unsigned NOT NULL DEFAULT '0', - UNIQUE KEY (`veid`,`traffic_date`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; - --- --- Dumping data for table `openvz_traffic` --- - - --- -------------------------------------------------------- - --- --- Table structure for table `openvz_vm` --- - -CREATE TABLE IF NOT EXISTS `openvz_vm` ( - `vm_id` bigint(20) NOT NULL AUTO_INCREMENT, - `sys_userid` int(11) NOT NULL DEFAULT '0', - `sys_groupid` int(11) NOT NULL DEFAULT '0', - `sys_perm_user` varchar(5) DEFAULT NULL, - `sys_perm_group` varchar(5) DEFAULT NULL, - `sys_perm_other` varchar(5) DEFAULT NULL, - `server_id` int(11) NOT NULL DEFAULT '0', - `veid` int(10) unsigned NOT NULL DEFAULT '0', - `ostemplate_id` int(11) NOT NULL DEFAULT '0', - `template_id` int(11) NOT NULL DEFAULT '0', - `ip_address` varchar(255) NOT NULL DEFAULT '', - `hostname` varchar(255) DEFAULT NULL, - `vm_password` varchar(255) DEFAULT NULL, - `start_boot` varchar(255) NOT NULL DEFAULT 'y', - `bootorder` int(11) NOT NULL DEFAULT '1', - `active` varchar(255) NOT NULL DEFAULT 'y', - `active_until_date` date NULL DEFAULT NULL, - `description` text, - `diskspace` int(11) NOT NULL DEFAULT '0', - `traffic` int(11) NOT NULL DEFAULT '-1', - `bandwidth` int(11) NOT NULL DEFAULT '-1', - `ram` int(11) NOT NULL DEFAULT '0', - `ram_burst` int(11) NOT NULL DEFAULT '0', - `cpu_units` int(11) NOT NULL DEFAULT '1000', - `cpu_num` int(11) NOT NULL DEFAULT '4', - `cpu_limit` int(11) NOT NULL DEFAULT '400', - `io_priority` int(11) NOT NULL DEFAULT '4', - `nameserver` varchar(255) NOT NULL DEFAULT '8.8.8.8 8.8.4.4', - `create_dns` varchar(1) NOT NULL DEFAULT 'n', - `capability` text, - `features` text, - `iptabless` text, - `config` mediumtext, - `custom` text, - PRIMARY KEY (`vm_id`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; - --- --- Dumping data for table `openvz_vm` --- - --- -------------------------------------------------------- - -- -- Table structure for table `remote_session` -- @@ -1298,7 +1112,6 @@ CREATE TABLE `server` ( `dns_server` tinyint(1) NOT NULL default '0', `file_server` tinyint(1) NOT NULL default '0', `db_server` tinyint(1) NOT NULL default '0', - `vserver_server` tinyint(1) NOT NULL default '0', `proxy_server` tinyint(1) NOT NULL default '0', `firewall_server` tinyint(1) NOT NULL default '0', `config` text, diff --git a/install/update.php b/install/update.php index 01a3799dc..a28228931 100644 --- a/install/update.php +++ b/install/update.php @@ -324,18 +324,17 @@ if($reconfigure_master_database_rights_answer == 'yes') { $inst->find_installed_apps(); //** Check for current service config state and compare to our results -if ($conf['mysql']['master_slave_setup'] == 'y') $current_svc_config = $inst->dbmaster->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf['mysql']['master_database'] . '.server', $conf['server_id']); -else $current_svc_config = $inst->db->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,vserver_server,db_server FROM ?? WHERE server_id=?", $conf["mysql"]["database"] . '.server', $conf['server_id']); +if ($conf['mysql']['master_slave_setup'] == 'y') $current_svc_config = $inst->dbmaster->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,db_server FROM ?? WHERE server_id=?", $conf['mysql']['master_database'] . '.server', $conf['server_id']); +else $current_svc_config = $inst->db->queryOneRecord("SELECT mail_server,web_server,dns_server,firewall_server,db_server FROM ?? WHERE server_id=?", $conf["mysql"]["database"] . '.server', $conf['server_id']); $conf['services']['mail'] = check_service_config_state('mail_server', $conf['postfix']['installed']); $conf['services']['dns'] = check_service_config_state('dns_server', ($conf['powerdns']['installed'] || $conf['bind']['installed'] || $conf['mydns']['installed'])); $conf['services']['web'] = check_service_config_state('web_server', ($conf['apache']['installed'] || $conf['nginx']['installed'])); $conf['services']['firewall'] = check_service_config_state('firewall_server', ($conf['ufw']['installed'] || $conf['firewall']['installed'])); -$conf['services']['vserver'] = check_service_config_state('vserver_server', $conf['services']['vserver']); $conf['services']['db'] = check_service_config_state('db_server', true); /* Will always offer as MySQL is of course installed on this host as it's a requirement for ISPC to work... */ unset($current_svc_config); //** Write new decisions into DB -$sql = "UPDATE ?? SET mail_server = '{$conf['services']['mail']}', web_server = '{$conf['services']['web']}', dns_server = '{$conf['services']['dns']}', file_server = '{$conf['services']['file']}', db_server = '{$conf['services']['db']}', vserver_server = '{$conf['services']['vserver']}', proxy_server = '{$conf['services']['proxy']}', firewall_server = '$firewall_server_enabled' WHERE server_id = ?"; +$sql = "UPDATE ?? SET mail_server = '{$conf['services']['mail']}', web_server = '{$conf['services']['web']}', dns_server = '{$conf['services']['dns']}', file_server = '{$conf['services']['file']}', db_server = '{$conf['services']['db']}', proxy_server = '{$conf['services']['proxy']}', firewall_server = '$firewall_server_enabled' WHERE server_id = ?"; $inst->db->query($sql, $conf['mysql']['database'].'.server', $conf['server_id']); if($conf['mysql']['master_slave_setup'] == 'y') { $inst->dbmaster->query($sql, $conf['mysql']['master_database'].'.server', $conf['server_id']); diff --git a/interface/lib/classes/custom_datasource.inc.php b/interface/lib/classes/custom_datasource.inc.php index f31296882..dc3e9e837 100644 --- a/interface/lib/classes/custom_datasource.inc.php +++ b/interface/lib/classes/custom_datasource.inc.php @@ -136,9 +136,6 @@ class custom_datasource { case 'default_dbserver': $field = 'db_server'; break; - case 'default_vserverserver': - $field = 'vserver_server'; - break; case 'mail_servers': $field = 'mail_server'; break; diff --git a/interface/lib/classes/functions.inc.php b/interface/lib/classes/functions.inc.php index a86057a06..bace18f44 100644 --- a/interface/lib/classes/functions.inc.php +++ b/interface/lib/classes/functions.inc.php @@ -232,12 +232,6 @@ class functions { } } - $results = $app->db->queryAllRecords("SELECT ip_address AS ip FROM openvz_ip"); - if(!empty($results) && is_array($results)){ - foreach($results as $result){ - if(preg_match($regex, $result['ip'])) $ips[] = $result['ip']; - } - } $results = $groupid != 1 ? $app->db->queryAllRecords("SELECT rr.data AS server_ip, rr.name as server_name, soa.origin as domain FROM dns_rr as rr, dns_soa as soa WHERE (rr.type = 'A' OR rr.type = 'AAAA') AND soa.id = rr.zone AND rr.sys_groupid = ?", $groupid) : $results = $app->db->queryAllRecords("SELECT rr.data AS server_ip, rr.name as server_name, soa.origin as domain FROM dns_rr as rr, dns_soa as soa WHERE (rr.type = 'A' OR rr.type = 'AAAA') AND soa.id = rr.zone"); if(!empty($results) && is_array($results)){ diff --git a/interface/lib/classes/remote.d/openvz.inc.php b/interface/lib/classes/remote.d/openvz.inc.php deleted file mode 100644 index a4ef38ad7..000000000 --- a/interface/lib/classes/remote.d/openvz.inc.php +++ /dev/null @@ -1,480 +0,0 @@ - - -*/ - -class remoting_openvz extends remoting { - //* Functions for virtual machine management - - //* Get OpenVZ OStemplate details - public function openvz_ostemplate_get($session_id, $ostemplate_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_ostemplate.tform.php'); - return $app->remoting_lib->getDataRecord($ostemplate_id); - } - - //* Add a openvz ostemplate record - public function openvz_ostemplate_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - return $this->insertQuery('../vm/form/openvz_ostemplate.tform.php', $client_id, $params); - } - - //* Update openvz ostemplate record - public function openvz_ostemplate_update($session_id, $client_id, $ostemplate_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../vm/form/openvz_ostemplate.tform.php', $client_id, $ostemplate_id, $params); - return $affected_rows; - } - - //* Delete openvz ostemplate record - public function openvz_ostemplate_delete($session_id, $ostemplate_id) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../vm/form/openvz_ostemplate.tform.php', $ostemplate_id); - return $affected_rows; - } - - //* Get OpenVZ template details - public function openvz_template_get($session_id, $template_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_template.tform.php'); - return $app->remoting_lib->getDataRecord($template_id); - } - - //* Add a openvz template record - public function openvz_template_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - return $this->insertQuery('../vm/form/openvz_template.tform.php', $client_id, $params); - } - - //* Update openvz template record - public function openvz_template_update($session_id, $client_id, $template_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../vm/form/openvz_template.tform.php', $client_id, $template_id, $params); - return $affected_rows; - } - - //* Delete openvz template record - public function openvz_template_delete($session_id, $template_id) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../vm/form/openvz_template.tform.php', $template_id); - return $affected_rows; - } - - //* Get OpenVZ ip details - public function openvz_ip_get($session_id, $ip_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_ip.tform.php'); - return $app->remoting_lib->getDataRecord($ip_id); - } - - //* Get OpenVZ a free IP address - public function openvz_get_free_ip($session_id, $server_id = 0) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $server_id = $app->functions->intval($server_id); - - if($server_id > 0) { - $tmp = $app->db->queryOneRecord("SELECT ip_address_id, server_id, ip_address FROM openvz_ip WHERE reserved = 'n' AND vm_id = 0 AND server_id = ? LIMIT 0,1", $server_id); - } else { - $tmp = $app->db->queryOneRecord("SELECT ip_address_id, server_id, ip_address FROM openvz_ip WHERE reserved = 'n' AND vm_id = 0 LIMIT 0,1"); - } - - if(count($tmp) > 0) { - return $tmp; - } else { - throw new SoapFault('no_free_ip', 'There is no free IP available.'); - } - } - - //* Add a openvz ip record - public function openvz_ip_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - return $this->insertQuery('../vm/form/openvz_ip.tform.php', $client_id, $params); - } - - //* Update openvz ip record - public function openvz_ip_update($session_id, $client_id, $ip_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../vm/form/openvz_ip.tform.php', $client_id, $ip_id, $params); - return $affected_rows; - } - - //* Delete openvz ip record - public function openvz_ip_delete($session_id, $ip_id) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../vm/form/openvz_ip.tform.php', $ip_id); - return $affected_rows; - } - - //* Get OpenVZ vm details - public function openvz_vm_get($session_id, $vm_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_vm.tform.php'); - return $app->remoting_lib->getDataRecord($vm_id); - } - - //* Get OpenVZ list - public function openvz_vm_get_by_client($session_id, $client_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - if (!empty($client_id)) { - $client_id = $app->functions->intval($client_id); - $tmp = $app->db->queryOneRecord("SELECT groupid FROM sys_group WHERE client_id = ?", $client_id); - $sql = "SELECT * FROM openvz_vm WHERE sys_groupid = ?"; - $result = $app->db->queryAllRecords($sql, $tmp['groupid']); - return $result; - } - return false; - } - - //* Add a openvz vm record - public function openvz_vm_add($session_id, $client_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - return $this->insertQuery('../vm/form/openvz_vm.tform.php', $client_id, $params); - } - - //* Add a openvz vm record from template - public function openvz_vm_add_from_template($session_id, $client_id, $ostemplate_id, $template_id, $override_params = array()) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - - $template_id = $app->functions->intval($template_id); - $ostemplate_id = $app->functions->intval($ostemplate_id); - - //* Verify parameters - if($template_id == 0) { - throw new SoapFault('template_id_error', 'Template ID must be > 0.'); - return false; - } - if($ostemplate_id == 0) { - throw new SoapFault('ostemplate_id_error', 'OSTemplate ID must be > 0.'); - return false; - } - - // Verify if template and ostemplate exist - $tmp = $app->db->queryOneRecord("SELECT template_id FROM openvz_template WHERE template_id = ?", $template_id); - if(!is_array($tmp)) { - throw new SoapFault('template_id_error', 'Template does not exist.'); - return false; - } - $tmp = $app->db->queryOneRecord("SELECT ostemplate_id FROM openvz_ostemplate WHERE ostemplate_id = ?", $ostemplate_id); - if(!is_array($tmp)) { - throw new SoapFault('ostemplate_id_error', 'OSTemplate does not exist.'); - return false; - } - - //* Get the template - $vtpl = $app->db->queryOneRecord("SELECT * FROM openvz_template WHERE template_id = ?", $template_id); - - //* Get the IP address and server_id - if($override_params['server_id'] > 0) { - $vmip = $app->db->queryOneRecord("SELECT ip_address_id, server_id, ip_address FROM openvz_ip WHERE reserved = 'n' AND vm_id = 0 AND server_id = ? LIMIT 0,1", $override_params['server_id']); - } else { - $vmip = $app->db->queryOneRecord("SELECT ip_address_id, server_id, ip_address FROM openvz_ip WHERE reserved = 'n' AND vm_id = 0 LIMIT 0,1"); - } - if(!is_array($vmip)) { - throw new SoapFault('vm_ip_error', 'Unable to get a free VM IP.'); - return false; - } - - //* Build the $params array - $params = array(); - $params['server_id'] = $vmip['server_id']; - $params['ostemplate_id'] = $ostemplate_id; - $params['template_id'] = $template_id; - $params['ip_address'] = $vmip['ip_address']; - $params['hostname'] = (isset($override_params['hostname']))?$override_params['hostname']:$vtpl['hostname']; - $params['vm_password'] = (isset($override_params['vm_password']))?$override_params['vm_password']:$app->auth->get_random_password(10); - $params['start_boot'] = (isset($override_params['start_boot']))?$override_params['start_boot']:'y'; - $params['active'] = (isset($override_params['active']))?$override_params['active']:'y'; - $params['active_until_date'] = (isset($override_params['active_until_date']))?$override_params['active_until_date']:null; - $params['description'] = (isset($override_params['description']))?$override_params['description']:''; - - //* The next params get filled with pseudo values, as the get replaced - //* by the openvz event plugin anyway with values from the template - $params['veid'] = 1; - $params['diskspace'] = 1; - $params['ram'] = 1; - $params['ram_burst'] = 1; - $params['cpu_units'] = 1; - $params['cpu_num'] = 1; - $params['cpu_limit'] = 1; - $params['io_priority'] = 1; - $params['nameserver'] = '8.8.8.8 8.8.4.4'; - $params['create_dns'] = 'n'; - $params['capability'] = ''; - - return $this->insertQuery('../vm/form/openvz_vm.tform.php', $client_id, $params, 'vm:openvz_vm:on_after_insert'); - } - - //* Update openvz vm record - public function openvz_vm_update($session_id, $client_id, $vm_id, $params) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->updateQuery('../vm/form/openvz_vm.tform.php', $client_id, $vm_id, $params, 'vm:openvz_vm:on_after_update'); - return $affected_rows; - } - - //* Delete openvz vm record - public function openvz_vm_delete($session_id, $vm_id) - { - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../vm/form/openvz_vm.tform.php', $vm_id, 'vm:openvz_vm:on_after_delete'); - return $affected_rows; - } - - //* Start VM - public function openvz_vm_start($session_id, $vm_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_vm.tform.php'); - $vm = $app->remoting_lib->getDataRecord($vm_id); - - if(!is_array($vm)) { - throw new SoapFault('action_pending', 'No VM with this ID available.'); - return false; - } - - if($vm['active'] == 'n') { - throw new SoapFault('action_pending', 'VM is not in active state.'); - return false; - } - - $action = 'openvz_start_vm'; - - $tmp = $app->db->queryOneRecord("SELECT count(action_id) as actions FROM sys_remoteaction - WHERE server_id = ? - AND action_type = ? - AND action_param = ? - AND action_state = 'pending'", $vm['server_id'], $action, $vm['veid']); - - if($tmp['actions'] > 0) { - throw new SoapFault('action_pending', 'There is already a action pending for this VM.'); - return false; - } else { - $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . - "VALUES (?, ?, ?, ?, 'pending', '')"; - $app->db->query($sql, (int)$vm['server_id'], time(), $action, $vm['veid']); - } - } - - //* Stop VM - public function openvz_vm_stop($session_id, $vm_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_vm.tform.php'); - $vm = $app->remoting_lib->getDataRecord($vm_id); - - if(!is_array($vm)) { - throw new SoapFault('action_pending', 'No VM with this ID available.'); - return false; - } - - if($vm['active'] == 'n') { - throw new SoapFault('action_pending', 'VM is not in active state.'); - return false; - } - - $action = 'openvz_stop_vm'; - - $tmp = $app->db->queryOneRecord("SELECT count(action_id) as actions FROM sys_remoteaction - WHERE server_id = ? - AND action_type = ? - AND action_param = ? - AND action_state = 'pending'", $vm['server_id'], $action, $vm['veid']); - - if($tmp['actions'] > 0) { - throw new SoapFault('action_pending', 'There is already a action pending for this VM.'); - return false; - } else { - $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . - "VALUES (?, ?, ?, ?, 'pending', '')"; - $app->db->query($sql, (int)$vm['server_id'], time(), $action, $vm['veid']); - } - } - - //* Restart VM - public function openvz_vm_restart($session_id, $vm_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'vm_openvz')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../vm/form/openvz_vm.tform.php'); - $vm = $app->remoting_lib->getDataRecord($vm_id); - - if(!is_array($vm)) { - throw new SoapFault('action_pending', 'No VM with this ID available.'); - return false; - } - - if($vm['active'] == 'n') { - throw new SoapFault('action_pending', 'VM is not in active state.'); - return false; - } - - $action = 'openvz_restart_vm'; - - $tmp = $app->db->queryOneRecord("SELECT count(action_id) as actions FROM sys_remoteaction - WHERE server_id = ? - AND action_type = ? - AND action_param = ? - AND action_state = 'pending'", $vm['server_id'], $action, $vm['veid']); - - if($tmp['actions'] > 0) { - throw new SoapFault('action_pending', 'There is already a action pending for this VM.'); - return false; - } else { - $sql = "INSERT INTO sys_remoteaction (server_id, tstamp, action_type, action_param, action_state, response) " . - "VALUES (?, ?, ?, ?, 'pending', '')"; - $app->db->query($sql, (int)$vm['server_id'], time(), $action, $vm['veid']); - } - } - -} - -?> diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index 4f612c69c..f1bf610af 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -228,7 +228,7 @@ class remoting_server extends remoting { return false; } if (!empty($session_id) && !empty($server_id)) { - $sql = "SELECT mail_server, web_server, dns_server, file_server, db_server, vserver_server, proxy_server, firewall_server, mirror_server_id FROM server WHERE server_id = ?"; + $sql = "SELECT mail_server, web_server, dns_server, file_server, db_server, proxy_server, firewall_server, mirror_server_id FROM server WHERE server_id = ?"; $all = $app->db->queryOneRecord($sql, $server_id); return $all; } else { diff --git a/interface/lib/classes/validate_openvz.inc.php b/interface/lib/classes/validate_openvz.inc.php deleted file mode 100644 index 4aa1a709c..000000000 --- a/interface/lib/classes/validate_openvz.inc.php +++ /dev/null @@ -1,66 +0,0 @@ -tform->wordbook[$errmsg])) { - return $app->tform->wordbook[$errmsg].$additional."
\r\n"; - } else { - return $errmsg."
".$additional."
\r\n"; - } - } - - function check_custom($field_name, $field_value, $validator) { - $template = file('../vm/templates/openvz.conf.tpl', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); - $custom_array = explode("\n", $field_value); - $used_parameters = array(); - foreach ($template as $line) { - $line = trim ($line); - if (preg_match('/^[^#].*=\".*\"/', $line)) { - $line = explode('=', $line, 2); - $used_parameters[] = $line[0]; - } - } - foreach ($custom_array as $check) { - $check = trim(strtoupper($check)); - $check = explode('=', trim($check), 2); - $check = trim($check[0]); - if (in_array($check, $used_parameters)) { - return $this->get_error($validator['errmsg'], $check); - } - } - } - -} diff --git a/interface/lib/plugins/vm_openvz_plugin.inc.php b/interface/lib/plugins/vm_openvz_plugin.inc.php deleted file mode 100644 index 281fae4a1..000000000 --- a/interface/lib/plugins/vm_openvz_plugin.inc.php +++ /dev/null @@ -1,298 +0,0 @@ -plugin->registerEvent('vm:openvz_vm:on_after_insert', 'vm_openvz_plugin', 'openvz_vm_insert'); - $app->plugin->registerEvent('vm:openvz_vm:on_after_update', 'vm_openvz_plugin', 'openvz_vm_update'); - $app->plugin->registerEvent('vm:openvz_vm:on_after_delete', 'vm_openvz_plugin', 'openvz_vm_delete'); - } - - /* - Function that gets called after a new vm was inserted - */ - function openvz_vm_insert($event_name, $page_form) { - global $app, $conf; - - $this->id = $app->functions->intval($page_form->id); - $this->dataRecord = $page_form->dataRecord; - $this->oldDataRecord = $page_form->oldDataRecord; - - // make sure that the record belongs to the clinet group and not the admin group when admin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE openvz_vm SET sys_groupid = ? WHERE vm_id = ?", $client_group_id, $this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE openvz_vm SET sys_groupid = ? WHERE vm_id = ?", $client_group_id, $this->id); - } - - // Set the VEID - $tmp = $app->db->queryOneRecord('SELECT MAX(veid) + 1 as newveid FROM openvz_vm'); - $veid = ($tmp['newveid'] > 100)?$tmp['newveid']:101; - $app->db->query("UPDATE openvz_vm SET veid = ? WHERE vm_id = ?", $veid, $this->id); - unset($tmp); - - // Apply template values to the advanced tab settings - $this->applyTemplate(); - - // Set the IP address - $app->db->query("UPDATE openvz_ip SET vm_id = ? WHERE ip_address = ?", $this->id, $this->dataRecord['ip_address']); - - // Set additional IPs - if (isset($this->dataRecord['additional_ip'])) { - $app->db->query("UPDATE openvz_ip SET vm_id = 0, additional = 'n' WHERE vm_id = ? AND additional='y'", $this->id); - foreach ($this->dataRecord['additional_ip'] as $idx => $rec) { - $app->db->query("UPDATE openvz_ip SET vm_id = ?, additional = 'y' WHERE ip_address = ?", $this->id, $rec); - } - } - - // Create the OpenVZ config file and store it in config field - $this->makeOpenVZConfig(); - - // Create the DNS record - $this->createDNS(); - - } - - /* - Function that gets called after a vm was updated - */ - function openvz_vm_update($event_name, $page_form) { - global $app, $conf; - - $this->id = $app->functions->intval($page_form->id); - $this->dataRecord = $page_form->dataRecord; - $this->oldDataRecord = $page_form->oldDataRecord; - - // make sure that the record belongs to the clinet group and not the admin group when a admin inserts it - // also make sure that the user can not delete domain created by a admin - if($_SESSION["s"]["user"]["typ"] == 'admin' && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE openvz_vm SET sys_groupid = ? WHERE vm_id = ?", $client_group_id, $this->id); - } - if($app->auth->has_clients($_SESSION['s']['user']['userid']) && isset($this->dataRecord["client_group_id"])) { - $client_group_id = $app->functions->intval($this->dataRecord["client_group_id"]); - $app->db->query("UPDATE openvz_vm SET sys_groupid = ? WHERE vm_id = ?", $client_group_id, $this->id); - } - - if(isset($this->dataRecord["ostemplate_id"]) && $this->oldDataRecord["ostemplate_id"] != $this->dataRecord["ostemplate_id"]) { - $this->applyTemplate(); - } - - // Set the IP address - if(isset($this->dataRecord['ip_address'])) { - $app->db->query("UPDATE openvz_ip SET vm_id = 0 WHERE vm_id = ? AND additional='n'", $this->id); - $app->db->query("UPDATE openvz_ip SET vm_id = ?, additional = 'n' WHERE ip_address = ?", $this->id, $this->dataRecord['ip_address']); - } - - // Set additional IPs - if (isset($this->dataRecord['additional_ip'])) { - $app->db->query("UPDATE openvz_ip SET vm_id = 0, additional = 'n' WHERE (vm_id = ? AND additional='y')", $this->id); - foreach ($this->dataRecord['additional_ip'] as $idx => $rec) { - $app->db->query("UPDATE openvz_ip SET vm_id = ?, additional = 'y' WHERE ip_address = ?", $this->id, $rec); - } - } - - // Create the OpenVZ config file and store it in config field - $this->makeOpenVZConfig(); - - // Create the DNS record - if((isset($this->dataRecord['hostname']) && $this->dataRecord['hostname'] != $this->oldDataRecord['hostname']) - or (isset($this->dataRecord['create_dns']) && $this->dataRecord['create_dns'] != $this->oldDataRecord['create_dns'])) { - $this->createDNS(); - } - - } - - function openvz_vm_delete($event_name, $page_form) { - global $app, $conf; - - //* Free the IP address - $tmp_rec = $app->db->queryAllRecords("SELECT ip_address_id FROM openvz_ip WHERE vm_id = ?", $page_form->id); - foreach ($tmp_rec as $tmp) { - $app->db->datalogUpdate('openvz_ip', array('vm_id' => 0), 'ip_address_id', $tmp['ip_address_id']); - } - } - - private function applyTemplate() { - global $app, $conf; - - $tpl = $app->db->queryOneRecord("SELECT * FROM openvz_template WHERE template_id = ?", $this->dataRecord["template_id"]); - - $sql = "UPDATE openvz_vm SET "; - $sql .= "diskspace = ?, "; - $sql .= "ram = ?, "; - $sql .= "ram_burst = ?, "; - $sql .= "cpu_units = ?, "; - $sql .= "cpu_num = ?, "; - $sql .= "cpu_limit = ?, "; - $sql .= "io_priority = ?, "; - $sql .= "nameserver = ?, "; - $sql .= "create_dns = ?, "; - $sql .= "capability = ?, "; - $sql .= "features = ?, "; - $sql .= "iptables = ? "; - $sql .= "custom = ? "; - $sql .= "WHERE vm_id = ?"; - $app->db->query($sql, $tpl['diskspace'], $tpl['ram'], $tpl['ram_burst'], $tpl['cpu_units'], $tpl['cpu_num'], $tpl['cpu_limit'], $tpl['io_priority'], $tpl['nameserver'], $tpl['create_dns'], $tpl['capability'], $tpl['features'], $tpl['iptables'], $tpl['custom'], $this->id); - - } - - private function makeOpenVZConfig() { - global $app, $conf; - - $vm = $app->db->queryOneRecord("SELECT * FROM openvz_vm WHERE vm_id = ?",$app->functions->intval($this->id)); - $vm_template = $app->db->queryOneRecord("SELECT * FROM openvz_template WHERE template_id = ?",$app->functions->intval($vm['template_id'])); - $burst_ram = $vm['ram_burst']*256; - $guar_ram = $vm['ram']*256; - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('../vm/templates/openvz.conf.tpl'); - - $onboot = ($vm['start_boot'] == 'y')?'yes':'no'; - $tpl->setVar('onboot', $onboot); - - $tpl->setVar('bootorder', $vm['bootorder']); - $tpl->setVar('kmemsize', $vm_template['kmemsize']); - $tpl->setVar('lockedpages', $vm_template['lockedpages']); - $tpl->setVar('privvmpages', $burst_ram.':'.$burst_ram*1.0625); - $tpl->setVar('shmpages', $guar_ram.':'.$guar_ram); - $tpl->setVar('numproc', $vm_template['numproc']); - $tpl->setVar('physpages', $vm_template['physpages']); - $tpl->setVar('vmguarpages', $guar_ram.':unlimited'); - $tpl->setVar('oomguarpages', $guar_ram.':'.$guar_ram); - $tpl->setVar('numtcpsock', $vm_template['numtcpsock']); - $tpl->setVar('numflock', $vm_template['numflock']); - $tpl->setVar('numpty', $vm_template['numpty']); - $tpl->setVar('numsiginfo', $vm_template['numsiginfo']); - $tpl->setVar('tcpsndbuf', $vm_template['tcpsndbuf']); - $tpl->setVar('tcprcvbuf', $vm_template['tcprcvbuf']); - $tpl->setVar('othersockbuf', $vm_template['othersockbuf']); - $tpl->setVar('dgramrcvbuf', $vm_template['dgramrcvbuf']); - $tpl->setVar('numothersock', $vm_template['numothersock']); - $tpl->setVar('dcachesize', $vm_template['dcachesize']); - $tpl->setVar('numfile', $vm_template['numfile']); - $tpl->setVar('avnumproc', $vm_template['avnumproc']); - $tpl->setVar('numiptent', $vm_template['numiptent']); - $tpl->setVar('swappages', $vm_template['swappages']); - - $diskspace = $vm['diskspace']*1048576; - $diskinodes = $vm['diskspace']*524288; - - $tpl->setVar('diskspace', $diskspace.":".$diskspace); - $tpl->setVar('diskinodes', $diskinodes.":".$diskinodes); - $tpl->setVar('io_priority', $vm['io_priority']); - - $tpl->setVar('cpu_num', $vm['cpu_num']); - $tpl->setVar('cpu_units', $vm['cpu_units']); - $tpl->setVar('cpu_limit', $vm['cpu_limit']); - - $hostname = str_replace('{VEID}', $vm['veid'], $vm['hostname']); - - $tpl->setVar('hostname', $hostname); - - $additional_ips = $app->db->queryAllRecords("SELECT * FROM openvz_ip WHERE vm_id = ?",$this->id); - if (isset($additional_ips)) { - $vm['ip_address']=''; - foreach ($additional_ips as $ip) { - $vm['ip_address'] .= " ".$ip['ip_address']; - } - $vm['ip_address'] = substr($vm['ip_address'],1); - } - $tpl->setVar('ip_address', $vm['ip_address']); - - $tpl->setVar('ip_address', $vm['ip_address']); - $tpl->setVar('nameserver', $vm['nameserver']); - $tpl->setVar('capability', $vm['capability']); - $tpl->setVar('features', $vm['features']); - $tpl->setVar('iptables', $vm['iptables']); - - $tpl->setVar('custom', $vm['custom']); - - $tmp = $app->db->queryOneRecord("SELECT template_file FROM openvz_ostemplate WHERE ostemplate_id = ?", $app->functions->intval($vm['ostemplate_id'])); - $tpl->setVar('ostemplate', $tmp['template_file']); - unset($tmp); - - $openvz_config = $tpl->grab(); - $app->db->query("UPDATE openvz_vm SET config = ? WHERE vm_id = ?", $openvz_config, $app->functions->intval($this->id)); - - unset($tpl); - - } - - private function createDNS() { - global $app, $conf; - - $vm = $app->db->queryOneRecord("SELECT * FROM openvz_vm WHERE vm_id = ?", $app->functions->intval($this->id)); - - if($vm['create_dns'] != 'y') return; - - $full_hostname = str_replace('{VEID}', $vm['veid'], $vm['hostname']); - $hostname_parts = explode('.', $full_hostname); - $hostname = $hostname_parts[0]; - unset($hostname_parts[0]); - $zone = implode('.', $hostname_parts); - unset($hostname_parts); - - // Find the dns zone - $zone_rec = $app->db->queryOneRecord("SELECT * FROM dns_soa WHERE origin = ?", $zone); - $rr_rec = $app->db->queryOneRecord("SELECT * FROM dns_rr WHERE zone = ? AND name = ?", $zone_rec['id'], $hostname); - - if($zone_rec['id'] > 0) { - $ip_address = $vm['ip_address']; - $sys_userid = $app->functions->intval($zone_rec['sys_userid']); - $sys_groupid = $app->functions->intval($zone_rec['sys_groupid']); - $server_id = $app->functions->intval($zone_rec['server_id']); - $dns_soa_id = $app->functions->intval($zone_rec['id']); - - if($rr_rec['id'] > 0) { - $app->uses('validate_dns'); - $app->db->datalogUpdate('dns_rr', array("data" => $ip_address), 'id', $app->functions->intval($rr_rec['id'])); - $serial = $app->validate_dns->increase_serial($zone_rec['serial']); - $app->db->datalogUpdate('dns_soa', array("serial" => $serial), 'id', $app->functions->intval($zone_rec['id'])); - } else { - $insert_data = array( - "sys_userid" => $sys_userid, - "sys_groupid" => $sys_groupid, - "sys_perm_user" => 'riud', - "sys_perm_group" => 'riud', - "sys_perm_other" => '', - "server_id" => $server_id, - "zone" => $dns_soa_id, - "name" => $hostname, - "type" => @(preg_match("/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/", $ip_address))?'A':'AAAA', - "data" => $ip_address, - "aux" => '0', - "ttl" => '3600', - "active" => 'Y' - ); - $dns_rr_id = $app->db->datalogInsert('dns_rr', $insert_data, 'id'); - } - - } - } - -} diff --git a/interface/lib/server_conf.master b/interface/lib/server_conf.master index 8fd54d992..7e705935e 100644 --- a/interface/lib/server_conf.master +++ b/interface/lib/server_conf.master @@ -21,6 +21,3 @@ module=generic [file] module=generic - -[vserver] -module=generic \ No newline at end of file diff --git a/interface/web/admin/form/server.tform.php b/interface/web/admin/form/server.tform.php index 2c74e6785..e28e3e34d 100644 --- a/interface/web/admin/form/server.tform.php +++ b/interface/web/admin/form/server.tform.php @@ -102,12 +102,6 @@ $form["tabs"]['services'] = array ( 'default' => '0', 'value' => array(0 => 0, 1 => 1) ), - 'vserver_server' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'CHECKBOX', - 'default' => '0', - 'value' => array(0 => 0, 1 => 1) - ), 'mirror_server_id' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/admin/list/server.list.php b/interface/web/admin/list/server.list.php index 5a44a7a2b..ee8f59002 100644 --- a/interface/web/admin/list/server.list.php +++ b/interface/web/admin/list/server.list.php @@ -100,14 +100,3 @@ $liste['item'][] = array( 'field' => 'db_server', 'suffix' => '%', 'width' => '', 'value' => array('1' => $app->lng('yes_txt'), '0' => $app->lng('no_txt'))); - -$liste['item'][] = array( 'field' => 'vserver_server', - 'datatype' => 'VARCHAR', - 'formtype' => 'SELECT', - 'op' => 'like', - 'prefix' => '%', - 'suffix' => '%', - 'width' => '', - 'value' => array('1' => $app->lng('yes_txt'), '0' => $app->lng('no_txt'))); - -?> diff --git a/interface/web/admin/templates/server_edit_services.htm b/interface/web/admin/templates/server_edit_services.htm index 0ee07d020..22d4a26f1 100644 --- a/interface/web/admin/templates/server_edit_services.htm +++ b/interface/web/admin/templates/server_edit_services.htm @@ -37,12 +37,6 @@
{tmpl_var name='db_server'}
-
-
- -
- {tmpl_var name='vserver_server'} -
diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm index 341eb5b64..2f527af17 100644 --- a/interface/web/admin/templates/server_list.htm +++ b/interface/web/admin/templates/server_list.htm @@ -15,7 +15,6 @@ - {tmpl_var name='search_limit'} @@ -25,7 +24,6 @@ - @@ -40,7 +38,6 @@ {tmpl_var name="dns_server"} {tmpl_var name="file_server"} {tmpl_var name="db_server"} - {tmpl_var name="vserver_server"} @@ -48,13 +45,13 @@ - {tmpl_var name='globalsearch_noresults_text_txt'} + {tmpl_var name='globalsearch_noresults_text_txt'} - + diff --git a/interface/web/client/client_edit.php b/interface/web/client/client_edit.php index 8577a1b32..c40538603 100644 --- a/interface/web/client/client_edit.php +++ b/interface/web/client/client_edit.php @@ -438,7 +438,6 @@ class page_action extends tform_actions { 'mail_user_smtp' => 'mailuser_id', 'mail_forwarding' => 'forwarding_id', 'mail_get' => 'mailget_id', - 'openvz_vm' => 'vm_id', 'shell_user' => 'shell_user_id', 'webdav_user' => 'webdav_user_id', 'web_database' => 'database_id', diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index dfba3ec36..b272fcbe2 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -1343,31 +1343,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_openvz_vm' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_openvz_vm_error_notint'), - ), - 'default' => '0', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_openvz_vm_template_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT template_id,template_name FROM openvz_template WHERE 1 ORDER BY template_name', - 'keyfield'=> 'template_id', - 'valuefield'=> 'template_name' - ), - 'value' => array(0 => ' ') - ), 'limit_aps' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/client_template.tform.php b/interface/web/client/form/client_template.tform.php index 13c76a598..b6dc1b202 100644 --- a/interface/web/client/form/client_template.tform.php +++ b/interface/web/client/form/client_template.tform.php @@ -748,31 +748,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_openvz_vm' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_openvz_vm_error_notint'), - ), - 'default' => '0', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_openvz_vm_template_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT template_id,template_name FROM openvz_template WHERE 1 ORDER BY template_name', - 'keyfield'=> 'template_id', - 'valuefield'=> 'template_name' - ), - 'value' => array(0 => ' ') - ), 'limit_aps' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index 7412dbb83..53acfd602 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -1342,31 +1342,6 @@ $form["tabs"]['limits'] = array ( 'rows' => '', 'cols' => '' ), - 'limit_openvz_vm' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'validators' => array ( 0 => array ( 'type' => 'ISINT', - 'errmsg'=> 'limit_openvz_vm_error_notint'), - ), - 'default' => '0', - 'value' => '', - 'separator' => '', - 'width' => '10', - 'maxlength' => '10', - 'rows' => '', - 'cols' => '' - ), - 'limit_openvz_vm_template_id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'SELECT', - 'default' => '', - 'datasource' => array ( 'type' => 'SQL', - 'querystring' => 'SELECT template_id,template_name FROM openvz_template WHERE 1 ORDER BY template_name', - 'keyfield'=> 'template_id', - 'valuefield'=> 'template_name' - ), - 'value' => array(0 => ' ') - ), 'limit_aps' => array ( 'datatype' => 'INTEGER', 'formtype' => 'TEXT', diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index a260e847e..7ebb33122 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -332,28 +332,6 @@
-
- -
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
- -
-
- -
-
-
-
-
-
- -
-
-
- -
-
- -
-
-
-
-
+ {tmpl_hook name="field_db_server"} + {tmpl_hook name="end_service_fields"}
@@ -52,7 +54,7 @@ {tmpl_var name='active'}
- + {tmpl_hook name="end_form"} diff --git a/interface/web/admin/templates/server_list.htm b/interface/web/admin/templates/server_list.htm index 2f527af17..25c18c01f 100644 --- a/interface/web/admin/templates/server_list.htm +++ b/interface/web/admin/templates/server_list.htm @@ -15,6 +15,7 @@ + {tmpl_hook name="end_table_headers"} {tmpl_var name='search_limit'} @@ -24,9 +25,10 @@ + {tmpl_hook name="end_table_filters"} - + "} @@ -38,6 +40,7 @@ {tmpl_var name="dns_server"} {tmpl_var name="file_server"} {tmpl_var name="db_server"} + {tmpl_hook name="end_table_columns"} diff --git a/interface/web/client/client_edit.php b/interface/web/client/client_edit.php index c40538603..0d06a42fe 100644 --- a/interface/web/client/client_edit.php +++ b/interface/web/client/client_edit.php @@ -445,6 +445,11 @@ class page_action extends tform_actions { 'web_folder' => 'web_folder_id', 'web_folder_user' => 'web_folder_user_id' ); + + $addons_disable = $app->plugin->raiseEvent('client::get_lockable_data', $this->id, true); + if(is_array($addons_disable) && !empty($addons_disable)) { + $to_disable = array_merge($to_disable, $addons_disable); + } $udata = $app->db->queryOneRecord('SELECT `userid` FROM `sys_user` WHERE `client_id` = ?', $this->id); $gdata = $app->db->queryOneRecord('SELECT `groupid` FROM `sys_group` WHERE `client_id` = ?', $this->id); diff --git a/interface/web/client/templates/client_edit_limits.htm b/interface/web/client/templates/client_edit_limits.htm index 7ebb33122..16cd1fc20 100644 --- a/interface/web/client/templates/client_edit_limits.htm +++ b/interface/web/client/templates/client_edit_limits.htm @@ -349,6 +349,7 @@ + {tmpl_hook name="end_form"} diff --git a/interface/web/client/templates/client_template_edit_limits.htm b/interface/web/client/templates/client_template_edit_limits.htm index 6c63829f0..abaf65aad 100644 --- a/interface/web/client/templates/client_template_edit_limits.htm +++ b/interface/web/client/templates/client_template_edit_limits.htm @@ -307,6 +307,7 @@ + {tmpl_hook name="end_form"}
diff --git a/interface/web/client/templates/reseller_edit_limits.htm b/interface/web/client/templates/reseller_edit_limits.htm index 4ca3d33b9..539b7d5e4 100644 --- a/interface/web/client/templates/reseller_edit_limits.htm +++ b/interface/web/client/templates/reseller_edit_limits.htm @@ -352,6 +352,7 @@
+ {tmpl_hook name="end_form"}
+ +{tmpl_hook name="end_form"}
diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php new file mode 100644 index 000000000..e7061f783 --- /dev/null +++ b/server/lib/classes/addon_installer.inc.php @@ -0,0 +1,178 @@ +system->tempdir(sys_get_temp_dir(), 'addon_', 0700); + if(!$temp_dir) { + throw new AddonInstallerException('Could not create temp dir.'); + } + + $ret = null; + $retval = 0; + $cmd = $unzip . ' -d ' . escapeshellarg($temp_dir) . ' ' . escapeshellarg($package_file); + exec($cmd, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Package extraction failed.'); + } + + return $temp_dir; + } + + /** + * @param string $path + * @return string + * @throws AddonInstallerValidationException + */ + private function validatePackage($path) { + if(!is_dir($path)) { + throw new AddonInstallerValidationException('Invalid path.'); + } + + $ini_file = $path . '/addon.ini'; + if(!is_file($ini_file)) { + throw new AddonInstallerValidationException('Addon ini file missing.'); + } + + $ini = parse_ini_file($ini_file, true); + if(!$ini || !isset($ini['addon'])) { + throw new AddonInstallerValidationException('Ini file is missing addon section.'); + } + + $addon = $ini['addon']; + if(!isset($addon['ident']) || !isset($addon['name']) || !isset($addon['version'])) { + throw new AddonInstallerValidationException('Ini file is missing addon ident/name/version.'); + } + + $class_file = $path . '/' . $addon['ident'] . '.addon.php'; + if(!is_file($class_file)) { + throw new AddonInstallerValidationException('Package is missing main addon class.'); + } + + if(isset($ini['ispconfig']['version.min']) && $ini['ispconfig']['version.min'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '>')) { + throw new AddonInstallerValidationException('Addon requires at least ISPConfig version ' . $ini['ispconfig']['version.min'] . '.'); + } elseif(isset($ini['ispconfig']['version.max']) && $ini['ispconfig']['version.max'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '<')) { + throw new AddonInstallerValidationException('Addon allows at max ISPConfig version ' . $ini['ispconfig']['version.max'] . '.'); + } + + $addon['class_file'] = $class_file; + $addon['class_name'] = substr(basename($class_file), 0, -10) . '_addon_installer'; + + return $addon; + } + + private function getInstalledAddonVersion($ident) { + global $app, $conf; + + $file_version = false; + $db_version = false; + + $addon_path = realpath($conf['rootpath'] . '/..') . '/addons'; + // check for previous version + if(is_dir($addon_path . '/' . $ident) && is_file($addon_path . '/' . $ident . '/addon.ini')) { + $addon = parse_ini_file($addon_path . '/' . $ident . '/addon.ini', true); + if(!$addon || !isset($addon['version']) || !isset($addon['ident']) || $addon['ident'] != $ident) { + throw new AddonInstallerException('Installed app found but it is invalid.'); + } + + $file_version = $addon['version']; + } + + $check = $app->db->queryOneRecord('SELECT `addon_version` FROM `addons` WHERE `addon_ident` = ?', $ident); + if($check && $check['addon_version']) { + $db_version = $check['addon_version']; + } + + if(!$file_version && !$db_version) { + return false; + } elseif($file_version != $db_version) { + throw new AddonInstallerException('Addon version mismatch in database (' . $db_version . ') and file system (' . $file_version . ').'); + } + + return $file_version; + + } + + /** + * @param string $package_file Full path + * @param boolean $force true if previous addon with same or higher version should be overwritten + * @throws AddonInstallerException + * @throws AddonInstallerValidationException + */ + public function installAddon($package_file, $force = false) { + if(!is_file($package_file)) { + throw new AddonInstallerException('Package file not found.'); + } elseif(substr($package_file, -4) !== '.pkg') { + throw new AddonInstallerException('Invalid package file.'); + } + + $tmp_dir = $this->extractPackage($package_file); + if(!$tmp_dir) { + // extracting failed + throw new AddonInstallerException('Package extraction failed.'); + } + + $addon = $this->validatePackage($tmp_dir); + if(!$addon) { + throw new AddonInstallerException('Package validation failed.'); + } + + $is_update = false; + $previous = $this->getInstalledAddonVersion($addon['ident']); + if($previous !== false) { + // this is an update + if(version_compare($previous, $addon['version'], '>') && $force !== true) { + throw new AddonInstallerException('Installed version is newer than the one to install.'); + } elseif(version_compare($previous, $addon['version'], '=') && $force !== true) { + throw new AddonInstallerException('Installed version is the same as the one to install.'); + } + $is_update = true; + } + include $addon['class_file']; + if(!class_exists($addon['class_name'])) { + throw new AddonInstallerException('Could not find main class in addon file.'); + } + + $class_name = $addon['class_name']; + /* @var $inst ispconfig_addon_installer_base */ + $inst = new $class_name(); + $inst->setAddonName($addon['name']); + $inst->setAddonIdent($addon['ident']); + $inst->setAddonVersion($addon['version']); + $inst->setAddonTempDir($tmp_dir); + + if($is_update === true) { + $inst->onBeforeUpdate(); + $inst->onUpdate(); + $inst->onAfterUpdate(); + } else { + $inst->onBeforeInstall(); + $inst->onInstall(); + $inst->onAfterInstall(); + } + + return true; + } + +} diff --git a/server/lib/classes/functions.inc.php b/server/lib/classes/functions.inc.php index b20f3ab0e..0470f4746 100644 --- a/server/lib/classes/functions.inc.php +++ b/server/lib/classes/functions.inc.php @@ -297,6 +297,12 @@ class functions { } } } + + $tmp_ips = $app->plugins->raiseAction('get_server_ips', 0, true); + if(is_array($tmp_ips) && !empty($tmp_ips)) { + $ips = array_merge($ips, $tmp_ips); + } + $ips = array_unique($ips); sort($ips, SORT_NUMERIC); diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php new file mode 100644 index 000000000..e971321ce --- /dev/null +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -0,0 +1,161 @@ +addon_ident = preg_replace('/_addon_installer$/', '', get_called_class()); + } + + public function setAddonName($name) { + $this->addon_name = $name; + } + + public function setAddonIdent($ident) { + $this->addon_ident = $ident; + } + + public function setAddonVersion($version) { + $this->addon_version = $version; + } + + public function setAddonTempDir($path) { + $this->temp_dir = $path; + } + + protected function copyInterfaceFiles() { + global $conf; + + $install_dir = realpath($conf['rootpath'] . '/..'); + + if(is_dir($this->temp_dir . '/interface')) { + $ret = null; + $retval = 0; + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/interface') . ' ' . escapeshellarg($install_dir . '/'); + exec($command, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + } + + return true; + } else { + return false; + } + } + + protected function copyServerFiles() { + global $conf; + + $install_dir = realpath($conf['rootpath'] . '/..'); + + if(is_dir($this->temp_dir . '/server')) { + $ret = null; + $retval = 0; + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/server'). ' ' . escapeshellarg($install_dir . '/'); + exec($command, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + } + return true; + } else { + return false; + } + } + + protected function executeSqlStatements() { + global $app, $conf; + + // create addon entry if not existing + $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; + $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); + + $incremental = false; + $check = $app->db->queryOneRecord('SELECT `db_version` FROM `addons` WHERE `addon_ident` = ?', $this->addon_ident); + if($check) { + $incremental = 0; + if($check['db_version']) { + $incremental = $check['db_version']; + } + } + + + $mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($conf['db_host']) . ' -u ' . escapeshellarg($conf['db_user']) . ' -p' . escapeshellarg($conf['db_password']) . ' -P ' . escapeshellarg($conf['db_port']) . ' -D ' . escapeshellarg($conf['db_database']); + + if($incremental === false) { + $sql_file = $this->temp_dir . '/install/sql/' . $this->addon_ident . '.sql'; + if(is_file($sql_file)) { + $ret = null; + $retval = 0; + exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); + if($retval != 0) { + /* TODO: log error! */ + } + } + } else { + $new_db_version = $incremental; + while(true) { + $sql_file = $this->temp_dir . '/install/sql/incremental/upd_' . str_pad($new_db_version + 1, '0', 5, STR_PAD_LEFT) . '.sql'; + if(!is_file($sql_file)) { + break; + } else { + $ret = null; + $retval = 0; + exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); + if($retval != 0) { + /* TODO: log error! */ + } + } + + $new_db_version++; + } + + $app->db->query('UPDATE `addons` SET `addon_version` = ?, `db_version` = ? WHERE `addon_ident` = ?', $this->addon_version, $new_db_version, $this->addon_ident); + } + + return true; + } + + public function onBeforeInstall() { } + + public function onInstall() { + $this->copyInterfaceFiles(); + $this->copyServerFiles(); + $this->executeSqlStatements(); + } + + public function onAfterInstall() { } + + public function onBeforeUpdate() { } + + public function onUpdate() { + $this->copyInterfaceFiles(); + $this->copyServerFiles(); + $this->executeSqlStatements(); + } + + public function onAfterUpdate() { } + + + + public function onRaisedInstallerEvent($event_name) { + + } +} + +class AddonInstallerException extends Exception { + public function __construct($message = "", $code = 0, $previous = null) { + parent::__construct($message, $code, $previous); + } +} + +class AddonInstallerValidationException extends AddonInstallerException { } \ No newline at end of file diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index adcc39f84..dc5a8dde8 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -2044,7 +2044,32 @@ class system{ return true; } + + public function tempdir($parent_path = null, $prefix = 'tmp_', $mode = 0700) { + if(is_null($parent_path)) { + $parent_path = sys_get_temp_dir(); + } + + $parent_path = rtrim($parent_path, '/'); + if(!is_dir($parent_path) || !is_writable($parent_path)) { + return false; + } + + if(strpbrk($prefix, '\\/:*?"<>|') !== false) { + return false; + } + + $path = false; + $tries = 0; + while($tries < 1000) { + $tries++; + $path = $parent_path . FS_DIV . uniqid($prefix, true); + if(mkdir($path, $mode)) { + break; + } + } + + return $path; + } } - -?> -- GitLab From 42a34df4fa3c420d0b1fb5f5407db4566e61c5ff Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 15:35:23 +0100 Subject: [PATCH 219/310] - installer class for addons - do not install/update addons during install/update of ISPconfig. This only leads to lots of trouble --- addons/empty.dir | 1 + install/install.php | 40 ---- .../classes/ispconfig_addon_installer.inc.php | 20 ++ install/lib/installer_base.lib.php | 17 +- .../sql/incremental/upd_dev_collection.sql | 9 + install/sql/ispconfig3.sql | 16 ++ install/update.php | 46 +---- interface/web/tools/resync.php | 13 ++ interface/web/tools/templates/resync.htm | 2 + server/lib/classes/addon_installer.inc.php | 178 ++++++++++++++++++ server/lib/classes/functions.inc.php | 6 + .../ispconfig_addon_installer_base.inc.php | 161 ++++++++++++++++ server/lib/classes/system.inc.php | 29 ++- 13 files changed, 444 insertions(+), 94 deletions(-) create mode 100644 addons/empty.dir create mode 100644 install/lib/classes/ispconfig_addon_installer.inc.php create mode 100644 server/lib/classes/addon_installer.inc.php create mode 100644 server/lib/classes/ispconfig_addon_installer_base.inc.php diff --git a/addons/empty.dir b/addons/empty.dir new file mode 100644 index 000000000..95ba9ef37 --- /dev/null +++ b/addons/empty.dir @@ -0,0 +1 @@ +This empty directory is needed by ISPConfig. diff --git a/install/install.php b/install/install.php index e8e878ccd..bb41927b3 100644 --- a/install/install.php +++ b/install/install.php @@ -145,46 +145,6 @@ if(is_file('dist/lib/'.$dist['baseid'].'.lib.php')) include_once 'dist/lib/'.$di include_once 'dist/lib/'.$dist['id'].'.lib.php'; include_once 'dist/conf/'.$dist['confid'].'.conf.php'; -//** Include addon lib config files -if(is_dir('dist/lib.d')) { - // scheme is: ..conf.php - if(($dir = opendir('dist/lib.d'))) { - while(false !== ($cur = readdir($dir))) { - $curpath = 'dist/lib.d/' . $cur; - if(strpos($curpath, '..') !== false - || !is_file($curpath) - || !preg_match('/\.(?:' . preg_quote($dist['id'], '/') . '|' . preg_quote($dist['baseid'], '/') . ')\.lib\.php$/', $cur)) { - - // invalid entry or entry not for current distribution - continue; - } - // valid file name and either generic or for current distribution - include_once $curpath; - } - closedir($dir); - } -} - -//** Include addon dist config files -if(is_dir('dist/conf.d')) { - // scheme is: ..conf.php - if(($dir = opendir('dist/conf.d'))) { - while(false !== ($cur = readdir($dir))) { - $curpath = 'dist/conf.d/' . $cur; - if(strpos($curpath, '..') !== false - || !is_file($curpath) - || !preg_match('/\.' . preg_quote($dist['confid'], '/') . '\.conf\.php$/', $cur)) { - - // invalid entry or entry not for current distribution - continue; - } - // valid file name and either generic or for current distribution - include_once $curpath; - } - closedir($dir); - } -} - //**************************************************************************************************** //** Installer Interface //**************************************************************************************************** diff --git a/install/lib/classes/ispconfig_addon_installer.inc.php b/install/lib/classes/ispconfig_addon_installer.inc.php new file mode 100644 index 000000000..78ef7e0b0 --- /dev/null +++ b/install/lib/classes/ispconfig_addon_installer.inc.php @@ -0,0 +1,20 @@ +addon_ident = preg_replace('/_addon_installer$/', '', get_called_class()); + } + + public function onRaisedInstallerEvent($event_name, $data) { + + } +} diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index fa7a7d3e5..f3db824cd 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -28,6 +28,8 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +require_once realpath(dirname(__FILE__)) . '/classes/ispconfig_addon_installer.inc.php'; + class installer_base { var $wb = array(); @@ -397,8 +399,6 @@ class installer_base { $this->db->query($sql, $conf['hostname'], $mail_server_enabled, $web_server_enabled, $dns_server_enabled, $file_server_enabled, $db_server_enabled, $server_ini_content, $current_db_version, $proxy_server_enabled, $firewall_server_enabled); $conf['server_id'] = $this->db->insertID(); } - - } public function detect_ips(){ @@ -2183,7 +2183,7 @@ class installer_base { // TODO: Implement a selector which modules and plugins shall be enabled. $dir = $install_dir.'/server/mods-available/'; if (is_dir($dir)) { - if ($dh = opendir($dir)) { + if (($dh = opendir($dir))) { while (($file = readdir($dh)) !== false) { if($file != '.' && $file != '..' && substr($file, -8, 8) == '.inc.php') { include_once $install_dir.'/server/mods-available/'.$file; @@ -2210,7 +2210,7 @@ class installer_base { $dir = $install_dir.'/server/plugins-available/'; if (is_dir($dir)) { - if ($dh = opendir($dir)) { + if (($dh = opendir($dir))) { while (($file = readdir($dh)) !== false) { if($conf['apache']['installed'] == true && $file == 'nginx_plugin.inc.php') continue; if($conf['nginx']['installed'] == true && $file == 'apache2_plugin.inc.php') continue; @@ -2828,7 +2828,7 @@ class installer_base { } private function loadAddonClasses($path) { - $libpath = $conf['ispconfig_install_dir'] . '/addons'; + $libpath = $path; if(($dir = opendir($libpath))) { while(false !== ($cur = readdir($dir))) { if($cur === '.' || $cur === '..' || strpos($cur, '..') !== false || !is_dir($libpath . '/' . $cur)) { @@ -2867,15 +2867,12 @@ class installer_base { if(is_null($this->addon_classes)) { // load addon libs $this->addon_classes = array(); - $addonpath = $conf['ispconfig_install_dir'] . '/addons'; - $this->loadAddonClasses($addonpath); - // check for addon libs in install dir - $addonpath = realpath(dirname(__FILE__) . '/..') . '/addons'; + $addonpath = $conf['ispconfig_install_dir'] . '/addons'; $this->loadAddonClasses($addonpath); } - $call_method = 'onRaisedEvent'; + $call_method = 'onRaisedInstallerEvent'; reset($this->addon_classes); foreach($this->addon_classes as $cl) { if(method_exists($cl, $call_method)) { diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 02a10ebfd..dc5d4bb45 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -142,3 +142,12 @@ UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '8.00' WHERE id = 6; UPDATE `spamfilter_policy` SET `rspamd_spam_kill_level` = '20.00' WHERE id = 7; -- end of rspamd +CREATE TABLE IF NOT EXISTS `addons` ( + `addon_id` int(11) NOT NULL AUTO_INCREMENT, + `addon_ident` VARCHAR(100) NOT NULL DEFAULT '', + `addon_version` VARCHAR(20) NOT NULL DEFAULT '', + `addon_name` VARCHAR(255) NOT NULL DEFAULT '', + `db_version` INT(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`addon_id`), + UNIQUE KEY `ident` (`addon_ident`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index bed58a44f..7462bbb74 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -53,6 +53,22 @@ SET FOREIGN_KEY_CHECKS = 0; -- -------------------------------------------------------- -- -------------------------------------------------------- +-- +-- Table structure for table `addons` +-- + +CREATE TABLE IF NOT EXISTS `addons` ( + `addon_id` int(11) NOT NULL AUTO_INCREMENT, + `addon_ident` VARCHAR(100) NOT NULL DEFAULT '', + `addon_version` VARCHAR(20) NOT NULL DEFAULT '', + `addon_name` VARCHAR(255) NOT NULL DEFAULT '', + `db_version` INT(6) NOT NULL DEFAULT '0', + PRIMARY KEY (`addon_id`), + UNIQUE KEY `ident` (`addon_ident`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +-- -------------------------------------------------------- + -- -- Table structure for table `aps_instances` -- diff --git a/install/update.php b/install/update.php index 2fe3f6559..3a51546f0 100644 --- a/install/update.php +++ b/install/update.php @@ -148,45 +148,11 @@ if(is_file('dist/lib/'.$dist['baseid'].'.lib.php')) include_once 'dist/lib/'.$di include_once 'dist/lib/'.$dist['id'].'.lib.php'; include_once 'dist/conf/'.$dist['confid'].'.conf.php'; -//** Include addon lib config files -if(is_dir('dist/lib.d')) { - // scheme is: ..conf.php - if(($dir = opendir('dist/lib.d'))) { - while(false !== ($cur = readdir($dir))) { - $curpath = 'dist/lib.d/' . $cur; - if(strpos($curpath, '..') !== false - || !is_file($curpath) - || !preg_match('/\.(?:' . preg_quote($dist['id'], '/') . '|' . preg_quote($dist['baseid'], '/') . ')\.lib\.php$/', $cur)) { - - // invalid entry or entry not for current distribution - continue; - } - // valid file name and either generic or for current distribution - include_once $curpath; - } - closedir($dir); - } -} +$inst = new installer(); +if (!$inst->get_php_version()) die('ISPConfig requieres PHP '.$inst->min_php."\n"); +$inst->is_update = true; -//** Include addon dist config files -if(is_dir('dist/conf.d')) { - // scheme is: ..conf.php - if(($dir = opendir('dist/conf.d'))) { - while(false !== ($cur = readdir($dir))) { - $curpath = 'dist/conf.d/' . $cur; - if(strpos($curpath, '..') !== false - || !is_file($curpath) - || !preg_match('/\.' . preg_quote($dist['confid'], '/') . '\.conf\.php$/', $cur)) { - - // invalid entry or entry not for current distribution - continue; - } - // valid file name and either generic or for current distribution - include_once $curpath; - } - closedir($dir); - } -} +$inst->raiseEvent('set_dist_config', $dist); //** tRNG dependencies $conf['tRNG']=''; @@ -228,10 +194,6 @@ if(!$conf['mysql']['ip'] = gethostbyname($conf['mysql']['host'])) die('Unable to $conf['server_id'] = intval($conf_old["server_id"]); $conf['ispconfig_log_priority'] = $conf_old["log_priority"]; -$inst = new installer(); -if (!$inst->get_php_version()) die('ISPConfig requieres PHP '.$inst->min_php."\n"); -$inst->is_update = true; - echo "This application will update ISPConfig 3 on your server.\n\n"; //* Make a backup before we start the update diff --git a/interface/web/tools/resync.php b/interface/web/tools/resync.php index b17cfb57d..b7cd96585 100644 --- a/interface/web/tools/resync.php +++ b/interface/web/tools/resync.php @@ -599,6 +599,19 @@ class page_action extends tform_actions { } $msg .= '
'; } + + $entries = $app->plugin->raiseEvent('tools:resync:get_resync_entries', $this->dataRecord, true); + if(is_array($entries) && !empty($entries)) { + foreach($entries as $entry) { + if(!isset($entry['db_table']) || !isset($entry['db_table']) || !isset($entry['db_table']) || !isset($entry['db_table']) || !isset($entry['db_table']) || !isset($entry['db_table'])) { + continue; + } + if(!isset($entry['active'])) { + $entry['active'] = true; + } + $msg .= $this->do_resync($entry['db_table'], $entry['index_field'], $entry['server_type'], $entry['server_id'], $entry['msg_field'], $entry['wordbook'], $entry['active']); + } + } echo $msg; } //* end onSumbmit diff --git a/interface/web/tools/templates/resync.htm b/interface/web/tools/templates/resync.htm index 9d34254a3..d9d76a50e 100644 --- a/interface/web/tools/templates/resync.htm +++ b/interface/web/tools/templates/resync.htm @@ -122,6 +122,8 @@
+ +{tmpl_hook name="end_form"}
diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php new file mode 100644 index 000000000..e7061f783 --- /dev/null +++ b/server/lib/classes/addon_installer.inc.php @@ -0,0 +1,178 @@ +system->tempdir(sys_get_temp_dir(), 'addon_', 0700); + if(!$temp_dir) { + throw new AddonInstallerException('Could not create temp dir.'); + } + + $ret = null; + $retval = 0; + $cmd = $unzip . ' -d ' . escapeshellarg($temp_dir) . ' ' . escapeshellarg($package_file); + exec($cmd, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Package extraction failed.'); + } + + return $temp_dir; + } + + /** + * @param string $path + * @return string + * @throws AddonInstallerValidationException + */ + private function validatePackage($path) { + if(!is_dir($path)) { + throw new AddonInstallerValidationException('Invalid path.'); + } + + $ini_file = $path . '/addon.ini'; + if(!is_file($ini_file)) { + throw new AddonInstallerValidationException('Addon ini file missing.'); + } + + $ini = parse_ini_file($ini_file, true); + if(!$ini || !isset($ini['addon'])) { + throw new AddonInstallerValidationException('Ini file is missing addon section.'); + } + + $addon = $ini['addon']; + if(!isset($addon['ident']) || !isset($addon['name']) || !isset($addon['version'])) { + throw new AddonInstallerValidationException('Ini file is missing addon ident/name/version.'); + } + + $class_file = $path . '/' . $addon['ident'] . '.addon.php'; + if(!is_file($class_file)) { + throw new AddonInstallerValidationException('Package is missing main addon class.'); + } + + if(isset($ini['ispconfig']['version.min']) && $ini['ispconfig']['version.min'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '>')) { + throw new AddonInstallerValidationException('Addon requires at least ISPConfig version ' . $ini['ispconfig']['version.min'] . '.'); + } elseif(isset($ini['ispconfig']['version.max']) && $ini['ispconfig']['version.max'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '<')) { + throw new AddonInstallerValidationException('Addon allows at max ISPConfig version ' . $ini['ispconfig']['version.max'] . '.'); + } + + $addon['class_file'] = $class_file; + $addon['class_name'] = substr(basename($class_file), 0, -10) . '_addon_installer'; + + return $addon; + } + + private function getInstalledAddonVersion($ident) { + global $app, $conf; + + $file_version = false; + $db_version = false; + + $addon_path = realpath($conf['rootpath'] . '/..') . '/addons'; + // check for previous version + if(is_dir($addon_path . '/' . $ident) && is_file($addon_path . '/' . $ident . '/addon.ini')) { + $addon = parse_ini_file($addon_path . '/' . $ident . '/addon.ini', true); + if(!$addon || !isset($addon['version']) || !isset($addon['ident']) || $addon['ident'] != $ident) { + throw new AddonInstallerException('Installed app found but it is invalid.'); + } + + $file_version = $addon['version']; + } + + $check = $app->db->queryOneRecord('SELECT `addon_version` FROM `addons` WHERE `addon_ident` = ?', $ident); + if($check && $check['addon_version']) { + $db_version = $check['addon_version']; + } + + if(!$file_version && !$db_version) { + return false; + } elseif($file_version != $db_version) { + throw new AddonInstallerException('Addon version mismatch in database (' . $db_version . ') and file system (' . $file_version . ').'); + } + + return $file_version; + + } + + /** + * @param string $package_file Full path + * @param boolean $force true if previous addon with same or higher version should be overwritten + * @throws AddonInstallerException + * @throws AddonInstallerValidationException + */ + public function installAddon($package_file, $force = false) { + if(!is_file($package_file)) { + throw new AddonInstallerException('Package file not found.'); + } elseif(substr($package_file, -4) !== '.pkg') { + throw new AddonInstallerException('Invalid package file.'); + } + + $tmp_dir = $this->extractPackage($package_file); + if(!$tmp_dir) { + // extracting failed + throw new AddonInstallerException('Package extraction failed.'); + } + + $addon = $this->validatePackage($tmp_dir); + if(!$addon) { + throw new AddonInstallerException('Package validation failed.'); + } + + $is_update = false; + $previous = $this->getInstalledAddonVersion($addon['ident']); + if($previous !== false) { + // this is an update + if(version_compare($previous, $addon['version'], '>') && $force !== true) { + throw new AddonInstallerException('Installed version is newer than the one to install.'); + } elseif(version_compare($previous, $addon['version'], '=') && $force !== true) { + throw new AddonInstallerException('Installed version is the same as the one to install.'); + } + $is_update = true; + } + include $addon['class_file']; + if(!class_exists($addon['class_name'])) { + throw new AddonInstallerException('Could not find main class in addon file.'); + } + + $class_name = $addon['class_name']; + /* @var $inst ispconfig_addon_installer_base */ + $inst = new $class_name(); + $inst->setAddonName($addon['name']); + $inst->setAddonIdent($addon['ident']); + $inst->setAddonVersion($addon['version']); + $inst->setAddonTempDir($tmp_dir); + + if($is_update === true) { + $inst->onBeforeUpdate(); + $inst->onUpdate(); + $inst->onAfterUpdate(); + } else { + $inst->onBeforeInstall(); + $inst->onInstall(); + $inst->onAfterInstall(); + } + + return true; + } + +} diff --git a/server/lib/classes/functions.inc.php b/server/lib/classes/functions.inc.php index b20f3ab0e..0470f4746 100644 --- a/server/lib/classes/functions.inc.php +++ b/server/lib/classes/functions.inc.php @@ -297,6 +297,12 @@ class functions { } } } + + $tmp_ips = $app->plugins->raiseAction('get_server_ips', 0, true); + if(is_array($tmp_ips) && !empty($tmp_ips)) { + $ips = array_merge($ips, $tmp_ips); + } + $ips = array_unique($ips); sort($ips, SORT_NUMERIC); diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php new file mode 100644 index 000000000..e971321ce --- /dev/null +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -0,0 +1,161 @@ +addon_ident = preg_replace('/_addon_installer$/', '', get_called_class()); + } + + public function setAddonName($name) { + $this->addon_name = $name; + } + + public function setAddonIdent($ident) { + $this->addon_ident = $ident; + } + + public function setAddonVersion($version) { + $this->addon_version = $version; + } + + public function setAddonTempDir($path) { + $this->temp_dir = $path; + } + + protected function copyInterfaceFiles() { + global $conf; + + $install_dir = realpath($conf['rootpath'] . '/..'); + + if(is_dir($this->temp_dir . '/interface')) { + $ret = null; + $retval = 0; + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/interface') . ' ' . escapeshellarg($install_dir . '/'); + exec($command, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + } + + return true; + } else { + return false; + } + } + + protected function copyServerFiles() { + global $conf; + + $install_dir = realpath($conf['rootpath'] . '/..'); + + if(is_dir($this->temp_dir . '/server')) { + $ret = null; + $retval = 0; + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/server'). ' ' . escapeshellarg($install_dir . '/'); + exec($command, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + } + return true; + } else { + return false; + } + } + + protected function executeSqlStatements() { + global $app, $conf; + + // create addon entry if not existing + $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; + $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); + + $incremental = false; + $check = $app->db->queryOneRecord('SELECT `db_version` FROM `addons` WHERE `addon_ident` = ?', $this->addon_ident); + if($check) { + $incremental = 0; + if($check['db_version']) { + $incremental = $check['db_version']; + } + } + + + $mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($conf['db_host']) . ' -u ' . escapeshellarg($conf['db_user']) . ' -p' . escapeshellarg($conf['db_password']) . ' -P ' . escapeshellarg($conf['db_port']) . ' -D ' . escapeshellarg($conf['db_database']); + + if($incremental === false) { + $sql_file = $this->temp_dir . '/install/sql/' . $this->addon_ident . '.sql'; + if(is_file($sql_file)) { + $ret = null; + $retval = 0; + exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); + if($retval != 0) { + /* TODO: log error! */ + } + } + } else { + $new_db_version = $incremental; + while(true) { + $sql_file = $this->temp_dir . '/install/sql/incremental/upd_' . str_pad($new_db_version + 1, '0', 5, STR_PAD_LEFT) . '.sql'; + if(!is_file($sql_file)) { + break; + } else { + $ret = null; + $retval = 0; + exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); + if($retval != 0) { + /* TODO: log error! */ + } + } + + $new_db_version++; + } + + $app->db->query('UPDATE `addons` SET `addon_version` = ?, `db_version` = ? WHERE `addon_ident` = ?', $this->addon_version, $new_db_version, $this->addon_ident); + } + + return true; + } + + public function onBeforeInstall() { } + + public function onInstall() { + $this->copyInterfaceFiles(); + $this->copyServerFiles(); + $this->executeSqlStatements(); + } + + public function onAfterInstall() { } + + public function onBeforeUpdate() { } + + public function onUpdate() { + $this->copyInterfaceFiles(); + $this->copyServerFiles(); + $this->executeSqlStatements(); + } + + public function onAfterUpdate() { } + + + + public function onRaisedInstallerEvent($event_name) { + + } +} + +class AddonInstallerException extends Exception { + public function __construct($message = "", $code = 0, $previous = null) { + parent::__construct($message, $code, $previous); + } +} + +class AddonInstallerValidationException extends AddonInstallerException { } \ No newline at end of file diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php index adcc39f84..dc5a8dde8 100644 --- a/server/lib/classes/system.inc.php +++ b/server/lib/classes/system.inc.php @@ -2044,7 +2044,32 @@ class system{ return true; } + + public function tempdir($parent_path = null, $prefix = 'tmp_', $mode = 0700) { + if(is_null($parent_path)) { + $parent_path = sys_get_temp_dir(); + } + + $parent_path = rtrim($parent_path, '/'); + if(!is_dir($parent_path) || !is_writable($parent_path)) { + return false; + } + + if(strpbrk($prefix, '\\/:*?"<>|') !== false) { + return false; + } + + $path = false; + $tries = 0; + while($tries < 1000) { + $tries++; + $path = $parent_path . FS_DIV . uniqid($prefix, true); + if(mkdir($path, $mode)) { + break; + } + } + + return $path; + } } - -?> -- GitLab From f8b551ed0aceb1c71dcdf4a5bef21a1691056af8 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 15:53:55 +0100 Subject: [PATCH 220/310] - added helper script for installing addons --- server/addons.php | 56 +++++++++---------- .../ispconfig_addon_installer_base.inc.php | 27 +++++++++ 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/server/addons.php b/server/addons.php index 615a56d74..f914e496e 100644 --- a/server/addons.php +++ b/server/addons.php @@ -1,7 +1,7 @@ uses('ini_parser,file,services,getconf,system,cron,functions'); -$app->load('libdatetime,cronjob'); - -// Path settings -$path = SCRIPT_PATH . '/lib/classes/cron.d'; - -//** Get commandline options -$cmd_opt = getopt('', array('cronjob::')); - -if(isset($cmd_opt['cronjob']) && is_file($path.'/'.$cmd_opt['cronjob'])) { - // Cronjob that shell be run - $cronjob_file = $cmd_opt['cronjob']; -} else { - die('Usage example: php cron_debug.php --cronjob=100-mailbox_stats.inc.php'); +if(!isset($_SERVER['argv'])) { + die('No package path given.'); } -// Load and run the cronjob -$name = substr($cronjob_file, 0, strpos($cronjob_file, '.')); -if(preg_match('/^\d+\-(.*)$/', $name, $match)) $name = $match[1]; // strip numerical prefix from file name -include $path . '/' . $cronjob_file; -$class_name = 'cronjob_' . $name; -$cronjob = new $class_name(); +$action = ''; +$package = ''; -$cronjob->onPrepare(); -$cronjob->onBeforeRun(); -$cronjob->onRunJob(); -$cronjob->onAfterRun(); - -die("finished.\n"); +$argv = $_SERVER['argv']; +for($a = 0; $a < count($argv); $a++) { + if($argv[$a] === '--install' || $argv[$a] === 'install' + || $argv[$a] === '--update' || $argv[$a] === 'update') { + $action = 'install'; + } elseif($argv[$a] === '--uninstall' || $argv[$a] === 'uninstall') { + $action = 'uninstall'; + } elseif(substr($argv[$a], -4) === '.pkg' && is_file($argv[$a])) { + $package = $argv[$a]; + } else { + die('Unknown argument ' . $argv[$a]); + } +} -?> +if($action == 'uninstall') { + die('Automatic uninstall not supported, yet.'); +} else { + try { + $app->addon_installer->installAddon($package); + } catch(Exception $e) { + die('Error: ' . $e->getMessage() . "\n"); + } +} \ No newline at end of file diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index e971321ce..e02ac0036 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -72,6 +72,31 @@ class ispconfig_addon_installer_base { } } + protected function copyAddonFiles() { + global $app, $conf; + + $install_dir = realpath($conf['rootpath'] . '/..') . '/addons/' . $this->addon_ident; + if(!is_dir($install_dir)) { + if(!$app->system->mkdir($install_dir, false, 0750, true)) { + throw new AddonInstallerException('Could not create addons dir ' . $install_dir); + } + } + + if(is_dir($this->temp_dir . '/install')) { + $ret = null; + $retval = 0; + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/addon.ini') . ' ' . escapeshellarg($this->temp_dir . '/' . $this->addon_ident . 'addon.php') . ' ' . escapeshellarg($this->temp_dir . '/install'). ' ' . escapeshellarg($install_dir . '/'); + exec($command, $ret, $retval); + if($retval != 0) { + throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + } + + return true; + } else { + return false; + } + } + protected function executeSqlStatements() { global $app, $conf; @@ -128,6 +153,7 @@ class ispconfig_addon_installer_base { public function onBeforeInstall() { } public function onInstall() { + $this->copyAddonFiles(); $this->copyInterfaceFiles(); $this->copyServerFiles(); $this->executeSqlStatements(); @@ -138,6 +164,7 @@ class ispconfig_addon_installer_base { public function onBeforeUpdate() { } public function onUpdate() { + $this->copyAddonFiles(); $this->copyInterfaceFiles(); $this->copyServerFiles(); $this->executeSqlStatements(); -- GitLab From d30a95cc0f70d769f33bd5c2a48bcf46bee9c621 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 15:54:14 +0100 Subject: [PATCH 221/310] - executable bit for addons.php --- server/addons.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 server/addons.php diff --git a/server/addons.php b/server/addons.php old mode 100644 new mode 100755 -- GitLab From 7dbf4c1ecb8376b2783aeb612bccc92561ba54c1 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 15:56:39 +0100 Subject: [PATCH 222/310] - fixed warning on missing addons dir --- install/lib/installer_base.lib.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index f3db824cd..49bf4ed77 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2828,6 +2828,9 @@ class installer_base { } private function loadAddonClasses($path) { + if(!is_dir($path)) { + return false; + } $libpath = $path; if(($dir = opendir($libpath))) { while(false !== ($cur = readdir($dir))) { -- GitLab From 2bdcab1ef303bc737ca514dc79cc07c85d7f80ef Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:11:50 +0100 Subject: [PATCH 223/310] - raised version to 3.2.0dev - fixes in addon installer --- install/sql/ispconfig3.sql | 2 +- install/tpl/config.inc.php.master | 2 +- interface/lib/config.inc.php | 2 +- server/addons.php | 2 +- server/lib/classes/addon_installer.inc.php | 4 ++++ 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 7462bbb74..1b168b44b 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -2270,7 +2270,7 @@ INSERT INTO `sys_user` (`userid`, `sys_userid`, `sys_groupid`, `sys_perm_user`, -- Dumping data for table `sys_config` -- -INSERT INTO sys_config VALUES ('db','db_version','3.1dev'); +INSERT INTO sys_config VALUES ('db','db_version','3.2.0dev'); INSERT INTO sys_config VALUES ('interface','session_timeout','0'); SET FOREIGN_KEY_CHECKS = 1; diff --git a/install/tpl/config.inc.php.master b/install/tpl/config.inc.php.master index 02a7b2f65..c3ed1c06b 100644 --- a/install/tpl/config.inc.php.master +++ b/install/tpl/config.inc.php.master @@ -56,7 +56,7 @@ $revision = str_replace(array('Revision:','$',' '), '', $svn_revision); //** Application define('ISPC_APP_TITLE', 'ISPConfig'); -define('ISPC_APP_VERSION', '3.1dev'); +define('ISPC_APP_VERSION', '3.2.0dev'); define('DEVSYSTEM', 0); diff --git a/interface/lib/config.inc.php b/interface/lib/config.inc.php index 3c534f3f2..e5789ace3 100644 --- a/interface/lib/config.inc.php +++ b/interface/lib/config.inc.php @@ -45,7 +45,7 @@ $revision = str_replace(array('Revision:', '$', ' '), '', $svn_revision); //** Application define('ISPC_APP_TITLE', 'ISPConfig'); -define('ISPC_APP_VERSION', '3.1dev'); +define('ISPC_APP_VERSION', '3.2.0dev'); define('DEVSYSTEM', 0); diff --git a/server/addons.php b/server/addons.php index f914e496e..84d0b7897 100755 --- a/server/addons.php +++ b/server/addons.php @@ -46,7 +46,7 @@ $action = ''; $package = ''; $argv = $_SERVER['argv']; -for($a = 0; $a < count($argv); $a++) { +for($a = 1; $a < count($argv); $a++) { if($argv[$a] === '--install' || $argv[$a] === 'install' || $argv[$a] === '--update' || $argv[$a] === 'update') { $action = 'install'; diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php index e7061f783..82df5008d 100644 --- a/server/lib/classes/addon_installer.inc.php +++ b/server/lib/classes/addon_installer.inc.php @@ -121,6 +121,10 @@ class addon_installer { * @throws AddonInstallerValidationException */ public function installAddon($package_file, $force = false) { + global $app; + + $app->load('ispconfig_addon_installer_base'); + if(!is_file($package_file)) { throw new AddonInstallerException('Package file not found.'); } elseif(substr($package_file, -4) !== '.pkg') { -- GitLab From 9ab5689634c673f70a91f4397b64320f0c3328e8 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:17:41 +0100 Subject: [PATCH 224/310] - addon installer fixes --- server/lib/classes/addon_installer.inc.php | 2 ++ server/lib/classes/ispconfig_addon_installer_base.inc.php | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php index 82df5008d..0b76ebf9f 100644 --- a/server/lib/classes/addon_installer.inc.php +++ b/server/lib/classes/addon_installer.inc.php @@ -176,6 +176,8 @@ class addon_installer { $inst->onAfterInstall(); } + exec('rm -rf ' . escapeshellarg($tmp_dir)); + return true; } diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index e02ac0036..1e3cf2ec9 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -85,10 +85,10 @@ class ispconfig_addon_installer_base { if(is_dir($this->temp_dir . '/install')) { $ret = null; $retval = 0; - $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/addon.ini') . ' ' . escapeshellarg($this->temp_dir . '/' . $this->addon_ident . 'addon.php') . ' ' . escapeshellarg($this->temp_dir . '/install'). ' ' . escapeshellarg($install_dir . '/'); + $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/addon.ini') . ' ' . escapeshellarg($this->temp_dir . '/' . $this->addon_ident . '.addon.php') . ' ' . escapeshellarg($this->temp_dir . '/install'). ' ' . escapeshellarg($install_dir . '/'); exec($command, $ret, $retval); if($retval != 0) { - throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); + /* TODO: logging */ } return true; @@ -174,7 +174,7 @@ class ispconfig_addon_installer_base { - public function onRaisedInstallerEvent($event_name) { + public function onRaisedInstallerEvent($event_name, $data) { } } -- GitLab From 02e3ef60f146904063da2e0f786ba820fa08fb75 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:19:29 +0100 Subject: [PATCH 225/310] - only to mysql check and not repair (innoDB does not support repair table) --- install/lib/update.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/lib/update.lib.php b/install/lib/update.lib.php index 8943aafdc..2351fbd4d 100644 --- a/install/lib/update.lib.php +++ b/install/lib/update.lib.php @@ -103,7 +103,8 @@ function checkDbHealth() { $notok = array(); echo "Checking ISPConfig database .. "; - exec("mysqlcheck -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." -r ".escapeshellarg($conf["mysql"]["database"]), $result); + $result = null; + exec("mysqlcheck -h ".escapeshellarg($conf['mysql']['host'])." -u ".escapeshellarg($conf['mysql']['admin_user'])." -p".escapeshellarg($conf['mysql']['admin_password'])." -P ".escapeshellarg($conf['mysql']['port'])." ".escapeshellarg($conf["mysql"]["database"]), $result); for( $i=0; $i Date: Fri, 16 Nov 2018 16:39:36 +0100 Subject: [PATCH 226/310] - added some logging --- server/lib/classes/addon_installer.inc.php | 48 +++++++++++++++++-- .../ispconfig_addon_installer_base.inc.php | 20 ++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php index 0b76ebf9f..07301f34f 100644 --- a/server/lib/classes/addon_installer.inc.php +++ b/server/lib/classes/addon_installer.inc.php @@ -13,19 +13,24 @@ class addon_installer { $ret = null; $retval = 0; + $app->log('Extracting addon package ' . $package_file, 0, false); + $cmd = 'which unzip'; $tmp = explode("\n", exec($cmd, $ret, $retval)); if($retval != 0) { + $app->log('The unzip command was not found on the server.', 2, false); throw new AddonInstallerException('unzip tool not found.'); } $unzip = reset($tmp); unset($tmp); if(!$unzip) { + $app->log('Unzip tool was not found.', 2, false); throw new AddonInstallerException('unzip tool not found.'); } $temp_dir = $app->system->tempdir(sys_get_temp_dir(), 'addon_', 0700); if(!$temp_dir) { + $app->log('Could not create the temp dir.', 2, false); throw new AddonInstallerException('Could not create temp dir.'); } @@ -34,9 +39,12 @@ class addon_installer { $cmd = $unzip . ' -d ' . escapeshellarg($temp_dir) . ' ' . escapeshellarg($package_file); exec($cmd, $ret, $retval); if($retval != 0) { + $app->log('Package extraction failed.', 2, false); throw new AddonInstallerException('Package extraction failed.'); } + $app->log('Extracted to ' . $temp_dir, 0, false); + return $temp_dir; } @@ -46,36 +54,48 @@ class addon_installer { * @throws AddonInstallerValidationException */ private function validatePackage($path) { + $app->log('Validating extracted addon at ' . $path, 0, false); + if(!is_dir($path)) { + $app->log('Invalid path.', 2, false); throw new AddonInstallerValidationException('Invalid path.'); } $ini_file = $path . '/addon.ini'; if(!is_file($ini_file)) { + $app->log('Addon ini file missing.', 2, false); throw new AddonInstallerValidationException('Addon ini file missing.'); } + $app->log('Parsing ini ' . $ini_file, 0, false); $ini = parse_ini_file($ini_file, true); if(!$ini || !isset($ini['addon'])) { + $app->log('Ini file could not be read.', 2, false); throw new AddonInstallerValidationException('Ini file is missing addon section.'); } $addon = $ini['addon']; if(!isset($addon['ident']) || !isset($addon['name']) || !isset($addon['version'])) { + $app->log('Addon data in ini file missing or invalid.', 2, false); throw new AddonInstallerValidationException('Ini file is missing addon ident/name/version.'); } $class_file = $path . '/' . $addon['ident'] . '.addon.php'; if(!is_file($class_file)) { + $app->log('Base class file in addon not found', 2, false); throw new AddonInstallerValidationException('Package is missing main addon class.'); } if(isset($ini['ispconfig']['version.min']) && $ini['ispconfig']['version.min'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '>')) { + $app->log('ISPConfig version too low for this addon.', 2, false); throw new AddonInstallerValidationException('Addon requires at least ISPConfig version ' . $ini['ispconfig']['version.min'] . '.'); } elseif(isset($ini['ispconfig']['version.max']) && $ini['ispconfig']['version.max'] && version_compare($ini['ispconfig']['version.min'], ISPC_APP_VERSION, '<')) { + $app->log('ISPConfig version too high for this addon.', 2, false); throw new AddonInstallerValidationException('Addon allows at max ISPConfig version ' . $ini['ispconfig']['version.max'] . '.'); } + $app->log('Loaded addon installer ' . $class_file, 0, false); + $addon['class_file'] = $class_file; $addon['class_name'] = substr(basename($class_file), 0, -10) . '_addon_installer'; @@ -92,21 +112,30 @@ class addon_installer { // check for previous version if(is_dir($addon_path . '/' . $ident) && is_file($addon_path . '/' . $ident . '/addon.ini')) { $addon = parse_ini_file($addon_path . '/' . $ident . '/addon.ini', true); + if($addon && isset($addon['addon'])) { + $addon = $addon['addon']; // ini section + } else { + $addon = false; + } if(!$addon || !isset($addon['version']) || !isset($addon['ident']) || $addon['ident'] != $ident) { - throw new AddonInstallerException('Installed app found but it is invalid.'); + $app->log('Could not get version of installed addon.', 2, false); + throw new AddonInstallerException('Installed app ' . $ident . ' found but it is invalid.'); } $file_version = $addon['version']; + $app->log('Installed version of addon ' . $ident . ' is ' . $file_version, 0, false); } $check = $app->db->queryOneRecord('SELECT `addon_version` FROM `addons` WHERE `addon_ident` = ?', $ident); if($check && $check['addon_version']) { $db_version = $check['addon_version']; + $app->log('Installed version of addon ' . $ident . ' (in db) is ' . $db_version . '.', 0, false); } if(!$file_version && !$db_version) { return false; } elseif($file_version != $db_version) { + $app->log('Version mismatch between ini file and database (' . $file_version . ' != ' . $db_version . ').', 0, false); throw new AddonInstallerException('Addon version mismatch in database (' . $db_version . ') and file system (' . $file_version . ').'); } @@ -126,14 +155,17 @@ class addon_installer { $app->load('ispconfig_addon_installer_base'); if(!is_file($package_file)) { + $app->log('Package file not found: ' . $package_file, 2, false); throw new AddonInstallerException('Package file not found.'); } elseif(substr($package_file, -4) !== '.pkg') { + $app->log('Invalid package file: ' . $package_file, 2, false); throw new AddonInstallerException('Invalid package file.'); } $tmp_dir = $this->extractPackage($package_file); if(!$tmp_dir) { // extracting failed + $app->log('Package extraction failed.', 2, false); throw new AddonInstallerException('Package extraction failed.'); } @@ -141,25 +173,34 @@ class addon_installer { if(!$addon) { throw new AddonInstallerException('Package validation failed.'); } + $app->log('Package validated.', 0, false); $is_update = false; $previous = $this->getInstalledAddonVersion($addon['ident']); if($previous !== false) { // this is an update if(version_compare($previous, $addon['version'], '>') && $force !== true) { + $app->log('Installed version is newer than the one to install and --force not used.', 2, false); throw new AddonInstallerException('Installed version is newer than the one to install.'); } elseif(version_compare($previous, $addon['version'], '=') && $force !== true) { + $app->log('Installed version is the same as the one to install and --force not used.', 2, false); throw new AddonInstallerException('Installed version is the same as the one to install.'); } $is_update = true; } + + $app->log('Including package class file ' . $addon['class_file'], 0, false); + include $addon['class_file']; - if(!class_exists($addon['class_name'])) { + $class_name = $addon['class_name']; + if(!class_exists($class_name)) { + $app->log('Class name ' . $class_name . ' not found in class file ' . $addon['class_file'], 2, false); throw new AddonInstallerException('Could not find main class in addon file.'); } - $class_name = $addon['class_name']; /* @var $inst ispconfig_addon_installer_base */ + $app->log('Instanciating installer class ' . $class_name, 0, false); + $inst = new $class_name(); $inst->setAddonName($addon['name']); $inst->setAddonIdent($addon['ident']); @@ -178,6 +219,7 @@ class addon_installer { exec('rm -rf ' . escapeshellarg($tmp_dir)); + $app->log('Installation completed.', 0, false); return true; } diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index 1e3cf2ec9..66b7b5131 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -36,6 +36,7 @@ class ispconfig_addon_installer_base { protected function copyInterfaceFiles() { global $conf; + $app->log('Copying interface files.', 0, false); $install_dir = realpath($conf['rootpath'] . '/..'); if(is_dir($this->temp_dir . '/interface')) { @@ -44,6 +45,7 @@ class ispconfig_addon_installer_base { $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/interface') . ' ' . escapeshellarg($install_dir . '/'); exec($command, $ret, $retval); if($retval != 0) { + $app->log('Copying interface files failed.', 2, false); throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); } @@ -56,6 +58,8 @@ class ispconfig_addon_installer_base { protected function copyServerFiles() { global $conf; + $app->log('Copying server files.', 0, false); + $install_dir = realpath($conf['rootpath'] . '/..'); if(is_dir($this->temp_dir . '/server')) { @@ -64,6 +68,7 @@ class ispconfig_addon_installer_base { $command = 'cp -rf ' . escapeshellarg($this->temp_dir . '/server'). ' ' . escapeshellarg($install_dir . '/'); exec($command, $ret, $retval); if($retval != 0) { + $app->log('Copying interface files failed.', 2, false); throw new AddonInstallerException('Command ' . $command . ' failed with code ' . $retval); } return true; @@ -75,9 +80,12 @@ class ispconfig_addon_installer_base { protected function copyAddonFiles() { global $app, $conf; + $app->log('Copying addon files.', 0, false); + $install_dir = realpath($conf['rootpath'] . '/..') . '/addons/' . $this->addon_ident; if(!is_dir($install_dir)) { if(!$app->system->mkdir($install_dir, false, 0750, true)) { + $app->log('Addons dir missing and could not be created.', 2, false); throw new AddonInstallerException('Could not create addons dir ' . $install_dir); } } @@ -89,6 +97,7 @@ class ispconfig_addon_installer_base { exec($command, $ret, $retval); if($retval != 0) { /* TODO: logging */ + $app->log('Warning or error on copying addon files. Returncode of command ' . $command . ' was: ' . $retval .'.', 0, false); } return true; @@ -100,6 +109,7 @@ class ispconfig_addon_installer_base { protected function executeSqlStatements() { global $app, $conf; + $app->log('Adding addon entry to db.', 0, false); // create addon entry if not existing $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); @@ -110,6 +120,7 @@ class ispconfig_addon_installer_base { $incremental = 0; if($check['db_version']) { $incremental = $check['db_version']; + $app->log('Current db version is ' . $incremental . '.', 0, false); } } @@ -121,9 +132,11 @@ class ispconfig_addon_installer_base { if(is_file($sql_file)) { $ret = null; $retval = 0; + $app->log('Loading ' . $sql_file . ' into db.', 0, false); exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); if($retval != 0) { /* TODO: log error! */ + $app->log('Loading ' . $sql_file . ' into db failed.', 1, false); } } } else { @@ -135,9 +148,11 @@ class ispconfig_addon_installer_base { } else { $ret = null; $retval = 0; + $app->log('Loading ' . $sql_file . ' into db.', 0, false); exec($mysql_command . ' < ' . escapeshellarg($sql_file), $ret, $retval); if($retval != 0) { /* TODO: log error! */ + $app->log('Loading ' . $sql_file . ' into db failed.', 1, false); } } @@ -145,6 +160,7 @@ class ispconfig_addon_installer_base { } $app->db->query('UPDATE `addons` SET `addon_version` = ?, `db_version` = ? WHERE `addon_ident` = ?', $this->addon_version, $new_db_version, $this->addon_ident); + $app->log('Db version of addon is now ' . $new_db_version . '.', 0, false); } return true; @@ -153,10 +169,12 @@ class ispconfig_addon_installer_base { public function onBeforeInstall() { } public function onInstall() { + $app->log('Running onInstall()', 0, false); $this->copyAddonFiles(); $this->copyInterfaceFiles(); $this->copyServerFiles(); $this->executeSqlStatements(); + $app->log('Finished onInstall()', 0, false); } public function onAfterInstall() { } @@ -164,10 +182,12 @@ class ispconfig_addon_installer_base { public function onBeforeUpdate() { } public function onUpdate() { + $app->log('Running onUpdate()', 0, false); $this->copyAddonFiles(); $this->copyInterfaceFiles(); $this->copyServerFiles(); $this->executeSqlStatements(); + $app->log('Finished onUpdate()', 0, false); } public function onAfterUpdate() { } -- GitLab From b8b1b5405c0d425c2441fc21872515da59f056fd Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:41:22 +0100 Subject: [PATCH 227/310] - fixed php warning from installer --- install/lib/classes/ispconfig_addon_installer.inc.php | 2 +- install/lib/installer_base.lib.php | 4 ++-- server/lib/classes/ispconfig_addon_installer_base.inc.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install/lib/classes/ispconfig_addon_installer.inc.php b/install/lib/classes/ispconfig_addon_installer.inc.php index 78ef7e0b0..f1b457af8 100644 --- a/install/lib/classes/ispconfig_addon_installer.inc.php +++ b/install/lib/classes/ispconfig_addon_installer.inc.php @@ -14,7 +14,7 @@ class ispconfig_addon_installer_base { $this->addon_ident = preg_replace('/_addon_installer$/', '', get_called_class()); } - public function onRaisedInstallerEvent($event_name, $data) { + public function onRaisedInstallerEvent($event_name, $data = false) { } } diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 49bf4ed77..38632d01d 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2864,7 +2864,7 @@ class installer_base { } } - public function raiseEvent($event_name) { + public function raiseEvent($event_name, $data = false) { global $conf; if(is_null($this->addon_classes)) { @@ -2879,7 +2879,7 @@ class installer_base { reset($this->addon_classes); foreach($this->addon_classes as $cl) { if(method_exists($cl, $call_method)) { - call_user_func(array($cl, $call_method), $event_name); + call_user_func(array($cl, $call_method), $event_name, $data); } } } diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index 66b7b5131..2aa2d184a 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -194,7 +194,7 @@ class ispconfig_addon_installer_base { - public function onRaisedInstallerEvent($event_name, $data) { + public function onRaisedInstallerEvent($event_name, $data = false) { } } -- GitLab From 15c14048aeb0406e3d7f29ca4420f6860420eabd Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:44:18 +0100 Subject: [PATCH 228/310] - fixed missing globals --- server/lib/classes/addon_installer.inc.php | 2 ++ server/lib/classes/ispconfig_addon_installer_base.inc.php | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/server/lib/classes/addon_installer.inc.php b/server/lib/classes/addon_installer.inc.php index 07301f34f..3a108e8bb 100644 --- a/server/lib/classes/addon_installer.inc.php +++ b/server/lib/classes/addon_installer.inc.php @@ -54,6 +54,8 @@ class addon_installer { * @throws AddonInstallerValidationException */ private function validatePackage($path) { + global $app; + $app->log('Validating extracted addon at ' . $path, 0, false); if(!is_dir($path)) { diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index 2aa2d184a..5767864c2 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -34,7 +34,7 @@ class ispconfig_addon_installer_base { } protected function copyInterfaceFiles() { - global $conf; + global $app, $conf; $app->log('Copying interface files.', 0, false); $install_dir = realpath($conf['rootpath'] . '/..'); @@ -56,7 +56,7 @@ class ispconfig_addon_installer_base { } protected function copyServerFiles() { - global $conf; + global $app, $conf; $app->log('Copying server files.', 0, false); @@ -169,6 +169,8 @@ class ispconfig_addon_installer_base { public function onBeforeInstall() { } public function onInstall() { + global $app; + $app->log('Running onInstall()', 0, false); $this->copyAddonFiles(); $this->copyInterfaceFiles(); @@ -182,6 +184,8 @@ class ispconfig_addon_installer_base { public function onBeforeUpdate() { } public function onUpdate() { + global $app; + $app->log('Running onUpdate()', 0, false); $this->copyAddonFiles(); $this->copyInterfaceFiles(); -- GitLab From 94087a5513a7df15c8339baa89bfb2231004081b Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:45:48 +0100 Subject: [PATCH 229/310] - main sql file of addons not loaded --- .../lib/classes/ispconfig_addon_installer_base.inc.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index 5767864c2..25aaece87 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -109,11 +109,6 @@ class ispconfig_addon_installer_base { protected function executeSqlStatements() { global $app, $conf; - $app->log('Adding addon entry to db.', 0, false); - // create addon entry if not existing - $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; - $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); - $incremental = false; $check = $app->db->queryOneRecord('SELECT `db_version` FROM `addons` WHERE `addon_ident` = ?', $this->addon_ident); if($check) { @@ -124,6 +119,10 @@ class ispconfig_addon_installer_base { } } + $app->log('Adding addon entry to db.', 0, false); + // create addon entry if not existing + $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; + $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); $mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($conf['db_host']) . ' -u ' . escapeshellarg($conf['db_user']) . ' -p' . escapeshellarg($conf['db_password']) . ' -P ' . escapeshellarg($conf['db_port']) . ' -D ' . escapeshellarg($conf['db_database']); -- GitLab From ad447c2715ee97da4c110de5da72a8e0ca9a0247 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:54:07 +0100 Subject: [PATCH 230/310] - store port in mysql_clientdb file - use clientdb config for addon sql files --- install/lib/installer_base.lib.php | 1 + install/tpl/mysql_clientdb.conf.master | 1 + server/lib/classes/ispconfig_addon_installer_base.inc.php | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 38632d01d..70e5bbf10 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -2578,6 +2578,7 @@ class installer_base { $content = str_replace('{hostname}', $conf['mysql']['host'], $content); $content = str_replace('{username}', $conf['mysql']['admin_user'], $content); $content = str_replace('{password}', addslashes($conf['mysql']['admin_password']), $content); + $content = str_replace('{port}', addslashes($conf['mysql']['port']), $content); wf($install_dir.'/server/lib/mysql_clientdb.conf', $content); chmod($install_dir.'/server/lib/mysql_clientdb.conf', 0600); chown($install_dir.'/server/lib/mysql_clientdb.conf', 'root'); diff --git a/install/tpl/mysql_clientdb.conf.master b/install/tpl/mysql_clientdb.conf.master index e6eba1261..c205d7142 100644 --- a/install/tpl/mysql_clientdb.conf.master +++ b/install/tpl/mysql_clientdb.conf.master @@ -3,5 +3,6 @@ $clientdb_host = '{hostname}'; $clientdb_user = '{username}'; $clientdb_password = '{password}'; +$clientdb_port = '{port}'; ?> \ No newline at end of file diff --git a/server/lib/classes/ispconfig_addon_installer_base.inc.php b/server/lib/classes/ispconfig_addon_installer_base.inc.php index 25aaece87..d5b02c65d 100644 --- a/server/lib/classes/ispconfig_addon_installer_base.inc.php +++ b/server/lib/classes/ispconfig_addon_installer_base.inc.php @@ -119,12 +119,14 @@ class ispconfig_addon_installer_base { } } + include '/usr/local/ispconfig/server/lib/mysql_clientdb.conf'; + $app->log('Adding addon entry to db.', 0, false); // create addon entry if not existing $qry = 'INSERT IGNORE INTO `addons` (`addon_ident`, `addon_version`, `addon_name`, `db_version`) VALUES (?, ?, ?, ?)'; $app->db->query($qry, $this->addon_ident, $this->addon_version, $this->addon_name, 0); - $mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($conf['db_host']) . ' -u ' . escapeshellarg($conf['db_user']) . ' -p' . escapeshellarg($conf['db_password']) . ' -P ' . escapeshellarg($conf['db_port']) . ' -D ' . escapeshellarg($conf['db_database']); + $mysql_command = 'mysql --default-character-set=' . escapeshellarg($conf['db_charset']) . ' --force -h ' . escapeshellarg($clientdb_host) . ' -u ' . escapeshellarg($clientdb_user) . ' -p' . escapeshellarg($clientdb_password) . ' -P ' . escapeshellarg($clientdb_port) . ' -D ' . escapeshellarg($conf['db_database']); if($incremental === false) { $sql_file = $this->temp_dir . '/install/sql/' . $this->addon_ident . '.sql'; -- GitLab From 72b935f4fd2c2aaaffa5b8cdeabf2e1ddd38889a Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 16 Nov 2018 16:57:59 +0100 Subject: [PATCH 231/310] - added --force option for addon installer --- server/addons.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/addons.php b/server/addons.php index 84d0b7897..40bf727e9 100755 --- a/server/addons.php +++ b/server/addons.php @@ -44,6 +44,7 @@ if(!isset($_SERVER['argv'])) { $action = ''; $package = ''; +$force = false; $argv = $_SERVER['argv']; for($a = 1; $a < count($argv); $a++) { @@ -52,6 +53,8 @@ for($a = 1; $a < count($argv); $a++) { $action = 'install'; } elseif($argv[$a] === '--uninstall' || $argv[$a] === 'uninstall') { $action = 'uninstall'; + } elseif($argv[$a] === '--force') { + $force = true; } elseif(substr($argv[$a], -4) === '.pkg' && is_file($argv[$a])) { $package = $argv[$a]; } else { @@ -63,7 +66,7 @@ if($action == 'uninstall') { die('Automatic uninstall not supported, yet.'); } else { try { - $app->addon_installer->installAddon($package); + $app->addon_installer->installAddon($package, $force); } catch(Exception $e) { die('Error: ' . $e->getMessage() . "\n"); } -- GitLab From ef8ba79ac7ad5ecc20a40c045385ae6bffb2897a Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 22 Nov 2018 12:00:13 +0100 Subject: [PATCH 232/310] Removed 3 unused - searchform - code files. --- interface/lib/classes/searchform.inc.php | 349 ------------------ .../lib/classes/searchform_actions.inc.php | 202 ---------- .../classes/searchform_tpl_generator.inc.php | 136 ------- 3 files changed, 687 deletions(-) delete mode 100644 interface/lib/classes/searchform.inc.php delete mode 100644 interface/lib/classes/searchform_actions.inc.php delete mode 100644 interface/lib/classes/searchform_tpl_generator.inc.php diff --git a/interface/lib/classes/searchform.inc.php b/interface/lib/classes/searchform.inc.php deleted file mode 100644 index 0a290c1d6..000000000 --- a/interface/lib/classes/searchform.inc.php +++ /dev/null @@ -1,349 +0,0 @@ -listDef = $liste; - $this->module = $module; - - //* Fill datasources - foreach($this->listDef['item'] as $key => $field) { - if(is_array($field['datasource'])) { - $this->listDef['item'][$key]['value'] = $this->getDatasourceData($field); - } - } - return true; - } - - /** - * Get the key => value array of a form filed from a datasource definitiom - * - * @param field = array with field definition - * @param record = Dataset as array - * @return key => value array for the value field of a form - */ - - - public function getDatasourceData($field) - { - global $app; - $values = array(); - - if($field['datasource']['type'] == 'SQL') { - //* Preparing SQL string. We will replace some common placeholders - $querystring = $field['datasource']['querystring']; - $querystring = str_replace('{USERID}', $_SESSION['s']['user']['userid'], $querystring); - $querystring = str_replace('{GROUPID}', $_SESSION['s']['user']['default_group'], $querystring); - $querystring = str_replace('{GROUPS}', $_SESSION['s']['user']['groups'], $querystring); - $table_idx = $this->formDef['db_table_idx']; - //$querystring = str_replace('{RECORDID}',$record[$table_idx],$querystring); - $app->uses('tform'); - $querystring = str_replace('{AUTHSQL}', $app->tform->getAuthSQL('r'), $querystring); - - //* Getting the records - $tmp_records = $app->db->queryAllRecords($querystring); - if($app->db->errorMessage != ''){ - die($app->db->errorMessage); - } - if(is_array($tmp_records)) { - $key_field = $field['datasource']['keyfield']; - $value_field = $field['datasource']['valuefield']; - foreach($tmp_records as $tmp_rec) { - $values[$tmp_rec[$key_field]] = $tmp_rec[$value_field]; - } - } - } - if($field['datasource']['type'] == 'CUSTOM') { - //* Calls a custom class to validate this record - if($field['datasource']['class'] != '' and $field['datasource']['function'] != '') { - $datasource_class = $field['datasource']['class']; - $datasource_function = $field['datasource']['function']; - $app->uses($datasource_class); - $record = array(); - $values = $app->$datasource_class->$datasource_function($field, $record); - }else{ - $this->errorMessage .= "Custom datasource class or function is empty
\r\n"; - } - } - return $values; - } - - public function getSearchSQL($sql_where = '') - { - global $db; - - //* Config vars - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - - //* store retrieval query - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - - //* TODO ? hat sich die suche ge�ndert - has itself search ? - $ki = $search_prefix.$field; - if(isset($_REQUEST) and $_REQUEST[$ki] != $_SESSION['search'][$list_name][$ki]){ - $this->searchChanged = 1; - } - - //* suchfield in session store. - if(isset($_REQUEST[$ki])){ - $_SESSION['search'][$list_name][$ki] = $_REQUEST[$ki]; - } - - if($i['formtype'] == 'SELECT'){ - if(is_array($i['value'])) { - $out = ''; - foreach($i['value'] as $k => $v) { - $selected = ($k == $_SESSION['search'][$list_name][$ki] && $_SESSION['search'][$list_name][$ki] != '') ? ' SELECTED' : ''; - $out .= "\r\n"; - } - } - $this->searchValues[$ki] = $out; - }else{ - $this->searchValues[$ki] = $_SESSION['search'][$list_name][$ki]; - } - } - - //* store variables in object. $this->searchValues = $_SESSION["search"][$list_name]; - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - //if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and"; - if($_SESSION['search'][$list_name][$ki] != ''){ - $sql_where .= " $field ".$i['op']." '".$i['prefix'].$_SESSION['search'][$list_name][$ki].$i['suffix']."' and"; - } - } - return ($sql_where != '') ? substr($sql_where, 0, -3) : '1'; - } - - public function getPagingSQL($sql_where = '1') { - global $app, $conf; - - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - $records_per_page = $this->listDef['records_per_page']; - $table = $this->listDef['table']; - - //* set page to seror id session not set - if($_SESSION['search'][$list_name]['page'] == '') $_SESSION['search'][$list_name]['page'] = 0; - - //* Set page size to request if set - if(isset($_REQUEST['page'])) $_SESSION['search'][$list_name]['page'] = $_REQUEST['page']; - - //* TODO PAGE to 0 set, if look for themselves ge?ndert. = page auf 0 setzen, wenn suche sich ge�ndert hat. - if($this->searchChanged == 1) $_SESSION['search'][$list_name]['page'] = 0; - - $sql_von = $_SESSION['search'][$list_name]['page'] * $records_per_page; - $record_count = $app->db->queryOneRecord("SELECT count(*) AS anzahl FROM ?? WHERE $sql_where", $table); - $pages = $app->functions->intval(($record_count['anzahl'] - 1) / $records_per_page); - - $vars['list_file'] = $this->listDef['file']; - $vars['page'] = $_SESSION['search'][$list_name]['page']; - $vars['last_page'] = $_SESSION['search'][$list_name]['page'] - 1; - $vars['next_page'] = $_SESSION['search'][$list_name]['page'] + 1; - $vars['pages'] = $pages; - $vars['max_pages'] = $pages + 1; - $vars['records_gesamt'] = $record_count['anzahl']; - $vars['page_params'] = $this->listDef['page_params']; - - if($_SESSION['search'][$list_name]['page'] > 0) $vars['show_page_back'] = 1; - if($_SESSION['search'][$list_name]['page'] <= $vars['pages'] - 1) $vars['show_page_next'] = 1; - - $this->pagingValues = $vars; - $this->pagingHTML = $this->getPagingHTML($vars); - - return "LIMIT $sql_von, $records_per_page"; - } - - public function getPagingHTML($vars) { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '   '; - if($vars['show_page_back'] == 1){ - $content .= ' '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '   '; - } else{ - $content .= ' '; - } - $content .= ' '; - return $content; - } - - public function getPagingHTMLasTXT($vars) - { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '[|<< ]'; - if($vars['show_page_back'] == 1){ - $content .= '[<< '.$app->lng('Back').'] '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '['.$app->lng('Next').' >>] '; - } - $content .= '[ >>|]'; - return $content; - } - - public function getSortSQL() - { - $sort_field = $this->listDef['sort_field']; - $sort_direction = $this->listDef['sort_direction']; - return ($sort_field != '' && $sort_direction != '') ? "ORDER BY $sort_field $sort_direction" : ''; - } - - public function saveSearchSettings($searchresult_name) - { - global $app, $conf; - - $list_name = $this->listDef['name']; - $settings = $_SESSION['search'][$list_name]; - unset($settings['page']); - $data = serialize($settings); - - $userid = $_SESSION['s']['user']['userid']; - $groupid = $_SESSION['s']['user']['default_group']; - $sys_perm_user = 'riud'; - $sys_perm_group = 'r'; - $sys_perm_other = ''; - $module = $_SESSION['s']['module']['name']; - $searchform = $this->listDef['name']; - $title = $searchresult_name; - - $sql = 'INSERT INTO `searchform` ( ' - .'`sys_userid` , `sys_groupid` , `sys_perm_user` , `sys_perm_group` , `sys_perm_other` , `module` , `searchform` , `title` , `data` ' - .')VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'; - $app->db->query($sql, $userid, $groupid, $sys_perm_user, $sys_perm_group, $sys_perm_other, $module, $searchform, $title, $data); - } - - public function decode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'DATE': - if($val > 0) { - $record[$key] = date($this->dateformat, $record[$key]); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $record[$key]; - break; - - case 'CURRENCY': - $record[$key] = number_format($record[$key], 2, ',', ''); - break; - - - case 'VARCHAR': - case 'TEXT': - default: - $record[$key] = stripslashes($record[$key]); - break; - } - } - } - return $record; - } - - /* TODO: check for double quoting mysql value */ - public function encode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'VARCHAR': - case 'TEXT': - if(!is_array($record[$key])) { - $record[$key] = $app->db->quote($record[$key]); - } else { - $record[$key] = implode($this->tableDef[$key]['separator'], $record[$key]); - } - break; - - case 'DATE': - if($record[$key] > 0) { - list($tag, $monat, $jahr) = explode('.', $record[$key]); - $record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $app->db->quote($record[$key]); - break; - - case 'CURRENCY': - $record[$key] = str_replace(',', '.', $record[$key]); - break; - } - } - } - return $record; - } - -} - -?> diff --git a/interface/lib/classes/searchform_actions.inc.php b/interface/lib/classes/searchform_actions.inc.php deleted file mode 100644 index c4372982c..000000000 --- a/interface/lib/classes/searchform_actions.inc.php +++ /dev/null @@ -1,202 +0,0 @@ -tpl)) $app->uses('tpl'); - if(!is_object($app->searchform)) $app->uses('searchform'); - if(!is_object($app->tform)) $app->uses('tform'); - - // Load list definition - $app->searchform->loadListDef($list_def_file); - - // Delete the search form contents, if requested - if($_REQUEST["empty_searchfields"] == 'yes') { - $list_name = $app->searchform->listDef["name"]; - unset($_SESSION["search"][$list_name]); - } - - // Save the search for later usage - if($_REQUEST["btn_submit_search_save"] && $_REQUEST["search_save_as"] != '') { - $app->searchform->saveSearchSettings($_REQUEST["search_save_as"]); - } - - // Set th returnto value for forms - $_SESSION["s"]["form"]["return_to_url"] = $app->searchform->listDef["file"]; - - if(!is_file('templates/'.$app->searchform->listDef["name"].'_search.htm')) { - $app->uses('searchform_tpl_generator'); - $app->searchform_tpl_generator->buildHTML($app->searchform->listDef); - } - - $app->tpl->newTemplate("searchpage.tpl.htm"); - $app->tpl->setInclude('content_tpl', 'templates/'.$app->searchform->listDef["name"].'_search.htm'); - - // Getting Datasets from DB - $records = $app->db->queryAllRecords($this->getQueryString()); - - - $this->DataRowColor = "#FFFFFF"; - if(is_array($records)) { - $this->idx_key = $app->searchform->listDef["table_idx"]; - foreach($records as $rec) { - $records_new[] = $this->prepareDataRow($rec); - } - } - - $app->tpl->setLoop('records', $records_new); - - //print_r($records_new); - - $this->onShow(); - - - } - - function prepareDataRow($rec) { - global $app; - - $rec = $app->searchform->decode($rec); - - // Alternating datarow colors - $this->DataRowColor = ($this->DataRowColor == "#FFFFFF")?"#EEEEEE":"#FFFFFF"; - $rec["bgcolor"] = $this->DataRowColor; - - // substitute value for select fields - foreach($app->searchform->listDef["item"] as $field) { - $key = $field["field"]; - if($field['formtype'] == "SELECT") { - if($rec[$key] == 'y' or $rec[$key] == 'n') { - // Set a additional image variable for bolean fields - $rec['_'.$key.'_'] = ($rec[$key] == 'y')?'list_icon_true.png':'list_icon_false.png'; - } - // substitute value for select field - $rec[$key] = $field['value'][$rec[$key]]; - } - } - - // The variable "id" contains always the index variable - $rec["id"] = $rec[$this->idx_key]; - - return $rec; - } - - function getQueryString() { - global $app; - - // Generate the search sql - if($app->searchform->listDef["auth"] != 'no') { - if($_SESSION["s"]["user"]["typ"] == "admin") { - $sql_where = ""; - } else { - $sql_where = $app->tform->getAuthSQL('r')." and"; - } - } - - if($this->SQLExtWhere != '') { - $sql_where .= " ".$this->SQLExtWhere." and"; - } - - $sql_where = $app->searchform->getSearchSQL($sql_where); - $app->tpl->setVar($app->searchform->searchValues); - - $order_by_sql = $this->SQLOrderBy; - - // Generate SQL for paging - $limit_sql = $app->searchform->getPagingSQL($sql_where); - $app->tpl->setVar("paging", $app->searchform->pagingHTML); - - return "SELECT * FROM ".$app->searchform->listDef["table"]." WHERE $sql_where $order_by_sql $limit_sql"; - - } - - - function onShow() { - global $app; - - // Language File setzen - $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_list.lng'; - if(!file_exists($lng_file)) $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/en_'.'_list.lng'; - include $lng_file; - $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$app->searchform->listDef['name']."_search.lng"; - if(!file_exists($lng_file)) $lng_file = 'lib/lang/en_'.$app->searchform->listDef['name']."_search.lng"; - include $lng_file; - $app->tpl->setVar($wb); - $app->tpl->setVar("form_action", $app->searchform->listDef["file"]); - - // Parse the templates and send output to the browser - $this->onShowEnd(); - } - - function onShowEnd() { - global $app; - - if(count($_REQUEST) > 0) { - $app->tpl->setVar('searchresult_visible', 1); - if($_REQUEST['searchresult_visible'] == 'no') $app->tpl->setVar('searchresult_visible', 0); - - if($_REQUEST['searchform_visible'] == 'yes') { - $app->tpl->setVar('searchform_visible', 1); - } else { - $app->tpl->setVar('searchform_visible', 0); - } - } else { - $app->tpl->setVar('searchform_visible', 1); - if($_REQUEST['searchform_visible'] == 'no') $app->tpl->setVar('searchform_visible', 0); - - if($_REQUEST['searchresult_visible'] == 'yes') { - $app->tpl->setVar('searchresult_visible', 1); - } else { - $app->tpl->setVar('searchresult_visible', 0); - } - } - - // make columns visible - $visible_columns = explode(",", $app->searchform->listDef['default_columns']); - foreach($visible_columns as $col) { - $app->tpl->setVar($col.'_visible', 1); - } - - $app->tpl_defaults(); - $app->tpl->pparse(); - } - -} - -?> diff --git a/interface/lib/classes/searchform_tpl_generator.inc.php b/interface/lib/classes/searchform_tpl_generator.inc.php deleted file mode 100644 index 81e2f4ef1..000000000 --- a/interface/lib/classes/searchform_tpl_generator.inc.php +++ /dev/null @@ -1,136 +0,0 @@ - -

- -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - - if($field["formtype"] == 'SELECT') { - $html .= " - - - - "; - } else { - $html .= " - - - - "; - } - } - - $html .= ' - - - -
:
:
-
- -

-[Neue Suche] -[Suchkriterien ändern] -Suche speichern unter: -

- - -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - $lang[$key."_txt"] = $key; - } - - $html .= ' - - - -'; - - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - } - - $html .= " - - -"; - $html .= ' -
 
{tmpl_var name=\"".$key."\"}[{tmpl_var name='delete_txt'}]
- - - -
-
-'; - - if($module == '') { - $filename = 'templates/'.$listDef["name"].'_search.htm'; - } else { - $filename = '../'.$module.'/templates/'.$listDef["name"].'_search.htm'; - } - - - // speichere Template - if (!$handle = fopen($filename, 'w')) { - print "Cannot open file ($filename)"; - exit; - } - - if (!fwrite($handle, $html)) { - print "Cannot write to file ($filename)"; - exit; - } - fclose($handle); - - } - -} - -?> -- GitLab From 058903a31762902af78aac37e9ac949bbe8ac546 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Thu, 22 Nov 2018 12:08:02 +0100 Subject: [PATCH 233/310] Apply stricter language filename check in admin language file editor. --- interface/web/admin/language_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/admin/language_edit.php b/interface/web/admin/language_edit.php index f17c4ae9a..39baec55e 100644 --- a/interface/web/admin/language_edit.php +++ b/interface/web/admin/language_edit.php @@ -49,7 +49,7 @@ $lang_file = $_REQUEST['lang_file']; if(!preg_match("/^[a-z]+$/i", $lang)) die('unallowed characters in language name.'); if(!preg_match("/^[a-z_]+$/i", $module)) die('unallowed characters in module name.'); -if(!preg_match("/^[a-z\._]+$/i", $lang_file)) die('unallowed characters in language file name.'); +if(!preg_match("/^[a-z\._]+$/i", $lang_file) || strpos($lang_file,'..') !== false || substr($lang_file,-4) != '.lng') die('unallowed characters in language file name.'); $msg = ''; -- GitLab From 35869ae98d425a50b5084c6077ecc7ee2b3c7ad8 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 23 Nov 2018 11:40:04 +0100 Subject: [PATCH 234/310] - remove searchform files (deprecated and unused code) --- interface/lib/classes/searchform.inc.php | 349 ------------------ .../lib/classes/searchform_actions.inc.php | 202 ---------- .../classes/searchform_tpl_generator.inc.php | 136 ------- 3 files changed, 687 deletions(-) delete mode 100644 interface/lib/classes/searchform.inc.php delete mode 100644 interface/lib/classes/searchform_actions.inc.php delete mode 100644 interface/lib/classes/searchform_tpl_generator.inc.php diff --git a/interface/lib/classes/searchform.inc.php b/interface/lib/classes/searchform.inc.php deleted file mode 100644 index 0a290c1d6..000000000 --- a/interface/lib/classes/searchform.inc.php +++ /dev/null @@ -1,349 +0,0 @@ -listDef = $liste; - $this->module = $module; - - //* Fill datasources - foreach($this->listDef['item'] as $key => $field) { - if(is_array($field['datasource'])) { - $this->listDef['item'][$key]['value'] = $this->getDatasourceData($field); - } - } - return true; - } - - /** - * Get the key => value array of a form filed from a datasource definitiom - * - * @param field = array with field definition - * @param record = Dataset as array - * @return key => value array for the value field of a form - */ - - - public function getDatasourceData($field) - { - global $app; - $values = array(); - - if($field['datasource']['type'] == 'SQL') { - //* Preparing SQL string. We will replace some common placeholders - $querystring = $field['datasource']['querystring']; - $querystring = str_replace('{USERID}', $_SESSION['s']['user']['userid'], $querystring); - $querystring = str_replace('{GROUPID}', $_SESSION['s']['user']['default_group'], $querystring); - $querystring = str_replace('{GROUPS}', $_SESSION['s']['user']['groups'], $querystring); - $table_idx = $this->formDef['db_table_idx']; - //$querystring = str_replace('{RECORDID}',$record[$table_idx],$querystring); - $app->uses('tform'); - $querystring = str_replace('{AUTHSQL}', $app->tform->getAuthSQL('r'), $querystring); - - //* Getting the records - $tmp_records = $app->db->queryAllRecords($querystring); - if($app->db->errorMessage != ''){ - die($app->db->errorMessage); - } - if(is_array($tmp_records)) { - $key_field = $field['datasource']['keyfield']; - $value_field = $field['datasource']['valuefield']; - foreach($tmp_records as $tmp_rec) { - $values[$tmp_rec[$key_field]] = $tmp_rec[$value_field]; - } - } - } - if($field['datasource']['type'] == 'CUSTOM') { - //* Calls a custom class to validate this record - if($field['datasource']['class'] != '' and $field['datasource']['function'] != '') { - $datasource_class = $field['datasource']['class']; - $datasource_function = $field['datasource']['function']; - $app->uses($datasource_class); - $record = array(); - $values = $app->$datasource_class->$datasource_function($field, $record); - }else{ - $this->errorMessage .= "Custom datasource class or function is empty
\r\n"; - } - } - return $values; - } - - public function getSearchSQL($sql_where = '') - { - global $db; - - //* Config vars - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - - //* store retrieval query - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - - //* TODO ? hat sich die suche ge�ndert - has itself search ? - $ki = $search_prefix.$field; - if(isset($_REQUEST) and $_REQUEST[$ki] != $_SESSION['search'][$list_name][$ki]){ - $this->searchChanged = 1; - } - - //* suchfield in session store. - if(isset($_REQUEST[$ki])){ - $_SESSION['search'][$list_name][$ki] = $_REQUEST[$ki]; - } - - if($i['formtype'] == 'SELECT'){ - if(is_array($i['value'])) { - $out = ''; - foreach($i['value'] as $k => $v) { - $selected = ($k == $_SESSION['search'][$list_name][$ki] && $_SESSION['search'][$list_name][$ki] != '') ? ' SELECTED' : ''; - $out .= "\r\n"; - } - } - $this->searchValues[$ki] = $out; - }else{ - $this->searchValues[$ki] = $_SESSION['search'][$list_name][$ki]; - } - } - - //* store variables in object. $this->searchValues = $_SESSION["search"][$list_name]; - foreach($this->listDef['item'] as $i) { - $field = $i['field']; - //if($_REQUEST[$search_prefix.$field] != '') $sql_where .= " $field ".$i["op"]." '".$i["prefix"].$_REQUEST[$search_prefix.$field].$i["suffix"]."' and"; - if($_SESSION['search'][$list_name][$ki] != ''){ - $sql_where .= " $field ".$i['op']." '".$i['prefix'].$_SESSION['search'][$list_name][$ki].$i['suffix']."' and"; - } - } - return ($sql_where != '') ? substr($sql_where, 0, -3) : '1'; - } - - public function getPagingSQL($sql_where = '1') { - global $app, $conf; - - $list_name = $this->listDef['name']; - $search_prefix = $this->listDef['search_prefix']; - $records_per_page = $this->listDef['records_per_page']; - $table = $this->listDef['table']; - - //* set page to seror id session not set - if($_SESSION['search'][$list_name]['page'] == '') $_SESSION['search'][$list_name]['page'] = 0; - - //* Set page size to request if set - if(isset($_REQUEST['page'])) $_SESSION['search'][$list_name]['page'] = $_REQUEST['page']; - - //* TODO PAGE to 0 set, if look for themselves ge?ndert. = page auf 0 setzen, wenn suche sich ge�ndert hat. - if($this->searchChanged == 1) $_SESSION['search'][$list_name]['page'] = 0; - - $sql_von = $_SESSION['search'][$list_name]['page'] * $records_per_page; - $record_count = $app->db->queryOneRecord("SELECT count(*) AS anzahl FROM ?? WHERE $sql_where", $table); - $pages = $app->functions->intval(($record_count['anzahl'] - 1) / $records_per_page); - - $vars['list_file'] = $this->listDef['file']; - $vars['page'] = $_SESSION['search'][$list_name]['page']; - $vars['last_page'] = $_SESSION['search'][$list_name]['page'] - 1; - $vars['next_page'] = $_SESSION['search'][$list_name]['page'] + 1; - $vars['pages'] = $pages; - $vars['max_pages'] = $pages + 1; - $vars['records_gesamt'] = $record_count['anzahl']; - $vars['page_params'] = $this->listDef['page_params']; - - if($_SESSION['search'][$list_name]['page'] > 0) $vars['show_page_back'] = 1; - if($_SESSION['search'][$list_name]['page'] <= $vars['pages'] - 1) $vars['show_page_next'] = 1; - - $this->pagingValues = $vars; - $this->pagingHTML = $this->getPagingHTML($vars); - - return "LIMIT $sql_von, $records_per_page"; - } - - public function getPagingHTML($vars) { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '   '; - if($vars['show_page_back'] == 1){ - $content .= ' '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '   '; - } else{ - $content .= ' '; - } - $content .= ' '; - return $content; - } - - public function getPagingHTMLasTXT($vars) - { - global $app; - $page_params = $vars['page_params']; - $list_file = $vars['list_file']; - $content = '[|<< ]'; - if($vars['show_page_back'] == 1){ - $content .= '[<< '.$app->lng('Back').'] '; - } - $content .= ' '.$app->lng('Page').' '.$vars['next_page'].' '.$app->lng('of').' '.$vars['max_pages'].' '; - if($vars['show_page_next'] == 1){ - $content .= '['.$app->lng('Next').' >>] '; - } - $content .= '[ >>|]'; - return $content; - } - - public function getSortSQL() - { - $sort_field = $this->listDef['sort_field']; - $sort_direction = $this->listDef['sort_direction']; - return ($sort_field != '' && $sort_direction != '') ? "ORDER BY $sort_field $sort_direction" : ''; - } - - public function saveSearchSettings($searchresult_name) - { - global $app, $conf; - - $list_name = $this->listDef['name']; - $settings = $_SESSION['search'][$list_name]; - unset($settings['page']); - $data = serialize($settings); - - $userid = $_SESSION['s']['user']['userid']; - $groupid = $_SESSION['s']['user']['default_group']; - $sys_perm_user = 'riud'; - $sys_perm_group = 'r'; - $sys_perm_other = ''; - $module = $_SESSION['s']['module']['name']; - $searchform = $this->listDef['name']; - $title = $searchresult_name; - - $sql = 'INSERT INTO `searchform` ( ' - .'`sys_userid` , `sys_groupid` , `sys_perm_user` , `sys_perm_group` , `sys_perm_other` , `module` , `searchform` , `title` , `data` ' - .')VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'; - $app->db->query($sql, $userid, $groupid, $sys_perm_user, $sys_perm_group, $sys_perm_other, $module, $searchform, $title, $data); - } - - public function decode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'DATE': - if($val > 0) { - $record[$key] = date($this->dateformat, $record[$key]); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $record[$key]; - break; - - case 'CURRENCY': - $record[$key] = number_format($record[$key], 2, ',', ''); - break; - - - case 'VARCHAR': - case 'TEXT': - default: - $record[$key] = stripslashes($record[$key]); - break; - } - } - } - return $record; - } - - /* TODO: check for double quoting mysql value */ - public function encode($record) - { - global $app; - if(is_array($record)) { - foreach($this->listDef['item'] as $field) { - $key = $field['field']; - switch ($field['datatype']) - { - case 'VARCHAR': - case 'TEXT': - if(!is_array($record[$key])) { - $record[$key] = $app->db->quote($record[$key]); - } else { - $record[$key] = implode($this->tableDef[$key]['separator'], $record[$key]); - } - break; - - case 'DATE': - if($record[$key] > 0) { - list($tag, $monat, $jahr) = explode('.', $record[$key]); - $record[$key] = mktime(0, 0, 0, $monat, $tag, $jahr); - } - break; - - case 'INTEGER': - $record[$key] = $app->functions->intval($record[$key]); - break; - - case 'DOUBLE': - $record[$key] = $app->db->quote($record[$key]); - break; - - case 'CURRENCY': - $record[$key] = str_replace(',', '.', $record[$key]); - break; - } - } - } - return $record; - } - -} - -?> diff --git a/interface/lib/classes/searchform_actions.inc.php b/interface/lib/classes/searchform_actions.inc.php deleted file mode 100644 index c4372982c..000000000 --- a/interface/lib/classes/searchform_actions.inc.php +++ /dev/null @@ -1,202 +0,0 @@ -tpl)) $app->uses('tpl'); - if(!is_object($app->searchform)) $app->uses('searchform'); - if(!is_object($app->tform)) $app->uses('tform'); - - // Load list definition - $app->searchform->loadListDef($list_def_file); - - // Delete the search form contents, if requested - if($_REQUEST["empty_searchfields"] == 'yes') { - $list_name = $app->searchform->listDef["name"]; - unset($_SESSION["search"][$list_name]); - } - - // Save the search for later usage - if($_REQUEST["btn_submit_search_save"] && $_REQUEST["search_save_as"] != '') { - $app->searchform->saveSearchSettings($_REQUEST["search_save_as"]); - } - - // Set th returnto value for forms - $_SESSION["s"]["form"]["return_to_url"] = $app->searchform->listDef["file"]; - - if(!is_file('templates/'.$app->searchform->listDef["name"].'_search.htm')) { - $app->uses('searchform_tpl_generator'); - $app->searchform_tpl_generator->buildHTML($app->searchform->listDef); - } - - $app->tpl->newTemplate("searchpage.tpl.htm"); - $app->tpl->setInclude('content_tpl', 'templates/'.$app->searchform->listDef["name"].'_search.htm'); - - // Getting Datasets from DB - $records = $app->db->queryAllRecords($this->getQueryString()); - - - $this->DataRowColor = "#FFFFFF"; - if(is_array($records)) { - $this->idx_key = $app->searchform->listDef["table_idx"]; - foreach($records as $rec) { - $records_new[] = $this->prepareDataRow($rec); - } - } - - $app->tpl->setLoop('records', $records_new); - - //print_r($records_new); - - $this->onShow(); - - - } - - function prepareDataRow($rec) { - global $app; - - $rec = $app->searchform->decode($rec); - - // Alternating datarow colors - $this->DataRowColor = ($this->DataRowColor == "#FFFFFF")?"#EEEEEE":"#FFFFFF"; - $rec["bgcolor"] = $this->DataRowColor; - - // substitute value for select fields - foreach($app->searchform->listDef["item"] as $field) { - $key = $field["field"]; - if($field['formtype'] == "SELECT") { - if($rec[$key] == 'y' or $rec[$key] == 'n') { - // Set a additional image variable for bolean fields - $rec['_'.$key.'_'] = ($rec[$key] == 'y')?'list_icon_true.png':'list_icon_false.png'; - } - // substitute value for select field - $rec[$key] = $field['value'][$rec[$key]]; - } - } - - // The variable "id" contains always the index variable - $rec["id"] = $rec[$this->idx_key]; - - return $rec; - } - - function getQueryString() { - global $app; - - // Generate the search sql - if($app->searchform->listDef["auth"] != 'no') { - if($_SESSION["s"]["user"]["typ"] == "admin") { - $sql_where = ""; - } else { - $sql_where = $app->tform->getAuthSQL('r')." and"; - } - } - - if($this->SQLExtWhere != '') { - $sql_where .= " ".$this->SQLExtWhere." and"; - } - - $sql_where = $app->searchform->getSearchSQL($sql_where); - $app->tpl->setVar($app->searchform->searchValues); - - $order_by_sql = $this->SQLOrderBy; - - // Generate SQL for paging - $limit_sql = $app->searchform->getPagingSQL($sql_where); - $app->tpl->setVar("paging", $app->searchform->pagingHTML); - - return "SELECT * FROM ".$app->searchform->listDef["table"]." WHERE $sql_where $order_by_sql $limit_sql"; - - } - - - function onShow() { - global $app; - - // Language File setzen - $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_list.lng'; - if(!file_exists($lng_file)) $lng_file = ISPC_WEB_PATH.'/lang/lib/lang/en_'.'_list.lng'; - include $lng_file; - $lng_file = "lib/lang/".$app->functions->check_language($_SESSION["s"]["language"])."_".$app->searchform->listDef['name']."_search.lng"; - if(!file_exists($lng_file)) $lng_file = 'lib/lang/en_'.$app->searchform->listDef['name']."_search.lng"; - include $lng_file; - $app->tpl->setVar($wb); - $app->tpl->setVar("form_action", $app->searchform->listDef["file"]); - - // Parse the templates and send output to the browser - $this->onShowEnd(); - } - - function onShowEnd() { - global $app; - - if(count($_REQUEST) > 0) { - $app->tpl->setVar('searchresult_visible', 1); - if($_REQUEST['searchresult_visible'] == 'no') $app->tpl->setVar('searchresult_visible', 0); - - if($_REQUEST['searchform_visible'] == 'yes') { - $app->tpl->setVar('searchform_visible', 1); - } else { - $app->tpl->setVar('searchform_visible', 0); - } - } else { - $app->tpl->setVar('searchform_visible', 1); - if($_REQUEST['searchform_visible'] == 'no') $app->tpl->setVar('searchform_visible', 0); - - if($_REQUEST['searchresult_visible'] == 'yes') { - $app->tpl->setVar('searchresult_visible', 1); - } else { - $app->tpl->setVar('searchresult_visible', 0); - } - } - - // make columns visible - $visible_columns = explode(",", $app->searchform->listDef['default_columns']); - foreach($visible_columns as $col) { - $app->tpl->setVar($col.'_visible', 1); - } - - $app->tpl_defaults(); - $app->tpl->pparse(); - } - -} - -?> diff --git a/interface/lib/classes/searchform_tpl_generator.inc.php b/interface/lib/classes/searchform_tpl_generator.inc.php deleted file mode 100644 index 81e2f4ef1..000000000 --- a/interface/lib/classes/searchform_tpl_generator.inc.php +++ /dev/null @@ -1,136 +0,0 @@ - -

- -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - - if($field["formtype"] == 'SELECT') { - $html .= " - - - - "; - } else { - $html .= " - - - - "; - } - } - - $html .= ' - - - -
:
:
-
- -

-[Neue Suche] -[Suchkriterien ändern] -Suche speichern unter: -

- - -'; - - $lang["list_head_txt"] = $listDef["name"]; - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - $lang[$key."_txt"] = $key; - } - - $html .= ' - - - -'; - - foreach($listDef["item"] as $field) { - $key = $field["field"]; - $html .= ""; - $html .= " \r\n"; - $html .= ""; - } - - $html .= " - - -"; - $html .= ' -
 
{tmpl_var name=\"".$key."\"}[{tmpl_var name='delete_txt'}]
- - - -
-
-'; - - if($module == '') { - $filename = 'templates/'.$listDef["name"].'_search.htm'; - } else { - $filename = '../'.$module.'/templates/'.$listDef["name"].'_search.htm'; - } - - - // speichere Template - if (!$handle = fopen($filename, 'w')) { - print "Cannot open file ($filename)"; - exit; - } - - if (!fwrite($handle, $html)) { - print "Cannot write to file ($filename)"; - exit; - } - fclose($handle); - - } - -} - -?> -- GitLab From b1d81817ed498d066dd5bddd74aed0cccb2f4af9 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 23 Nov 2018 11:58:02 +0100 Subject: [PATCH 235/310] - get rid of SoapFault dependency when using json/rest remoting endpoint --- interface/lib/classes/json_handler.inc.php | 10 +- interface/lib/classes/remote.d/admin.inc.php | 44 ++--- interface/lib/classes/remote.d/aps.inc.php | 52 +++--- interface/lib/classes/remote.d/client.inc.php | 78 ++++----- interface/lib/classes/remote.d/dns.inc.php | 120 ++++++------- .../lib/classes/remote.d/domains.inc.php | 8 +- interface/lib/classes/remote.d/mail.inc.php | 162 +++++++++--------- .../lib/classes/remote.d/monitor.inc.php | 2 +- interface/lib/classes/remote.d/server.inc.php | 26 +-- interface/lib/classes/remote.d/sites.inc.php | 128 +++++++------- interface/lib/classes/remoting.inc.php | 34 ++-- interface/lib/classes/remoting_lib.inc.php | 2 +- interface/lib/classes/rest_handler.inc.php | 10 +- interface/lib/classes/soap_handler.inc.php | 16 +- interface/lib/classes/validate_client.inc.php | 4 +- 15 files changed, 357 insertions(+), 339 deletions(-) diff --git a/interface/lib/classes/json_handler.inc.php b/interface/lib/classes/json_handler.inc.php index de8dd5ba0..edc57132b 100644 --- a/interface/lib/classes/json_handler.inc.php +++ b/interface/lib/classes/json_handler.inc.php @@ -115,11 +115,17 @@ class ISPConfigJSONHandler { try { $this->_return_json('ok', '', call_user_func_array(array($this->classes[$class_name], $method), $params)); - } catch(SoapFault $e) { + } catch(ISPConfigRemoteException $e) { $this->_return_json('remote_fault', $e->getMessage()); } } } -?> +if(!class_exists('ISPConfigRemoteException')) { + class ISPConfigRemoteException extends Exception { + public function __construct($code = '', $message = '') { + parent::__construct($message . ' (' . $code . ')', 0); + } + } +} \ No newline at end of file diff --git a/interface/lib/classes/remote.d/admin.inc.php b/interface/lib/classes/remote.d/admin.inc.php index 8b0c4730e..497f9a655 100644 --- a/interface/lib/classes/remote.d/admin.inc.php +++ b/interface/lib/classes/remote.d/admin.inc.php @@ -52,7 +52,7 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'admin_record_permissions')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -62,7 +62,7 @@ class remoting_admin extends remoting { // check if userid is valid $check = $app->db->queryOneRecord('SELECT userid FROM sys_user WHERE userid = ?', $app->functions->intval($value)); if(!$check || !$check['userid']) { - throw new SoapFault('invalid parameters', $value . ' is no valid sys_userid.'); + throw new ISPConfigRemoteException('invalid parameters', $value . ' is no valid sys_userid.'); return false; } $permissions[$key] = $app->functions->intval($value); @@ -71,7 +71,7 @@ class remoting_admin extends remoting { // check if groupid is valid $check = $app->db->queryOneRecord('SELECT groupid FROM sys_group WHERE groupid = ?', $app->functions->intval($value)); if(!$check || !$check['groupid']) { - throw new SoapFault('invalid parameters', $value . ' is no valid sys_groupid.'); + throw new ISPConfigRemoteException('invalid parameters', $value . ' is no valid sys_groupid.'); return false; } $permissions[$key] = $app->functions->intval($value); @@ -81,7 +81,7 @@ class remoting_admin extends remoting { // check if permissions are valid $value = strtolower($value); if(!preg_match('/^[riud]+$/', $value)) { - throw new SoapFault('invalid parameters', $value . ' is no valid permission string.'); + throw new ISPConfigRemoteException('invalid parameters', $value . ' is no valid permission string.'); return false; } @@ -95,7 +95,7 @@ class remoting_admin extends remoting { break; default: - throw new SoapFault('invalid parameters', 'Only sys_userid, sys_groupid, sys_perm_user and sys_perm_group parameters can be changed with this function.'); + throw new ISPConfigRemoteException('invalid parameters', 'Only sys_userid, sys_groupid, sys_perm_user and sys_perm_group parameters can be changed with this function.'); break; } } @@ -113,7 +113,7 @@ class remoting_admin extends remoting { public function system_config_set($session_id, $section, $key, $value) { global $app; if(!$this->checkPerm($session_id, 'system_config_set')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if ($section != '' && $key != '') { @@ -123,7 +123,7 @@ class remoting_admin extends remoting { $system_config_str = $app->ini_parser->get_ini_string($system_config_array); return $app->db->datalogUpdate('sys_ini', array("config" => $system_config_str), 'sysini_id', 1); } else { - throw new SoapFault('invalid_function_parameter', 'Invalid function parameter.'); + throw new ISPConfigRemoteException('invalid_function_parameter', 'Invalid function parameter.'); return false; } } @@ -138,7 +138,7 @@ class remoting_admin extends remoting { public function system_config_get($session_id, $section, $key) { global $app; if(!$this->checkPerm($session_id, 'system_config_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if ($section != '') { @@ -152,7 +152,7 @@ class remoting_admin extends remoting { else return false; } } else { - throw new SoapFault('invalid_function_parameter', 'Invalid function parameter.'); + throw new ISPConfigRemoteException('invalid_function_parameter', 'Invalid function parameter.'); return false; } } @@ -165,13 +165,13 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'config_value_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } // validate fields if($group == '' || $name == '') { - throw new SoapFault('field_empty_error', 'Group and name parameter may not be empty.'); + throw new ISPConfigRemoteException('field_empty_error', 'Group and name parameter may not be empty.'); return false; } @@ -184,18 +184,18 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'config_value_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } // validate fields if($group == '' || $name == '' || $value == '') { - throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + throw new ISPConfigRemoteException('field_empty_error', 'Group, name, and value parameter may not be empty.'); return false; } if(is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { - throw new SoapFault('record_unique_error', 'Group plus name field combination is not unique.'); + throw new ISPConfigRemoteException('record_unique_error', 'Group plus name field combination is not unique.'); return false; } @@ -208,18 +208,18 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'config_value_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } // validate fields if($group == '' || $name == '' || $value == '') { - throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + throw new ISPConfigRemoteException('field_empty_error', 'Group, name, and value parameter may not be empty.'); return false; } if(!is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { - throw new SoapFault('record_nonexist_error', 'There is no record with this group plus name field combination.'); + throw new ISPConfigRemoteException('record_nonexist_error', 'There is no record with this group plus name field combination.'); return false; } @@ -232,13 +232,13 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'config_value_replace')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } // validate fields if($group == '' || $name == '' || $value == '') { - throw new SoapFault('field_empty_error', 'Group, name, and value parameter may not be empty.'); + throw new ISPConfigRemoteException('field_empty_error', 'Group, name, and value parameter may not be empty.'); return false; } @@ -255,18 +255,18 @@ class remoting_admin extends remoting { global $app; if(!$this->checkPerm($session_id, 'config_value_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } // validate fields if($group == '' || $name == '') { - throw new SoapFault('field_empty_error', 'Group and name parameter may not be empty.'); + throw new ISPConfigRemoteException('field_empty_error', 'Group and name parameter may not be empty.'); return false; } if(!is_array($app->db->queryOneRecord('SELECT * FROM sys_config WHERE `group` = ? AND `name` = ?', $group, $name))) { - throw new SoapFault('record_nonexist_error', 'There is no record with this group plus name field combination.'); + throw new ISPConfigRemoteException('record_nonexist_error', 'There is no record with this group plus name field combination.'); return false; } diff --git a/interface/lib/classes/remote.d/aps.inc.php b/interface/lib/classes/remote.d/aps.inc.php index 50dda4825..2e1770be4 100644 --- a/interface/lib/classes/remote.d/aps.inc.php +++ b/interface/lib/classes/remote.d/aps.inc.php @@ -40,7 +40,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_update_package_list')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -60,7 +60,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_available_packages_list')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -82,7 +82,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_get_package_details')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -98,14 +98,14 @@ class remoting_aps extends remoting { // Make sure an integer ID is given if (!isset($primary_id) || !$gui->isValidPackageID($primary_id, true)) {// always adminflag - throw new SoapFault('package_error', 'The given Package ID is not valid.'); + throw new ISPConfigRemoteException('package_error', 'The given Package ID is not valid.'); return false; } // Get package details $details = $gui->getPackageDetails($primary_id); if (isset($details['error'])) { - throw new SoapFault('package_error', $details['error']); + throw new ISPConfigRemoteException('package_error', $details['error']); return false; } @@ -121,7 +121,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_get_package_file')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -137,14 +137,14 @@ class remoting_aps extends remoting { // Make sure an integer ID is given if (!isset($primary_id) || !$gui->isValidPackageID($primary_id, true)) {// always adminflag - throw new SoapFault('package_error', 'The given Package ID is not valid.'); + throw new ISPConfigRemoteException('package_error', 'The given Package ID is not valid.'); return false; } // Get package details $details = $gui->getPackageDetails($primary_id); if (isset($details['error'])) { - throw new SoapFault('package_error', $details['error']); + throw new ISPConfigRemoteException('package_error', $details['error']); return false; } @@ -155,7 +155,7 @@ class remoting_aps extends remoting { foreach ($details['Screenshots'] as $screen) { if (basename($screen['ScreenPath']) == $filename) { $found = true; break; } } if (!$found) { - throw new SoapFault('package_error', 'File not found in package.'); + throw new ISPConfigRemoteException('package_error', 'File not found in package.'); return false; } @@ -167,7 +167,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_get_package_details')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -183,14 +183,14 @@ class remoting_aps extends remoting { // Make sure an integer ID is given if (!isset($primary_id) || !$gui->isValidPackageID($primary_id, true)) {// always adminflag - throw new SoapFault('package_error', 'The given Package ID is not valid.'); + throw new ISPConfigRemoteException('package_error', 'The given Package ID is not valid.'); return false; } // Get package settings $settings = $gui->getPackageSettings($primary_id); if (isset($settings['error'])) { - throw new SoapFault('package_error', $settings['error']); + throw new ISPConfigRemoteException('package_error', $settings['error']); return false; } @@ -205,7 +205,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_change_package_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -215,12 +215,12 @@ class remoting_aps extends remoting { // Make sure an integer ID is given if (!isset($primary_id) || !$gui->isValidPackageID($primary_id, true)) {// always adminflag - throw new SoapFault('package_error', 'The given Package ID is not valid.'); + throw new ISPConfigRemoteException('package_error', 'The given Package ID is not valid.'); return false; } if(!isset($params['package_status']) || (($params['package_status'] != PACKAGE_ENABLED) && ($params['package_status'] != PACKAGE_LOCKED))) { - throw new SoapFault('package_error', 'Wrong new status: '.$params['package_status']); + throw new ISPConfigRemoteException('package_error', 'Wrong new status: '.$params['package_status']); return false; } @@ -235,7 +235,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_install_package')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -251,25 +251,25 @@ class remoting_aps extends remoting { // Make sure an integer ID is given if (!isset($primary_id) || !$gui->isValidPackageID($primary_id, true)) {// always adminflag - throw new SoapFault('package_error', 'The given Package ID is not valid.'); + throw new ISPConfigRemoteException('package_error', 'The given Package ID is not valid.'); return false; } // Get package details $details = $gui->getPackageDetails($primary_id); if (isset($details['error'])) { - throw new SoapFault('package_error', $details['error']); + throw new ISPConfigRemoteException('package_error', $details['error']); return false; } $settings = $gui->getPackageSettings($primary_id); if (isset($settings['error'])) { - throw new SoapFault('package_error', $settings['error']); + throw new ISPConfigRemoteException('package_error', $settings['error']); return false; } // Check given Site/VHostDomain if (!isset($params['main_domain'])) { - throw new SoapFault('invalid parameters', 'No valid domain given.'); + throw new ISPConfigRemoteException('invalid parameters', 'No valid domain given.'); return false; } @@ -284,7 +284,7 @@ class remoting_aps extends remoting { } if (!$domain) { - throw new SoapFault('invalid parameters', 'No valid domain given.'); + throw new ISPConfigRemoteException('invalid parameters', 'No valid domain given.'); return false; } @@ -295,7 +295,7 @@ class remoting_aps extends remoting { return $gui->createPackageInstance($result['input'], $primary_id); } - throw new SoapFault('invalid parameters', implode('
', $result['error'])); + throw new ISPConfigRemoteException('invalid parameters', implode('
', $result['error'])); return false; } @@ -304,7 +304,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_instance_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -318,7 +318,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_instance_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -332,7 +332,7 @@ class remoting_aps extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_aps_instance_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -344,7 +344,7 @@ class remoting_aps extends remoting { $result = $app->db->queryOneRecord($sql, $primary_id); if (!$result) { - throw new SoapFault('instance_error', 'No valid instance id given.'); + throw new ISPConfigRemoteException('instance_error', 'No valid instance id given.'); return false; } diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php index 92adb9af5..2d068a137 100644 --- a/interface/lib/classes/remote.d/client.inc.php +++ b/interface/lib/classes/remote.d/client.inc.php @@ -53,7 +53,7 @@ class remoting_client extends remoting { global $app; if(!$this->checkPerm($session_id, 'client_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -98,7 +98,7 @@ class remoting_client extends remoting { { global $app; if(!$this->checkPerm($session_id, 'client_get_id')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -108,7 +108,7 @@ class remoting_client extends remoting { if(isset($rec['client_id'])) { return $app->functions->intval($rec['client_id']); } else { - throw new SoapFault('no_client_found', 'There is no sysuser account for this client ID.'); + throw new ISPConfigRemoteException('no_client_found', 'There is no sysuser account for this client ID.'); return false; } @@ -119,7 +119,7 @@ class remoting_client extends remoting { global $app; if(!$this->checkPerm($session_id, 'client_get_emailcontact')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -130,7 +130,7 @@ class remoting_client extends remoting { if(is_array($rec)) { return $rec; } else { - throw new SoapFault('no_client_found', 'There is no client with this client ID.'); + throw new ISPConfigRemoteException('no_client_found', 'There is no client with this client ID.'); return false; } } @@ -139,7 +139,7 @@ class remoting_client extends remoting { { global $app; if(!$this->checkPerm($session_id, 'client_get_id')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -149,7 +149,7 @@ class remoting_client extends remoting { if(isset($rec['groupid'])) { return $app->functions->intval($rec['groupid']); } else { - throw new SoapFault('no_group_found', 'There is no group for this client ID.'); + throw new ISPConfigRemoteException('no_group_found', 'There is no group for this client ID.'); return false; } @@ -162,7 +162,7 @@ class remoting_client extends remoting { if (!$this->checkPerm($session_id, 'client_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if(!isset($params['parent_client_id']) || $params['parent_client_id'] == 0) $params['parent_client_id'] = $reseller_id; @@ -174,7 +174,7 @@ class remoting_client extends remoting { // Selected client is not a reseller. REMOVING PARENT_CLIENT_ID!!! $params['parent_client_id'] = 0; } elseif(isset($params['limit_client']) && $params['limit_client'] != 0) { - throw new SoapFault('Invalid reseller', 'Reseller cannot be client of another reseller.'); + throw new ISPConfigRemoteException('Invalid reseller', 'Reseller cannot be client of another reseller.'); return false; } } @@ -191,7 +191,7 @@ class remoting_client extends remoting { if (!$this->checkPerm($session_id, 'client_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -208,12 +208,12 @@ class remoting_client extends remoting { // check if this one is reseller $check = $app->db->queryOneRecord('SELECT `limit_client` FROM `client` WHERE `client_id` = ?', intval($params['parent_client_id'])); if($check['limit_client'] == 0) { - throw new SoapFault('Invalid reseller', 'Selected client is not a reseller.'); + throw new ISPConfigRemoteException('Invalid reseller', 'Selected client is not a reseller.'); return false; } if(isset($params['limit_client']) && $params['limit_client'] != 0) { - throw new SoapFault('Invalid reseller', 'Reseller cannot be client of another reseller.'); + throw new ISPConfigRemoteException('Invalid reseller', 'Reseller cannot be client of another reseller.'); return false; } } @@ -251,7 +251,7 @@ class remoting_client extends remoting { global $app; if(!$this->checkPerm($session_id, 'client_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -259,7 +259,7 @@ class remoting_client extends remoting { $sql = "SELECT * FROM `client_template_assigned` WHERE `client_id` = ?"; return $app->db->queryOneRecord($sql, $client_id); } else { - throw new SoapFault('The ID must be an integer.'); + throw new ISPConfigRemoteException('The ID must be an integer.'); return array(); } } @@ -289,7 +289,7 @@ class remoting_client extends remoting { global $app; if(!$this->checkPerm($session_id, 'client_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -297,13 +297,13 @@ class remoting_client extends remoting { // check if client exists $check = $app->db->queryOneRecord('SELECT `client_id` FROM `client` WHERE `client_id` = ?', $client_id); if(!$check) { - throw new SoapFault('Invalid client'); + throw new ISPConfigRemoteException('Invalid client'); return false; } // check if template exists $check = $app->db->queryOneRecord('SELECT `template_id` FROM `client_template` WHERE `template_id` = ?', $template_id); if(!$check) { - throw new SoapFault('Invalid template'); + throw new ISPConfigRemoteException('Invalid template'); return false; } @@ -318,7 +318,7 @@ class remoting_client extends remoting { return $insert_id; } else { - throw new SoapFault('The IDs must be of type integer.'); + throw new ISPConfigRemoteException('The IDs must be of type integer.'); return false; } } @@ -327,7 +327,7 @@ class remoting_client extends remoting { global $app; if(!$this->checkPerm($session_id, 'client_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -335,13 +335,13 @@ class remoting_client extends remoting { // check if client exists $check = $app->db->queryOneRecord('SELECT `client_id` FROM `client` WHERE `client_id` = ?', $client_id); if(!$check) { - throw new SoapFault('Invalid client'); + throw new ISPConfigRemoteException('Invalid client'); return false; } // check if template exists $check = $app->db->queryOneRecord('SELECT `assigned_template_id` FROM `client_template_assigned` WHERE `client_id` = ? AND `client_template_id` = ?', $client_id, $assigned_template_id); if(!$check) { - throw new SoapFault('Invalid template'); + throw new ISPConfigRemoteException('Invalid template'); return false; } @@ -356,7 +356,7 @@ class remoting_client extends remoting { return $affected_rows; } else { - throw new SoapFault('The IDs must be of type integer.'); + throw new ISPConfigRemoteException('The IDs must be of type integer.'); return false; } } @@ -367,7 +367,7 @@ class remoting_client extends remoting { if (!$this->checkPerm($session_id, 'client_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../client/form/client.tform.php', $client_id); @@ -384,7 +384,7 @@ class remoting_client extends remoting { global $app, $conf; if(!$this->checkPerm($session_id, 'client_delete_everything')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -440,7 +440,7 @@ class remoting_client extends remoting { } if (!$this->checkPerm($session_id, 'client_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../client/form/client.tform.php', $client_id); @@ -460,14 +460,14 @@ class remoting_client extends remoting { public function client_get_by_username($session_id, $username) { global $app; if(!$this->checkPerm($session_id, 'client_get_by_username')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $rec = $app->db->queryOneRecord("SELECT * FROM sys_user WHERE username = ?", $username); if (isset($rec)) { return $rec; } else { - throw new SoapFault('no_client_found', 'There is no user account for this user name.'); + throw new ISPConfigRemoteException('no_client_found', 'There is no user account for this user name.'); return false; } } @@ -475,12 +475,12 @@ class remoting_client extends remoting { public function client_get_by_customer_no($session_id, $customer_no) { global $app; if(!$this->checkPerm($session_id, 'client_get_by_customer_no')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $customer_no = trim($customer_no); if($customer_no == '') { - throw new SoapFault('permission_denied', 'There was no customer number specified.'); + throw new ISPConfigRemoteException('permission_denied', 'There was no customer number specified.'); return false; } $customer_no = $app->db->quote($customer_no); @@ -488,7 +488,7 @@ class remoting_client extends remoting { if (isset($rec)) { return $rec; } else { - throw new SoapFault('no_client_found', 'There is no user account for this customer number.'); + throw new ISPConfigRemoteException('no_client_found', 'There is no user account for this customer number.'); return false; } } @@ -501,7 +501,7 @@ class remoting_client extends remoting { public function client_get_all($session_id) { global $app; if(!$this->checkPerm($session_id, 'client_get_all')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $result = $app->db->queryAllRecords("SELECT client_id FROM client WHERE 1"); @@ -529,7 +529,7 @@ class remoting_client extends remoting { $app->uses('auth'); if(!$this->checkPerm($session_id, 'client_change_password')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -542,7 +542,7 @@ class remoting_client extends remoting { $app->db->query($sql, $new_password, $client_id); return true; } else { - throw new SoapFault('no_client_found', 'There is no user account for this client_id'); + throw new ISPConfigRemoteException('no_client_found', 'There is no user account for this client_id'); return false; } } @@ -555,7 +555,7 @@ class remoting_client extends remoting { public function client_templates_get_all($session_id) { global $app; if(!$this->checkPerm($session_id, 'client_templates_get_all')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $sql = "SELECT * FROM client_template"; @@ -568,17 +568,17 @@ class remoting_client extends remoting { //* Check permissions if(!$this->checkPerm($session_id, 'client_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } //* Check username and password if(!preg_match("/^[\w\.\-\_\@]{1,128}$/", $username)) { - throw new SoapFault('user_regex_error', 'Username contains invalid characters.'); + throw new ISPConfigRemoteException('user_regex_error', 'Username contains invalid characters.'); return false; } if(!preg_match("/^.{1,64}$/i", $password)) { - throw new SoapFault('password_length_error', 'Invalid password length or no password provided.'); + throw new ISPConfigRemoteException('password_length_error', 'Invalid password length or no password provided.'); return false; } @@ -588,7 +588,7 @@ class remoting_client extends remoting { //* too many failedlogins if($alreadyfailed['times'] > 5) { - throw new SoapFault('error_user_too_many_logins', 'Too many failed logins.'); + throw new ISPConfigRemoteException('error_user_too_many_logins', 'Too many failed logins.'); return false; } @@ -659,7 +659,7 @@ class remoting_client extends remoting { 'language' => $user['language'], 'country' => 'de'); } else { - throw new SoapFault('login_failed', 'Login failed.'); + throw new ISPConfigRemoteException('login_failed', 'Login failed.'); } } diff --git a/interface/lib/classes/remote.d/dns.inc.php b/interface/lib/classes/remote.d/dns.inc.php index f7b0d1397..4bd518ed1 100644 --- a/interface/lib/classes/remote.d/dns.inc.php +++ b/interface/lib/classes/remote.d/dns.inc.php @@ -46,7 +46,7 @@ class remoting_dns extends remoting { { global $app, $conf; if(!$this->checkPerm($session_id, 'dns_templatezone_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -180,7 +180,7 @@ class remoting_dns extends remoting { return $dns_soa_id; exit; } else { - throw new SoapFault('permission_denied', $error); + throw new ISPConfigRemoteException('permission_denied', $error); } } @@ -191,7 +191,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -203,7 +203,7 @@ class remoting_dns extends remoting { public function dns_slave_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../dns/form/dns_slave.tform.php', $client_id, $params); @@ -213,7 +213,7 @@ class remoting_dns extends remoting { public function dns_slave_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../dns/form/dns_slave.tform.php', $client_id, $primary_id, $params); @@ -224,7 +224,7 @@ class remoting_dns extends remoting { public function dns_slave_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'dns_zone_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->deleteQuery('../dns/form/dns_slave.tform.php', $primary_id); @@ -236,12 +236,12 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get_id')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if(!preg_match('/^([a-z0-9][a-z0-9\-]+[a-z0-9]|[a-z0-9]{2})(\.[a-z]{2,63})+$/i', $origin)){ - throw new SoapFault('no_domain_found', 'Invalid domain name.'); + throw new ISPConfigRemoteException('no_domain_found', 'Invalid domain name.'); return false; } @@ -249,7 +249,7 @@ class remoting_dns extends remoting { if(isset($rec['id'])) { return $app->functions->intval($rec['id']); } else { - throw new SoapFault('no_domain_found', 'There is no domain ID with informed domain name.'); + throw new ISPConfigRemoteException('no_domain_found', 'There is no domain ID with informed domain name.'); return false; } } @@ -258,7 +258,7 @@ class remoting_dns extends remoting { public function dns_zone_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../dns/form/dns_soa.tform.php', $client_id, $params); @@ -268,7 +268,7 @@ class remoting_dns extends remoting { public function dns_zone_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../dns/form/dns_soa.tform.php', $client_id, $primary_id, $params); @@ -279,7 +279,7 @@ class remoting_dns extends remoting { public function dns_zone_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'dns_zone_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_soa.tform.php', $primary_id); @@ -294,7 +294,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_aaaa_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -306,7 +306,7 @@ class remoting_dns extends remoting { public function dns_aaaa_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_aaaa_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -317,7 +317,7 @@ class remoting_dns extends remoting { public function dns_aaaa_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_aaaa_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../dns/form/dns_aaaa.tform.php', $client_id, $primary_id, $params); @@ -329,7 +329,7 @@ class remoting_dns extends remoting { public function dns_aaaa_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_aaaa_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_aaaa.tform.php', $primary_id); @@ -345,7 +345,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_a_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -357,7 +357,7 @@ class remoting_dns extends remoting { public function dns_a_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_a_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -368,7 +368,7 @@ class remoting_dns extends remoting { public function dns_a_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_a_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -380,7 +380,7 @@ class remoting_dns extends remoting { public function dns_a_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_a_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_a.tform.php', $primary_id); @@ -396,7 +396,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_alias_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -408,7 +408,7 @@ class remoting_dns extends remoting { public function dns_alias_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_alias_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -419,7 +419,7 @@ class remoting_dns extends remoting { public function dns_alias_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_alias_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -431,7 +431,7 @@ class remoting_dns extends remoting { public function dns_alias_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_alias_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_alias.tform.php', $primary_id); @@ -447,7 +447,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_cname_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -459,7 +459,7 @@ class remoting_dns extends remoting { public function dns_cname_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_cname_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -470,7 +470,7 @@ class remoting_dns extends remoting { public function dns_cname_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_cname_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -482,7 +482,7 @@ class remoting_dns extends remoting { public function dns_cname_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_cname_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_cname.tform.php', $primary_id); @@ -498,7 +498,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_hinfo_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -510,7 +510,7 @@ class remoting_dns extends remoting { public function dns_hinfo_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_hinfo_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -521,7 +521,7 @@ class remoting_dns extends remoting { public function dns_hinfo_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_hinfo_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -533,7 +533,7 @@ class remoting_dns extends remoting { public function dns_hinfo_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_hinfo_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_hinfo.tform.php', $primary_id); @@ -549,7 +549,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_mx_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -561,7 +561,7 @@ class remoting_dns extends remoting { public function dns_mx_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_mx_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -572,7 +572,7 @@ class remoting_dns extends remoting { public function dns_mx_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_mx_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -584,7 +584,7 @@ class remoting_dns extends remoting { public function dns_mx_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_mx_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_mx.tform.php', $primary_id); @@ -600,7 +600,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_ns_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -612,7 +612,7 @@ class remoting_dns extends remoting { public function dns_ns_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ns_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -623,7 +623,7 @@ class remoting_dns extends remoting { public function dns_ns_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ns_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -635,7 +635,7 @@ class remoting_dns extends remoting { public function dns_ns_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ns_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_ns.tform.php', $primary_id); @@ -651,7 +651,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_ptr_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -663,7 +663,7 @@ class remoting_dns extends remoting { public function dns_ptr_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ptr_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -674,7 +674,7 @@ class remoting_dns extends remoting { public function dns_ptr_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ptr_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -686,7 +686,7 @@ class remoting_dns extends remoting { public function dns_ptr_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_ptr_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_ptr.tform.php', $primary_id); @@ -702,7 +702,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_rp_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -714,7 +714,7 @@ class remoting_dns extends remoting { public function dns_rp_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_rp_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -725,7 +725,7 @@ class remoting_dns extends remoting { public function dns_rp_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_rp_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -737,7 +737,7 @@ class remoting_dns extends remoting { public function dns_rp_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_rp_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_rp.tform.php', $primary_id); @@ -753,7 +753,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_srv_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -765,7 +765,7 @@ class remoting_dns extends remoting { public function dns_srv_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_srv_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -776,7 +776,7 @@ class remoting_dns extends remoting { public function dns_srv_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_srv_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -788,7 +788,7 @@ class remoting_dns extends remoting { public function dns_srv_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_srv_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_srv.tform.php', $primary_id); @@ -804,7 +804,7 @@ class remoting_dns extends remoting { global $app; if(!$this->checkPerm($session_id, 'dns_txt_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -816,7 +816,7 @@ class remoting_dns extends remoting { public function dns_txt_add($session_id, $client_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_txt_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -827,7 +827,7 @@ class remoting_dns extends remoting { public function dns_txt_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_txt_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if($update_serial) $this->increase_serial($session_id, $client_id, $params); @@ -839,7 +839,7 @@ class remoting_dns extends remoting { public function dns_txt_delete($session_id, $primary_id, $update_serial=false) { if(!$this->checkPerm($session_id, 'dns_txt_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../dns/form/dns_txt.tform.php', $primary_id); @@ -856,7 +856,7 @@ class remoting_dns extends remoting { public function dns_zone_get_by_user($session_id, $client_id, $server_id) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($client_id) && !empty($server_id)) { @@ -880,7 +880,7 @@ class remoting_dns extends remoting { public function dns_rr_get_all_by_zone($session_id, $zone_id) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $sql = "SELECT * FROM dns_rr WHERE zone = ?"; @@ -898,7 +898,7 @@ class remoting_dns extends remoting { public function dns_zone_set_status($session_id, $primary_id, $status) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_set_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if(in_array($status, array('active', 'inactive'))) { @@ -912,7 +912,7 @@ class remoting_dns extends remoting { $result = $app->db->affectedRows(); return $result; } else { - throw new SoapFault('status_undefined', 'The status is not available'); + throw new ISPConfigRemoteException('status_undefined', 'The status is not available'); return false; } } diff --git a/interface/lib/classes/remote.d/domains.inc.php b/interface/lib/classes/remote.d/domains.inc.php index 33830335d..5bc70cf4a 100644 --- a/interface/lib/classes/remote.d/domains.inc.php +++ b/interface/lib/classes/remote.d/domains.inc.php @@ -47,7 +47,7 @@ class remoting_domains extends remoting { global $app; if(!$this->checkPerm($session_id, 'domains_domain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -59,7 +59,7 @@ class remoting_domains extends remoting { public function domains_domain_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'domains_domain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../client/form/domain.tform.php', $client_id, $params); @@ -69,7 +69,7 @@ class remoting_domains extends remoting { public function domains_domain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'domains_domain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../client/form/domain.tform.php', $primary_id); @@ -82,7 +82,7 @@ class remoting_domains extends remoting { { global $app; if(!$this->checkPerm($session_id, 'domains_get_all_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $group_id = $app->functions->intval($group_id); diff --git a/interface/lib/classes/remote.d/mail.inc.php b/interface/lib/classes/remote.d/mail.inc.php index 955c85d7a..decd45a7c 100644 --- a/interface/lib/classes/remote.d/mail.inc.php +++ b/interface/lib/classes/remote.d/mail.inc.php @@ -45,7 +45,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_domain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -57,7 +57,7 @@ class remoting_mail extends remoting { public function mail_domain_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'mail_domain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $primary_id = $this->insertQuery('../mail/form/mail_domain.tform.php', $client_id, $params); @@ -68,7 +68,7 @@ class remoting_mail extends remoting { public function mail_domain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'mail_domain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_domain.tform.php', $client_id, $primary_id, $params); @@ -79,7 +79,7 @@ class remoting_mail extends remoting { public function mail_domain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'mail_domain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_domain.tform.php', $primary_id); @@ -92,7 +92,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_aliasdomain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -105,7 +105,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_aliasdomain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_aliasdomain.tform.php', $client_id, $params); @@ -117,7 +117,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_aliasdomain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_aliasdomain.tform.php', $client_id, $primary_id, $params); @@ -128,7 +128,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_aliasdomain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_aliasdomain.tform.php', $primary_id); @@ -141,7 +141,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -155,7 +155,7 @@ class remoting_mail extends remoting { global $app; if (!$this->checkPerm($session_id, 'mail_user_add')){ - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -163,7 +163,7 @@ class remoting_mail extends remoting { $email_parts = explode('@', $params['email']); $tmp = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain = ?", $email_parts[1]); if($tmp['domain'] != $email_parts[1]) { - throw new SoapFault('mail_domain_does_not_exist', 'Mail domain - '.$email_parts[1].' - does not exist.'); + throw new ISPConfigRemoteException('mail_domain_does_not_exist', 'Mail domain - '.$email_parts[1].' - does not exist.'); return false; } @@ -183,7 +183,7 @@ class remoting_mail extends remoting { if (!$this->checkPerm($session_id, 'mail_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -191,7 +191,7 @@ class remoting_mail extends remoting { $email_parts = explode('@', $params['email']); $tmp = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain = ?", $email_parts[1]); if($tmp['domain'] != $email_parts[1]) { - throw new SoapFault('mail_domain_does_not_exist', 'Mail domain - '.$email_parts[1].' - does not exist.'); + throw new ISPConfigRemoteException('mail_domain_does_not_exist', 'Mail domain - '.$email_parts[1].' - does not exist.'); return false; } @@ -205,7 +205,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_user.tform.php', $primary_id); @@ -218,7 +218,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_user_filter_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -230,7 +230,7 @@ class remoting_mail extends remoting { { global $app; if (!$this->checkPerm($session_id, 'mail_user_filter_add')){ - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_user_filter.tform.php', $client_id, $params, 'mail:mail_user_filter:on_after_insert'); @@ -243,7 +243,7 @@ class remoting_mail extends remoting { global $app; if (!$this->checkPerm($session_id, 'mail_user_filter_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_user_filter.tform.php', $client_id, $primary_id, $params, 'mail:mail_user_filter:on_after_update'); @@ -256,7 +256,7 @@ class remoting_mail extends remoting { global $app; if (!$this->checkPerm($session_id, 'mail_user_filter_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_user_filter.tform.php', $primary_id, 'mail:mail_user_filter:on_after_delete'); @@ -270,7 +270,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_user_backup')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -293,7 +293,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_user_backup')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -307,19 +307,19 @@ class remoting_mail extends remoting { //* Basic validation of variables if ($server_id <= 0) { - throw new SoapFault('invalid_backup_id', "Invalid or non existant backup_id $primary_id"); + throw new ISPConfigRemoteException('invalid_backup_id', "Invalid or non existant backup_id $primary_id"); return false; } if (/*$action_type != 'backup_download_mail' and*/ $action_type != 'backup_restore_mail' and $action_type != 'backup_delete_mail') { - throw new SoapFault('invalid_action', "Invalid action_type $action_type"); + throw new ISPConfigRemoteException('invalid_action', "Invalid action_type $action_type"); return false; } //* Validate instance $instance_record = $app->db->queryOneRecord("SELECT * FROM `sys_remoteaction` WHERE `action_param`=? and `action_type`=? and `action_state`='pending'", $primary_id, $action_type); if ($instance_record['action_id'] >= 1) { - throw new SoapFault('duplicate_action', "There is already a pending $action_type action"); + throw new ISPConfigRemoteException('duplicate_action', "There is already a pending $action_type action"); return false; } @@ -337,7 +337,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_alias_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -352,14 +352,14 @@ class remoting_mail extends remoting { if (!$this->checkPerm($session_id, 'mail_alias_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } //* Check if there is no active mailbox with this address $tmp = $app->db->queryOneRecord("SELECT count(mailuser_id) as number FROM mail_user WHERE postfix = 'y' AND email = ?", $params["source"]); if($tmp['number'] > 0) { - throw new SoapFault('duplicate', 'There is already a mailbox with this email address.'); + throw new ISPConfigRemoteException('duplicate', 'There is already a mailbox with this email address.'); } unset($tmp); @@ -374,14 +374,14 @@ class remoting_mail extends remoting { if (!$this->checkPerm($session_id, 'mail_alias_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } //* Check if there is no active mailbox with this address $tmp = $app->db->queryOneRecord("SELECT count(mailuser_id) as number FROM mail_user WHERE postfix = 'y' AND email = ?", $params["source"]); if($tmp['number'] > 0) { - throw new SoapFault('duplicate', 'There is already a mailbox with this email address.'); + throw new ISPConfigRemoteException('duplicate', 'There is already a mailbox with this email address.'); } unset($tmp); @@ -393,7 +393,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_alias_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_alias.tform.php', $primary_id); @@ -406,7 +406,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_forward_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -419,7 +419,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_forward_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_forward.tform.php', $client_id, $params); @@ -431,7 +431,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_forward_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_forward.tform.php', $client_id, $primary_id, $params); @@ -443,7 +443,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_forward_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_forward.tform.php', $primary_id); @@ -456,7 +456,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_catchall_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -469,7 +469,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_catchall_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_domain_catchall.tform.php', $client_id, $params); @@ -480,7 +480,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_catchall_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_domain_catchall.tform.php', $client_id, $primary_id, $params); @@ -491,7 +491,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_catchall_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_domain_catchall.tform.php', $primary_id); @@ -504,7 +504,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_transport_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -517,7 +517,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_transport_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_transport.tform.php', $client_id, $params); @@ -529,7 +529,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_transport_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_transport.tform.php', $client_id, $primary_id, $params); @@ -541,7 +541,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_transport_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_transport.tform.php', $primary_id); @@ -554,7 +554,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_relay_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -568,7 +568,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_relay_add')) { - throw new SoapFault('permission_denied','You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied','You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_relay_recipient.tform.php', $client_id, $params); @@ -580,7 +580,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_relay_update')) { - throw new SoapFault('permission_denied','You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied','You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_relay_recipient.tform.php', $client_id, $primary_id, $params); @@ -592,7 +592,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_relay_delete')) { - throw new SoapFault('permission_denied','You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied','You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_relay_recipient.tform.php', $primary_id); @@ -605,7 +605,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_spamfilter_whitelist_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -618,7 +618,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_whitelist_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/spamfilter_whitelist.tform.php', $client_id, $params); @@ -630,7 +630,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_whitelist_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/spamfilter_whitelist.tform.php', $client_id, $primary_id, $params); @@ -642,7 +642,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_whitelist_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/spamfilter_whitelist.tform.php', $primary_id); @@ -655,7 +655,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_spamfilter_blacklist_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -668,7 +668,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_blacklist_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/spamfilter_blacklist.tform.php', $client_id, $params); @@ -680,7 +680,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_blacklist_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/spamfilter_blacklist.tform.php', $client_id, $primary_id, $params); @@ -692,7 +692,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_blacklist_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/spamfilter_blacklist.tform.php', $primary_id); @@ -705,7 +705,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_spamfilter_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -718,7 +718,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_user_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/spamfilter_users.tform.php', $client_id, $params); @@ -730,7 +730,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/spamfilter_users.tform.php', $client_id, $primary_id, $params); @@ -742,7 +742,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_spamfilter_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/spamfilter_users.tform.php', $primary_id); @@ -755,7 +755,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_policy_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -768,7 +768,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_policy_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/spamfilter_policy.tform.php', $client_id, $params); @@ -780,7 +780,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_policy_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/spamfilter_policy.tform.php', $client_id, $primary_id, $params); @@ -792,7 +792,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_policy_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/spamfilter_policy.tform.php', $primary_id); @@ -805,7 +805,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_fetchmail_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -818,7 +818,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_fetchmail_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_get.tform.php', $client_id, $params); @@ -830,7 +830,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_fetchmail_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_get.tform.php', $client_id, $primary_id, $params); @@ -842,7 +842,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_fetchmail_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_get.tform.php', $primary_id); @@ -855,7 +855,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_whitelist_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -868,7 +868,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_whitelist_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_whitelist.tform.php', $client_id, $params); @@ -880,7 +880,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_whitelist_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_whitelist.tform.php', $client_id, $primary_id, $params); @@ -892,7 +892,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_whitelist_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_whitelist.tform.php', $primary_id); @@ -905,7 +905,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_blacklist_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -918,7 +918,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_blacklist_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_blacklist.tform.php', $client_id, $params); @@ -930,7 +930,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_blacklist_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_blacklist.tform.php', $client_id, $primary_id, $params); @@ -942,7 +942,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_blacklist_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_blacklist.tform.php', $primary_id); @@ -955,7 +955,7 @@ class remoting_mail extends remoting { global $app; if(!$this->checkPerm($session_id, 'mail_filter_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -968,7 +968,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_filter_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->insertQuery('../mail/form/mail_content_filter.tform.php', $client_id, $params); @@ -980,7 +980,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_filter_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../mail/form/mail_content_filter.tform.php', $client_id, $primary_id, $params); @@ -992,7 +992,7 @@ class remoting_mail extends remoting { { if (!$this->checkPerm($session_id, 'mail_filter_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../mail/form/mail_content_filter.tform.php', $primary_id); @@ -1011,7 +1011,7 @@ class remoting_mail extends remoting { public function mail_domain_get_by_domain($session_id, $domain) { global $app; if(!$this->checkPerm($session_id, 'mail_domain_get_by_domain')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($domain)) { @@ -1025,7 +1025,7 @@ class remoting_mail extends remoting { public function mail_domain_set_status($session_id, $primary_id, $status) { global $app; if(!$this->checkPerm($session_id, 'mail_domain_set_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if(in_array($status, array('active', 'inactive'))) { @@ -1039,7 +1039,7 @@ class remoting_mail extends remoting { $result = $app->db->affectedRows(); return $result; } else { - throw new SoapFault('status_undefined', 'The status is not available'); + throw new ISPConfigRemoteException('status_undefined', 'The status is not available'); return false; } } @@ -1051,7 +1051,7 @@ class remoting_mail extends remoting { $app->uses('quota_lib'); if(!$this->checkPerm($session_id, 'mailquota_get_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } diff --git a/interface/lib/classes/remote.d/monitor.inc.php b/interface/lib/classes/remote.d/monitor.inc.php index d3689b94c..9d207f079 100644 --- a/interface/lib/classes/remote.d/monitor.inc.php +++ b/interface/lib/classes/remote.d/monitor.inc.php @@ -38,7 +38,7 @@ class remoting_monitor extends remoting { global $app; if(!$this->checkPerm($session_id, 'monitor_jobqueue_count')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index 66684cf15..261acd848 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -52,7 +52,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get_serverid_by_ip')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $sql = "SELECT server_id FROM server_ip WHERE ip_address = ?"; @@ -66,7 +66,7 @@ class remoting_server extends remoting { global $app; if(!$this->checkPerm($session_id, 'server_ip_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -78,7 +78,7 @@ class remoting_server extends remoting { public function server_ip_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'server_ip_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../admin/form/server_ip.tform.php', $client_id, $params); @@ -88,7 +88,7 @@ class remoting_server extends remoting { public function server_ip_update($session_id, $client_id, $ip_id, $params) { if(!$this->checkPerm($session_id, 'server_ip_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../admin/form/server_ip.tform.php', $client_id, $ip_id, $params); @@ -99,7 +99,7 @@ class remoting_server extends remoting { public function server_ip_delete($session_id, $ip_id) { if(!$this->checkPerm($session_id, 'server_ip_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../admin/form/server_ip.tform.php', $ip_id); @@ -118,7 +118,7 @@ class remoting_server extends remoting { public function server_get($session_id, $server_id = null, $section ='') { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($session_id)) { @@ -155,7 +155,7 @@ class remoting_server extends remoting { public function server_config_set($session_id, $server_id, $section, $key, $value) { global $app; if(!$this->checkPerm($session_id, 'server_config_set')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($server_id) && $server_id > 0 && $section != '' && $key != '') { @@ -165,7 +165,7 @@ class remoting_server extends remoting { $server_config_str = $app->ini_parser->get_ini_string($server_config_array); return $app->db->datalogUpdate('server', array("config" => $server_config_str), 'server_id', $server_id); } else { - throw new SoapFault('invalid_function_parameter', 'Invalid function parameter.'); + throw new ISPConfigRemoteException('invalid_function_parameter', 'Invalid function parameter.'); return false; } } @@ -180,7 +180,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($session_id)) { @@ -202,7 +202,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); } if (!empty($session_id) && !empty($server_name)) { $sql = "SELECT server_id FROM server WHERE server_name = ?"; @@ -223,7 +223,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); } if (!empty($session_id) && !empty($server_id)) { $sql = "SELECT * FROM server WHERE server_id = ?"; @@ -249,7 +249,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); } if (!empty($session_id)) { if($server_id == 0) $ispc_app_version = array('ispc_app_version' => ISPC_APP_VERSION); @@ -269,7 +269,7 @@ class remoting_server extends remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); } if (!empty($session_id) && !empty($server_id) && !empty($php)) { $php_versions = array(); diff --git a/interface/lib/classes/remote.d/sites.inc.php b/interface/lib/classes/remote.d/sites.inc.php index a2f15d6f9..b8ca4c203 100644 --- a/interface/lib/classes/remote.d/sites.inc.php +++ b/interface/lib/classes/remote.d/sites.inc.php @@ -47,7 +47,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_cron_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -59,7 +59,7 @@ class remoting_sites extends remoting { public function sites_cron_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_cron_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/cron.tform.php', $client_id, $params); @@ -69,7 +69,7 @@ class remoting_sites extends remoting { public function sites_cron_update($session_id, $client_id, $cron_id, $params) { if(!$this->checkPerm($session_id, 'sites_cron_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/cron.tform.php', $client_id, $cron_id, $params); @@ -80,7 +80,7 @@ class remoting_sites extends remoting { public function sites_cron_delete($session_id, $cron_id) { if(!$this->checkPerm($session_id, 'sites_cron_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/cron.tform.php', $cron_id); @@ -95,7 +95,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -110,14 +110,14 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } //* Check for duplicates $tmp = $app->db->queryOneRecord("SELECT count(database_id) as dbnum FROM web_database WHERE database_name = ? AND server_id = ?", $params['database_name'], $params["server_id"]); if($tmp['dbnum'] > 0) { - throw new SoapFault('database_name_error_unique', 'There is already a database with that name on the same server.'); + throw new ISPConfigRemoteException('database_name_error_unique', 'There is already a database with that name on the same server.'); return false; } @@ -151,7 +151,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -183,7 +183,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_database_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -202,7 +202,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -214,7 +214,7 @@ class remoting_sites extends remoting { public function sites_database_user_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_database_user_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -227,7 +227,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -257,7 +257,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_database_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -285,7 +285,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_ftp_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -297,7 +297,7 @@ class remoting_sites extends remoting { public function sites_ftp_user_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_ftp_user_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/ftp_user.tform.php', $client_id, $params); @@ -307,7 +307,7 @@ class remoting_sites extends remoting { public function sites_ftp_user_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_ftp_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/ftp_user.tform.php', $client_id, $primary_id, $params); @@ -318,7 +318,7 @@ class remoting_sites extends remoting { public function sites_ftp_user_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_ftp_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/ftp_user.tform.php', $primary_id); @@ -331,7 +331,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_ftp_user_server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -353,7 +353,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_shell_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -365,7 +365,7 @@ class remoting_sites extends remoting { public function sites_shell_user_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_shell_user_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/shell_user.tform.php', $client_id, $params); @@ -375,7 +375,7 @@ class remoting_sites extends remoting { public function sites_shell_user_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_shell_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/shell_user.tform.php', $client_id, $primary_id, $params); @@ -386,7 +386,7 @@ class remoting_sites extends remoting { public function sites_shell_user_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_shell_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/shell_user.tform.php', $primary_id); @@ -401,7 +401,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_domain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -414,7 +414,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_web_domain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -445,7 +445,7 @@ class remoting_sites extends remoting { public function sites_web_domain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_domain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -465,7 +465,7 @@ class remoting_sites extends remoting { public function sites_web_domain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_domain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_vhost_domain.tform.php', $primary_id); @@ -480,7 +480,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -493,7 +493,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -517,7 +517,7 @@ class remoting_sites extends remoting { public function sites_web_vhost_aliasdomain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -537,7 +537,7 @@ class remoting_sites extends remoting { public function sites_web_vhost_aliasdomain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_vhost_domain.tform.php', $primary_id); @@ -552,7 +552,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_subdomain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -565,7 +565,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_web_subdomain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -589,7 +589,7 @@ class remoting_sites extends remoting { public function sites_web_vhost_subdomain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_subdomain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -609,7 +609,7 @@ class remoting_sites extends remoting { public function sites_web_vhost_subdomain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_subdomain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_vhost_domain.tform.php', $primary_id); @@ -624,7 +624,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -636,7 +636,7 @@ class remoting_sites extends remoting { public function sites_web_aliasdomain_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/web_childdomain.tform.php', $client_id, $params); @@ -646,7 +646,7 @@ class remoting_sites extends remoting { public function sites_web_aliasdomain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/web_childdomain.tform.php', $client_id, $primary_id, $params); @@ -657,7 +657,7 @@ class remoting_sites extends remoting { public function sites_web_aliasdomain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_aliasdomain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_childdomain.tform.php', $primary_id); @@ -672,7 +672,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_subdomain_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -684,7 +684,7 @@ class remoting_sites extends remoting { public function sites_web_subdomain_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_subdomain_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/web_childdomain.tform.php', $client_id, $params); @@ -694,7 +694,7 @@ class remoting_sites extends remoting { public function sites_web_subdomain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_subdomain_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/web_childdomain.tform.php', $client_id, $primary_id, $params); @@ -705,7 +705,7 @@ class remoting_sites extends remoting { public function sites_web_subdomain_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_subdomain_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_childdomain.tform.php', $primary_id); @@ -720,7 +720,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_folder_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -732,7 +732,7 @@ class remoting_sites extends remoting { public function sites_web_folder_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_folder_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/web_folder.tform.php', $client_id, $params); @@ -742,7 +742,7 @@ class remoting_sites extends remoting { public function sites_web_folder_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_folder_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/web_folder.tform.php', $client_id, $primary_id, $params); @@ -754,7 +754,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_web_folder_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -778,7 +778,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_folder_user_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $app->uses('remoting_lib'); @@ -790,7 +790,7 @@ class remoting_sites extends remoting { public function sites_web_folder_user_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_folder_user_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->insertQuery('../sites/form/web_folder_user.tform.php', $client_id, $params); @@ -800,7 +800,7 @@ class remoting_sites extends remoting { public function sites_web_folder_user_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'sites_web_folder_user_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->updateQuery('../sites/form/web_folder_user.tform.php', $client_id, $primary_id, $params); @@ -811,7 +811,7 @@ class remoting_sites extends remoting { public function sites_web_folder_user_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'sites_web_folder_user_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $affected_rows = $this->deleteQuery('../sites/form/web_folder_user.tform.php', $primary_id); @@ -831,7 +831,7 @@ class remoting_sites extends remoting { public function client_get_sites_by_user($session_id, $sys_userid, $sys_groupid) { global $app; if(!$this->checkPerm($session_id, 'client_get_sites_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $sys_userid = $app->functions->intval($sys_userid); @@ -846,7 +846,7 @@ class remoting_sites extends remoting { if(isset($result)) { return $result; } else { - throw new SoapFault('no_client_found', 'There is no site for this user'); + throw new ISPConfigRemoteException('no_client_found', 'There is no site for this user'); return false; } } @@ -864,7 +864,7 @@ class remoting_sites extends remoting { public function sites_web_domain_set_status($session_id, $primary_id, $status) { global $app; if(!$this->checkPerm($session_id, 'sites_web_domain_set_status')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if(in_array($status, array('active', 'inactive'))) { @@ -880,7 +880,7 @@ class remoting_sites extends remoting { $affected_rows = $this->updateQuery('../sites/form/web_vhost_domain.tform.php', 0, $primary_id, $params); return $affected_rows; } else { - throw new SoapFault('status_undefined', 'The status is not available'); + throw new ISPConfigRemoteException('status_undefined', 'The status is not available'); return false; } } @@ -893,7 +893,7 @@ class remoting_sites extends remoting { { global $app; if(!$this->checkPerm($session_id, 'sites_database_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } $client_id = $app->functions->intval($client_id); @@ -908,7 +908,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_domain_backup')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -922,7 +922,7 @@ class remoting_sites extends remoting { global $app; if(!$this->checkPerm($session_id, 'sites_web_domain_backup')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -936,19 +936,19 @@ class remoting_sites extends remoting { //* Basic validation of variables if ($server_id <= 0) { - throw new SoapFault('invalid_backup_id', "Invalid or non existant backup_id $primary_id"); + throw new ISPConfigRemoteException('invalid_backup_id', "Invalid or non existant backup_id $primary_id"); return false; } if ($action_type != 'backup_download' and $action_type != 'backup_restore' and $action_type != 'backup_delete') { - throw new SoapFault('invalid_action', "Invalid action_type $action_type"); + throw new ISPConfigRemoteException('invalid_action', "Invalid action_type $action_type"); return false; } //* Validate instance $instance_record = $app->db->queryOneRecord("SELECT * FROM `sys_remoteaction` WHERE `action_param`= ? and `action_type`= ? and `action_state`= ?", $primary_id, $action_type, 'pending'); if ($instance_record['action_id'] >= 1) { - throw new SoapFault('duplicate_action', "There is already a pending $action_type action"); + throw new ISPConfigRemoteException('duplicate_action', "There is already a pending $action_type action"); return false; } @@ -967,7 +967,7 @@ class remoting_sites extends remoting { $app->uses('quota_lib'); if(!$this->checkPerm($session_id, 'quota_get_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } @@ -980,7 +980,7 @@ class remoting_sites extends remoting { $app->uses('quota_lib'); if(!$this->checkPerm($session_id, 'trafficquota_get_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if ($client_id != null) @@ -995,7 +995,7 @@ class remoting_sites extends remoting { $app->uses('quota_lib'); if(!$this->checkPerm($session_id, 'trafficquota_get_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if ($client_id != null) @@ -1010,7 +1010,7 @@ class remoting_sites extends remoting { $app->uses('quota_lib'); if(!$this->checkPerm($session_id, 'databasequota_get_by_user')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index 8522ebc6f..0ca262e59 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -206,7 +206,7 @@ class remoting { fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); - throw new SoapFault($error['faultcode'], $error['faultstring']); + throw new ISPConfigRemoteException($error['faultcode'], $error['faultstring']); return false; } else { // User login right, so attempts can be deleted @@ -231,7 +231,7 @@ class remoting { global $app; if(empty($session_id)) { - throw new SoapFault('session_id_empty', 'The SessionID is empty.'); + throw new ISPConfigRemoteException('session_id_empty', 'The SessionID is empty.'); return false; } @@ -265,14 +265,14 @@ class remoting { //* Stop on error while preparing the sql query if($app->remoting_lib->errorMessage != '') { - throw new SoapFault('data_processing_error', $app->remoting_lib->errorMessage); + throw new ISPConfigRemoteException('data_processing_error', $app->remoting_lib->errorMessage); return false; } //* Execute the SQL query $app->db->query($sql); if($app->db->errorMessage != '') { - throw new SoapFault('database_error', $app->db->errorMessage . ' '.$sql); + throw new ISPConfigRemoteException('database_error', $app->db->errorMessage . ' '.$sql); return false; } if ( isset($params['_primary_id'] )) @@ -283,7 +283,7 @@ class remoting { //* Stop on error while executing the sql query if($app->remoting_lib->errorMessage != '') { - throw new SoapFault('data_processing_error', $app->remoting_lib->errorMessage); + throw new ISPConfigRemoteException('data_processing_error', $app->remoting_lib->errorMessage); return false; } @@ -294,7 +294,7 @@ class remoting { /* if($app->db->errorMessage != '') { - throw new SoapFault('database_error', $app->db->errorMessage . ' '.$sql); + throw new ISPConfigRemoteException('database_error', $app->db->errorMessage . ' '.$sql); return false; } */ @@ -345,7 +345,7 @@ class remoting { //* Get the SQL query $sql = $app->remoting_lib->getSQL($params, 'INSERT', 0); if($app->remoting_lib->errorMessage != '') { - throw new SoapFault('data_processing_error', $app->remoting_lib->errorMessage); + throw new ISPConfigRemoteException('data_processing_error', $app->remoting_lib->errorMessage); return false; } $app->log('Executed insertQueryPrepare', LOGLEVEL_DEBUG); @@ -361,7 +361,7 @@ class remoting { $app->db->query($sql); if($app->db->errorMessage != '') { - throw new SoapFault('database_error', $app->db->errorMessage . ' '.$sql); + throw new ISPConfigRemoteException('database_error', $app->db->errorMessage . ' '.$sql); return false; } @@ -421,9 +421,9 @@ class remoting { //* Get the SQL query $sql = $app->remoting_lib->getSQL($params, 'UPDATE', $primary_id); - // throw new SoapFault('debug', $sql); + // throw new ISPConfigRemoteException('debug', $sql); if($app->remoting_lib->errorMessage != '') { - throw new SoapFault('data_processing_error', $app->remoting_lib->errorMessage); + throw new ISPConfigRemoteException('data_processing_error', $app->remoting_lib->errorMessage); return false; } @@ -446,7 +446,7 @@ class remoting { $app->db->query($sql); if($app->db->errorMessage != '') { - throw new SoapFault('database_error', $app->db->errorMessage . ' '.$sql); + throw new ISPConfigRemoteException('database_error', $app->db->errorMessage . ' '.$sql); return false; } @@ -492,7 +492,7 @@ class remoting { $affected_rows = $app->db->affectedRows(); if($app->db->errorMessage != '') { - throw new SoapFault('database_error', $app->db->errorMessage . ' '.$sql); + throw new ISPConfigRemoteException('database_error', $app->db->errorMessage . ' '.$sql); return false; } @@ -543,7 +543,7 @@ class remoting { global $app; if(empty($session_id)) { - throw new SoapFault('session_id_empty', 'The SessionID is empty.'); + throw new ISPConfigRemoteException('session_id_empty', 'The SessionID is empty.'); return false; } @@ -552,7 +552,7 @@ class remoting { if($session['remote_userid'] > 0) { return $session; } else { - throw new SoapFault('session_does_not_exist', 'The Session is expired or does not exist.'); + throw new ISPConfigRemoteException('session_does_not_exist', 'The Session is expired or does not exist.'); return false; } } @@ -560,7 +560,7 @@ class remoting { public function server_get($session_id, $server_id = null, $section ='') { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($session_id)) { @@ -594,7 +594,7 @@ class remoting { { global $app; if(!$this->checkPerm($session_id, 'server_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } if (!empty($session_id)) { @@ -617,7 +617,7 @@ class remoting { public function get_function_list($session_id) { if(!$this->checkPerm($session_id, 'get_function_list')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + throw new ISPConfigRemoteException('permission_denied', 'You do not have the permissions to access this function.'); return false; } return $this->_methods; diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index a5a5d0c31..6fd5d2f3d 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -238,7 +238,7 @@ class remoting_lib extends tform_base { $sql = "SELECT * FROM ??"; return $app->db->queryAllRecords($sql, $this->formDef['db_table']); } else { - throw new SoapFault('invalid_id', 'The ID has to be > 0 or -1.'); + throw new ISPConfigRemoteException('invalid_id', 'The ID has to be > 0 or -1.'); return array(); } } elseif (@is_array($primary_id) || @is_object($primary_id)) { diff --git a/interface/lib/classes/rest_handler.inc.php b/interface/lib/classes/rest_handler.inc.php index ceaa7c63b..ebca73c40 100644 --- a/interface/lib/classes/rest_handler.inc.php +++ b/interface/lib/classes/rest_handler.inc.php @@ -173,11 +173,17 @@ class ISPConfigRESTHandler { try { $this->_return_json($return_code, call_user_func_array(array($this->classes[$class_name], $method), $params)); - } catch(SoapFault $e) { + } catch(ISPConfigRemoteException $e) { $this->_return_error(500, 'REQUEST ERROR', $e->getMessage()); } } } -?> +if(!class_exists('ISPConfigRemoteException')) { + class ISPConfigRemoteException extends Exception { + public function __construct($code = '', $message = '') { + parent::__construct($message . ' (' . $code . ')', 0); + } + } +} \ No newline at end of file diff --git a/interface/lib/classes/soap_handler.inc.php b/interface/lib/classes/soap_handler.inc.php index 704e21b20..31221bcfe 100644 --- a/interface/lib/classes/soap_handler.inc.php +++ b/interface/lib/classes/soap_handler.inc.php @@ -71,25 +71,31 @@ class ISPConfigSoapHandler { public function __call($method, $params) { if(array_key_exists($method, $this->methods) == false) { - throw new SoapFault('invalid_method', 'Method ' . $method . ' does not exist'); + throw new ISPConfigRemoteException('invalid_method', 'Method ' . $method . ' does not exist'); } $class_name = $this->methods[$method]; if(array_key_exists($class_name, $this->classes) == false) { - throw new SoapFault('invalid_class', 'Class ' . $class_name . ' does not exist'); + throw new ISPConfigRemoteException('invalid_class', 'Class ' . $class_name . ' does not exist'); } if(method_exists($this->classes[$class_name], $method) == false) { - throw new SoapFault('invalid_method', 'Method ' . $method . ' does not exist in the class it was expected (' . $class_name . ')'); + throw new ISPConfigRemoteException('invalid_method', 'Method ' . $method . ' does not exist in the class it was expected (' . $class_name . ')'); } try { return call_user_func_array(array($this->classes[$class_name], $method), $params); - } catch(SoapFault $e) { + } catch(ISPConfigRemoteException $e) { throw $e; } } } -?> +if(!class_exists('ISPConfigRemoteException')) { + class ISPConfigRemoteException extends SoapFault { + public function __construct($code = '', $message = '') { + parent::__construct($code, $message); + } + } +} diff --git a/interface/lib/classes/validate_client.inc.php b/interface/lib/classes/validate_client.inc.php index 980e6ffbb..20050d8cb 100644 --- a/interface/lib/classes/validate_client.inc.php +++ b/interface/lib/classes/validate_client.inc.php @@ -193,7 +193,7 @@ class validate_client { } */ - } catch(SoapFault $e) { + } catch(ISPConfigRemoteException $e) { //echo 'Error, see message: '.$e->faultstring; switch ($e->faultstring) { case 'INVALID_INPUT': @@ -212,7 +212,7 @@ class validate_client { break; } } - } catch(SoapFault $e){ + } catch(ISPConfigRemoteException $e){ // Connection to host not possible, europe.eu down? // this shouldn't be the user's fault, so we return no error } -- GitLab From 60820b77ea9077e93e5b587605965efee64e7cd4 Mon Sep 17 00:00:00 2001 From: Paco Date: Tue, 27 Nov 2018 22:41:48 +0100 Subject: [PATCH 236/310] Add new file --- server/conf/index/standard_index.html_bg | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 server/conf/index/standard_index.html_bg diff --git a/server/conf/index/standard_index.html_bg b/server/conf/index/standard_index.html_bg new file mode 100644 index 000000000..e69de29bb -- GitLab From af030ccf36a1722a2a180357ad1c56a5766bd596 Mon Sep 17 00:00:00 2001 From: Paco Date: Tue, 27 Nov 2018 22:47:07 +0100 Subject: [PATCH 237/310] Update standard_index.html_bg --- server/conf/index/standard_index.html_bg | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/server/conf/index/standard_index.html_bg b/server/conf/index/standard_index.html_bg index e69de29bb..4e303d88b 100644 --- a/server/conf/index/standard_index.html_bg +++ b/server/conf/index/standard_index.html_bg @@ -0,0 +1,60 @@ + + + + Привет! + + + + + + +
+ +
+

Това е страницата по подразбиране за вашият уеб сайт.

+

Този файл може да бъде изтрит или презаписан с друг без никакъв проблем. Виждате съдържанието на файла index.html в web директорията.

+

Ако имате въпроси или проблеми може да се свържете с поддръжката.

+
+ +
+ + -- GitLab From 1d0a8d1c662aa0330b8200606f3cb79f6a19e8c8 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 20 Nov 2018 22:38:43 +0100 Subject: [PATCH 238/310] First draft domains_domain_update --- interface/lib/classes/remote.d/domains.inc.php | 10 ++++++++++ interface/web/client/lib/remote.conf.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/interface/lib/classes/remote.d/domains.inc.php b/interface/lib/classes/remote.d/domains.inc.php index 33830335d..ef768825b 100644 --- a/interface/lib/classes/remote.d/domains.inc.php +++ b/interface/lib/classes/remote.d/domains.inc.php @@ -65,6 +65,16 @@ class remoting_domains extends remoting { return $this->insertQuery('../client/form/domain.tform.php', $client_id, $params); } + //* Update a record + public function domains_domain_update($session_id, $client_id, $params) + { + if(!$this->checkPerm($session_id, 'domains_domain_update')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + return $this->updateQuery('../client/form/domain.tform.php', $client_id, $params); + } + //* Delete a record public function domains_domain_delete($session_id, $primary_id) { diff --git a/interface/web/client/lib/remote.conf.php b/interface/web/client/lib/remote.conf.php index d58029e85..0c2449b93 100644 --- a/interface/web/client/lib/remote.conf.php +++ b/interface/web/client/lib/remote.conf.php @@ -1,7 +1,7 @@ Date: Tue, 27 Nov 2018 10:53:35 +0100 Subject: [PATCH 239/310] correct parameters --- interface/lib/classes/remote.d/domains.inc.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/lib/classes/remote.d/domains.inc.php b/interface/lib/classes/remote.d/domains.inc.php index ef768825b..05a639ad6 100644 --- a/interface/lib/classes/remote.d/domains.inc.php +++ b/interface/lib/classes/remote.d/domains.inc.php @@ -66,13 +66,13 @@ class remoting_domains extends remoting { } //* Update a record - public function domains_domain_update($session_id, $client_id, $params) + public function domains_domain_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'domains_domain_update')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; } - return $this->updateQuery('../client/form/domain.tform.php', $client_id, $params); + return $this->updateQuery('../client/form/domain.tform.php', $client_id, $primary_id, $params); } //* Delete a record -- GitLab From e5ac9179520c1e51c99179e5f92c8e5fa667435e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 10:54:27 +0100 Subject: [PATCH 240/310] Add example for domains_domain_update --- .../examples/domains_domain_update.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 remoting_client/examples/domains_domain_update.php diff --git a/remoting_client/examples/domains_domain_update.php b/remoting_client/examples/domains_domain_update.php new file mode 100644 index 000000000..4e868c204 --- /dev/null +++ b/remoting_client/examples/domains_domain_update.php @@ -0,0 +1,38 @@ + $soap_location, + 'uri' => $soap_uri, + 'trace' => 1, + 'exceptions' => 1)); + + +try { + if($session_id = $client->login($username, $password)) { + echo 'Logged successfull. Session ID:'.$session_id.'
'; + } + + //* Set the function parameters. + $client_id = 1; + $primary_id = 42; // The domain_id + $params = array( + 'domain' => 'cellar.door' + ); + + $domain_id = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); + + echo "Domain ID: ".$domain_id."
"; + + if($client->logout($session_id)) { + echo 'Logged out.
'; + } + + +} catch (SoapFault $e) { + echo $client->__getLastResponse(); + die('SOAP Error: '.$e->getMessage()); +} + +?> -- GitLab From cacfe8d3d6e0aa0815e618b0cad6e4e07a811da4 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 10:57:13 +0100 Subject: [PATCH 241/310] Correct an obvious typo ... maybe remove as the code path below was unreachable --- interface/lib/classes/tform_base.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php index 3dc9edacc..36de1371a 100644 --- a/interface/lib/classes/tform_base.inc.php +++ b/interface/lib/classes/tform_base.inc.php @@ -1384,7 +1384,7 @@ class tform_base { } else { if($this->formDef['auth'] == 'yes') { if($primary_id != 0) { - if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["iserid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) { + if($api == true && $_SESSION["s"]["user"]["client_id"] > 0 && $_SESSION["s"]["user"]["userid"] > 0 && $_SESSION["s"]["user"]["default_group"] > 0) { $sql_update .= '`sys_userid` = '.$this->sys_userid.', '; $sql_update .= '`sys_groupid` = '.$this->sys_default_group.', '; } -- GitLab From 54c38fc4a7f9c1cf34398097b16f183f965d8cec Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 27 Nov 2018 11:20:09 +0100 Subject: [PATCH 242/310] Add apidoc domains_domain_update --- .../API-docs/domains_domain_update.html | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 remoting_client/API-docs/domains_domain_update.html diff --git a/remoting_client/API-docs/domains_domain_update.html b/remoting_client/API-docs/domains_domain_update.html new file mode 100644 index 000000000..bf3dd9c4b --- /dev/null +++ b/remoting_client/API-docs/domains_domain_update.html @@ -0,0 +1,30 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

domains_domain_update($session_id, $client_id, $primary_id, $params);

+
+

Description:

+

Updates domain to move it to another client.


+

Input Variables:

+

$session_id, $client_id, $primary_id, $params

+

Parameters (in $params):

+

domain  (varchar(255))

+

client_id  (int(11))

+

Output:

+

Returns the number of affected rows.

+ +
+ + -- GitLab From e7f95dbe999e9ab73566237a2863bb97c0301f0c Mon Sep 17 00:00:00 2001 From: Kordian Bruck Date: Mon, 3 Dec 2018 18:53:20 +0100 Subject: [PATCH 243/310] Warn if the lockfile for system cron is older than a day We want to avoid deadlock situations and right now if there is a process running with the same PID that is not our process (e.g. after a reboot) we might be waiting forever to run the cron again. So to make this transparent to the user, we at least post a warning into the logfile. --- server/cron.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/server/cron.php b/server/cron.php index 261abd983..6f74bd357 100644 --- a/server/cron.php +++ b/server/cron.php @@ -32,9 +32,18 @@ define('SCRIPT_PATH', dirname($_SERVER["SCRIPT_FILENAME"])); require SCRIPT_PATH."/lib/config.inc.php"; // Check whether another instance of this script is already running -if (is_file($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')) { +$lockFile = $conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock'; +if (is_file($lockFile)) { clearstatcache(); - $pid = trim(file_get_contents($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')); + + // Maybe we hit a deadlock and the lock file is no longer relevant + if(filemtime($lockFile) > time() - 86400) { // 86400 seconds = 1 day + if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - The cron lock file is older than one day.' . "\n"; + exit; + } + + // Check if the process id we have in the lock file is still present + $pid = trim(file_get_contents($lockFile)); if(preg_match('/^[0-9]+$/', $pid)) { if(file_exists('/proc/' . $pid)) { if($conf['log_priority'] <= LOGLEVEL_WARN) print @date('d.m.Y-H:i').' - WARNING - There is already an instance of server.php running with pid ' . $pid . '.' . "\n"; @@ -45,7 +54,7 @@ if (is_file($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock')) { } // Set Lockfile -@file_put_contents($conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock', getmypid()); +@file_put_contents($lockFile, getmypid()); if($conf['log_priority'] <= LOGLEVEL_DEBUG) print 'Set Lock: ' . $conf['temppath'] . $conf['fs_div'] . '.ispconfig_cron_lock' . "\n"; -- GitLab From 03e39417a8250db0e698399c4a3ba9575eeb71bd Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 4 Dec 2018 16:26:11 +0100 Subject: [PATCH 244/310] Pass a client_id to getDataRecord() to not override a session in loadUserProfile() --- interface/lib/classes/remoting.inc.php | 2 +- interface/lib/classes/remoting_lib.inc.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index fe8b1694c..6e551355a 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -383,7 +383,7 @@ class remoting { $app->remoting_lib->loadFormDef($formdef_file); //* get old record and merge with params, so only new values have to be set in $params - $old_rec = $app->remoting_lib->getDataRecord($primary_id); + $old_rec = $app->remoting_lib->getDataRecord($primary_id, $client_id); foreach ($app->remoting_lib->formDef['fields'] as $fieldName => $fieldConf) { diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index a5a5d0c31..ec04254dd 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -225,10 +225,10 @@ class remoting_lib extends tform_base { return $sql; } - function getDataRecord($primary_id) { + function getDataRecord($primary_id, $client_id) { global $app; $escape = '`'; - $this->loadUserProfile(); + $this->loadUserProfile($client_id); if(@is_numeric($primary_id)) { if($primary_id > 0) { // Return a single record -- GitLab From 7bd740fa1e4c0f15d4b0b4ab46e330b8a43a645e Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 4 Dec 2018 18:58:15 +0100 Subject: [PATCH 245/310] Fixed #5168 Mail server settings can generate invalid main.cf --- interface/web/admin/lib/lang/ar_server_config.lng | 1 + interface/web/admin/lib/lang/bg_server_config.lng | 1 + interface/web/admin/lib/lang/br_server_config.lng | 1 + interface/web/admin/lib/lang/ca_server_config.lng | 1 + interface/web/admin/lib/lang/cz_server_config.lng | 1 + interface/web/admin/lib/lang/de_server_config.lng | 1 + interface/web/admin/lib/lang/dk_server_config.lng | 1 + interface/web/admin/lib/lang/el_server_config.lng | 1 + interface/web/admin/lib/lang/en_server_config.lng | 1 + interface/web/admin/lib/lang/es_server_config.lng | 1 + interface/web/admin/lib/lang/fi_server_config.lng | 1 + interface/web/admin/lib/lang/fr_server_config.lng | 1 + interface/web/admin/lib/lang/hr_server_config.lng | 1 + interface/web/admin/lib/lang/hu_server_config.lng | 1 + interface/web/admin/lib/lang/id_server_config.lng | 1 + interface/web/admin/lib/lang/it_server_config.lng | 1 + interface/web/admin/lib/lang/ja_server_config.lng | 1 + interface/web/admin/lib/lang/nl_server_config.lng | 1 + interface/web/admin/lib/lang/pl_server_config.lng | 1 + interface/web/admin/lib/lang/pt_server_config.lng | 1 + interface/web/admin/lib/lang/ro_server_config.lng | 1 + interface/web/admin/lib/lang/ru_server_config.lng | 1 + interface/web/admin/lib/lang/se_server_config.lng | 1 + interface/web/admin/lib/lang/sk_server_config.lng | 1 + interface/web/admin/lib/lang/tr_server_config.lng | 1 + interface/web/admin/server_config_edit.php | 9 +++++++++ 26 files changed, 34 insertions(+) diff --git a/interface/web/admin/lib/lang/ar_server_config.lng b/interface/web/admin/lib/lang/ar_server_config.lng index 55d4c4ffc..b7e75ffd4 100644 --- a/interface/web/admin/lib/lang/ar_server_config.lng +++ b/interface/web/admin/lib/lang/ar_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/bg_server_config.lng b/interface/web/admin/lib/lang/bg_server_config.lng index 74e0405cd..37f654d5a 100644 --- a/interface/web/admin/lib/lang/bg_server_config.lng +++ b/interface/web/admin/lib/lang/bg_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/br_server_config.lng b/interface/web/admin/lib/lang/br_server_config.lng index 70512ea93..b016ad04c 100644 --- a/interface/web/admin/lib/lang/br_server_config.lng +++ b/interface/web/admin/lib/lang/br_server_config.lng @@ -292,4 +292,5 @@ $wb['logging_desc_txt'] = 'Use Tools > Resync to apply changes to existing sites $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ca_server_config.lng b/interface/web/admin/lib/lang/ca_server_config.lng index fbd3e1ea0..a83144b33 100644 --- a/interface/web/admin/lib/lang/ca_server_config.lng +++ b/interface/web/admin/lib/lang/ca_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/cz_server_config.lng b/interface/web/admin/lib/lang/cz_server_config.lng index 54acda96f..9a7656352 100644 --- a/interface/web/admin/lib/lang/cz_server_config.lng +++ b/interface/web/admin/lib/lang/cz_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/de_server_config.lng b/interface/web/admin/lib/lang/de_server_config.lng index f81bb279b..1d8109e8e 100644 --- a/interface/web/admin/lib/lang/de_server_config.lng +++ b/interface/web/admin/lib/lang/de_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Beschreibung Standard PHP'; $wb['php_default_name_error_empty'] = 'Beschreibung Standard PHP ist leer.'; +$wb['error_mailbox_message_size_txt'] = 'Mailboxgröße muss gleich oder größer als max. Nachrichtengröße sein.'; ?> diff --git a/interface/web/admin/lib/lang/dk_server_config.lng b/interface/web/admin/lib/lang/dk_server_config.lng index 61139aa54..26f953d5b 100644 --- a/interface/web/admin/lib/lang/dk_server_config.lng +++ b/interface/web/admin/lib/lang/dk_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/el_server_config.lng b/interface/web/admin/lib/lang/el_server_config.lng index 38600769c..1298ea71a 100644 --- a/interface/web/admin/lib/lang/el_server_config.lng +++ b/interface/web/admin/lib/lang/el_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/en_server_config.lng b/interface/web/admin/lib/lang/en_server_config.lng index bcbf4ceea..fe35d1c5e 100644 --- a/interface/web/admin/lib/lang/en_server_config.lng +++ b/interface/web/admin/lib/lang/en_server_config.lng @@ -294,4 +294,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/es_server_config.lng b/interface/web/admin/lib/lang/es_server_config.lng index cb0fbf121..5ce3381d9 100755 --- a/interface/web/admin/lib/lang/es_server_config.lng +++ b/interface/web/admin/lib/lang/es_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/fi_server_config.lng b/interface/web/admin/lib/lang/fi_server_config.lng index 6e08e9841..4609ce5b1 100755 --- a/interface/web/admin/lib/lang/fi_server_config.lng +++ b/interface/web/admin/lib/lang/fi_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/fr_server_config.lng b/interface/web/admin/lib/lang/fr_server_config.lng index 2045dbb8b..e31d68383 100644 --- a/interface/web/admin/lib/lang/fr_server_config.lng +++ b/interface/web/admin/lib/lang/fr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/hr_server_config.lng b/interface/web/admin/lib/lang/hr_server_config.lng index 99d69fec0..c54a67659 100644 --- a/interface/web/admin/lib/lang/hr_server_config.lng +++ b/interface/web/admin/lib/lang/hr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/hu_server_config.lng b/interface/web/admin/lib/lang/hu_server_config.lng index 24d2fcb05..1ac1cd268 100644 --- a/interface/web/admin/lib/lang/hu_server_config.lng +++ b/interface/web/admin/lib/lang/hu_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/id_server_config.lng b/interface/web/admin/lib/lang/id_server_config.lng index 8abd5d6be..a47389196 100644 --- a/interface/web/admin/lib/lang/id_server_config.lng +++ b/interface/web/admin/lib/lang/id_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/it_server_config.lng b/interface/web/admin/lib/lang/it_server_config.lng index a87f3129d..8c563853c 100644 --- a/interface/web/admin/lib/lang/it_server_config.lng +++ b/interface/web/admin/lib/lang/it_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ja_server_config.lng b/interface/web/admin/lib/lang/ja_server_config.lng index f915e8607..76c400728 100644 --- a/interface/web/admin/lib/lang/ja_server_config.lng +++ b/interface/web/admin/lib/lang/ja_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/nl_server_config.lng b/interface/web/admin/lib/lang/nl_server_config.lng index c8b320b8c..350a06ba3 100644 --- a/interface/web/admin/lib/lang/nl_server_config.lng +++ b/interface/web/admin/lib/lang/nl_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/pl_server_config.lng b/interface/web/admin/lib/lang/pl_server_config.lng index 6f00d524e..c052b7f37 100644 --- a/interface/web/admin/lib/lang/pl_server_config.lng +++ b/interface/web/admin/lib/lang/pl_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/pt_server_config.lng b/interface/web/admin/lib/lang/pt_server_config.lng index 62a8a3401..4767022e4 100644 --- a/interface/web/admin/lib/lang/pt_server_config.lng +++ b/interface/web/admin/lib/lang/pt_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ro_server_config.lng b/interface/web/admin/lib/lang/ro_server_config.lng index f7c4c5703..41b967b73 100644 --- a/interface/web/admin/lib/lang/ro_server_config.lng +++ b/interface/web/admin/lib/lang/ro_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/ru_server_config.lng b/interface/web/admin/lib/lang/ru_server_config.lng index a95d6e70c..0775ab7f8 100644 --- a/interface/web/admin/lib/lang/ru_server_config.lng +++ b/interface/web/admin/lib/lang/ru_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/se_server_config.lng b/interface/web/admin/lib/lang/se_server_config.lng index 97d3c9f80..5808fb2f5 100644 --- a/interface/web/admin/lib/lang/se_server_config.lng +++ b/interface/web/admin/lib/lang/se_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/sk_server_config.lng b/interface/web/admin/lib/lang/sk_server_config.lng index cfc0b3ab7..d5b1f92bf 100644 --- a/interface/web/admin/lib/lang/sk_server_config.lng +++ b/interface/web/admin/lib/lang/sk_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/lib/lang/tr_server_config.lng b/interface/web/admin/lib/lang/tr_server_config.lng index ccf1ed5b9..c7be37926 100644 --- a/interface/web/admin/lib/lang/tr_server_config.lng +++ b/interface/web/admin/lib/lang/tr_server_config.lng @@ -293,4 +293,5 @@ $wb['log_retention_txt'] = 'Log retention (days)'; $wb['log_retention_error_ispositive'] = 'Log retention must be a number > 0'; $wb['php_default_name_txt'] = 'Description Default PHP-Version'; $wb['php_default_name_error_empty'] = 'Description Default PHP-Version must not be empty'; +$wb['error_mailbox_message_size_txt'] = 'Mailbox size must be larger or equal to message size'; ?> diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index e446bf3ad..7eebb7f5b 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -52,6 +52,15 @@ $app->load('tform_actions'); class page_action extends tform_actions { + function onSubmit() { + global $app, $conf; + + if(isset($this->dataRecord['mailbox_size_limit']) && $this->dataRecord['mailbox_size_limit'] != 0 && $this->dataRecord['mailbox_size_limit'] < $this->dataRecord['message_size_limit']) { + $app->tform->errorMessage .= $app->tform->lng("error_mailbox_message_size_txt").'
'; + } + parent::onSubmit(); + } + function onShowEdit() { global $app, $conf; -- GitLab From 33014e3beefef7e24021b0906da1ff1c20dba3f2 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Tue, 4 Dec 2018 16:50:00 +0100 Subject: [PATCH 246/310] Add a default value for client_id --- interface/lib/classes/remoting_lib.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/remoting_lib.inc.php b/interface/lib/classes/remoting_lib.inc.php index ec04254dd..62ccd506c 100644 --- a/interface/lib/classes/remoting_lib.inc.php +++ b/interface/lib/classes/remoting_lib.inc.php @@ -225,7 +225,7 @@ class remoting_lib extends tform_base { return $sql; } - function getDataRecord($primary_id, $client_id) { + function getDataRecord($primary_id, $client_id = 0) { global $app; $escape = '`'; $this->loadUserProfile($client_id); -- GitLab From c6320660dd20c14c9bc85e99853be6551c76690f Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Wed, 5 Dec 2018 09:35:36 +0100 Subject: [PATCH 247/310] Correct example code --- remoting_client/examples/domains_domain_update.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/remoting_client/examples/domains_domain_update.php b/remoting_client/examples/domains_domain_update.php index 4e868c204..244222428 100644 --- a/remoting_client/examples/domains_domain_update.php +++ b/remoting_client/examples/domains_domain_update.php @@ -21,11 +21,12 @@ try { 'domain' => 'cellar.door' ); - $domain_id = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); + $result = $client->domains_domain_update($session_id, $client_id, $primary_id, $params); - echo "Domain ID: ".$domain_id."
"; - - if($client->logout($session_id)) { + if ($result) { + echo 'Domain updated.
'; + } + if ($client->logout($session_id)) { echo 'Logged out.
'; } -- GitLab From 79f6d0c842df9cd956452b0954cadc5b16b08d1e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Wed, 5 Dec 2018 10:15:35 +0100 Subject: [PATCH 248/310] Limit rounding quota to 1 decimal 104.3 MB looks better to me then the current 104.3345 MB. (is that level of detail is desired then maybe we should force kB notation.) Maybe 2 or even three decimals ... but not 4. --- interface/lib/classes/quota_lib.inc.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/interface/lib/classes/quota_lib.inc.php b/interface/lib/classes/quota_lib.inc.php index e5d55ff80..3946b216d 100644 --- a/interface/lib/classes/quota_lib.inc.php +++ b/interface/lib/classes/quota_lib.inc.php @@ -54,19 +54,19 @@ class quota_lib { if($used_ratio >= 1) $sites[$i]['display_colour'] = '#cc0000'; if($sites[$i]['used'] > 1024) { - $sites[$i]['used'] = round($sites[$i]['used'] / 1024, 2).' MB'; + $sites[$i]['used'] = round($sites[$i]['used'] / 1024, 1).' MB'; } else { if ($sites[$i]['used'] != '') $sites[$i]['used'] .= ' KB'; } if($sites[$i]['soft'] > 1024) { - $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024, 2).' MB'; + $sites[$i]['soft'] = round($sites[$i]['soft'] / 1024, 1).' MB'; } else { $sites[$i]['soft'] .= ' KB'; } if($sites[$i]['hard'] > 1024) { - $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024, 2).' MB'; + $sites[$i]['hard'] = round($sites[$i]['hard'] / 1024, 1).' MB'; } else { $sites[$i]['hard'] .= ' KB'; } @@ -268,14 +268,14 @@ class quota_lib { if($emails[$i]['quota'] == 0){ $emails[$i]['quota'] = $app->lng('unlimited'); } else { - $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576, 4).' MB'; + $emails[$i]['quota'] = round($emails[$i]['quota'] / 1048576, 1).' MB'; } if($emails[$i]['used'] < 1544000) { - $emails[$i]['used'] = round($emails[$i]['used'] / 1024, 4).' KB'; + $emails[$i]['used'] = round($emails[$i]['used'] / 1024, 1).' KB'; } else { - $emails[$i]['used'] = round($emails[$i]['used'] / 1048576, 4).' MB'; + $emails[$i]['used'] = round($emails[$i]['used'] / 1048576, 1).' MB'; } } } @@ -334,9 +334,9 @@ class quota_lib { if($databases[$i]['used'] < 1544000) { - $databases[$i]['used'] = round($databases[$i]['used'] / 1024, 4).' KB'; + $databases[$i]['used'] = round($databases[$i]['used'] / 1024, 1).' KB'; } else { - $databases[$i]['used'] = round($databases[$i]['used'] / 1048576, 4).' MB'; + $databases[$i]['used'] = round($databases[$i]['used'] / 1048576, 1).' MB'; } } } -- GitLab From e908814c1ca0402d55ba3ef1e2cf5cb3a0eb519d Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 20 Oct 2018 21:55:25 +0200 Subject: [PATCH 249/310] Make the debug log more specific --- server/plugins-available/shelluser_jailkit_plugin.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/server/plugins-available/shelluser_jailkit_plugin.inc.php b/server/plugins-available/shelluser_jailkit_plugin.inc.php index 9a29a10a6..147d39d57 100755 --- a/server/plugins-available/shelluser_jailkit_plugin.inc.php +++ b/server/plugins-available/shelluser_jailkit_plugin.inc.php @@ -131,10 +131,11 @@ class shelluser_jailkit_plugin { $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 { + $app->log("Jailkit Plugin -> insert username:".$data['new']['username']. "skipped, Jailkit not selected", LOGLEVEL_DEBUG); } - $app->log("Jailkit Plugin -> insert username:".$data['new']['username'], LOGLEVEL_DEBUG); - } else { $app->log("Jailkit Plugin -> insert username:".$data['new']['username']." skipped, the user does not exist.", LOGLEVEL_WARN); } -- GitLab From c890a9f0f7dbca4db18bb0460f822aac6dfe28a7 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Mon, 3 Dec 2018 13:48:25 +0100 Subject: [PATCH 250/310] Add README to indicate where to override these templates --- install/tpl/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 install/tpl/README.md diff --git a/install/tpl/README.md b/install/tpl/README.md new file mode 100644 index 000000000..cf75d789d --- /dev/null +++ b/install/tpl/README.md @@ -0,0 +1,4 @@ +Overriding templates +-------------------- + +Manually altered versions have to be put into `server/conf-custom/install/`, e.g. `/usr/local/ispconfig/server/conf-custom/install/` -- GitLab From 1543ba74b27cc7aa63993ad9fd8c49915ea9b9ec Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 12 Dec 2018 14:02:24 +0100 Subject: [PATCH 251/310] - fixed autoresponder datetime validation in remote API --- interface/lib/classes/validate_autoresponder.inc.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/lib/classes/validate_autoresponder.inc.php b/interface/lib/classes/validate_autoresponder.inc.php index 98d49fdf6..8fefa33b3 100755 --- a/interface/lib/classes/validate_autoresponder.inc.php +++ b/interface/lib/classes/validate_autoresponder.inc.php @@ -52,8 +52,9 @@ class validate_autoresponder extends validate_datetime //$start_date = $app->tform_actions->dataRecord['autoresponder_start_date']; // Parse date - $start_date_array = date_parse_from_format($app->lng('conf_format_datetime'),$start_date); - $end_date_array = date_parse_from_format($app->lng('conf_format_datetime'),$field_value); + $datetimeformat = (isset($app->remoting_lib) ? $app->remoting_lib->datetimeformat : $app->tform->datetimeformat); + $start_date_array = date_parse_from_format($datetimeformat,$start_date); + $end_date_array = date_parse_from_format($datetimeformat,$field_value); //calculate timestamps $start_date_tstamp = mktime($start_date_array['hour'], $start_date_array['minute'], $start_date_array['second'], $start_date_array['month'], $start_date_array['day'], $start_date_array['year']); -- GitLab From 9145f9d3b8c8661c5164fe227426d6f3308c1702 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 12 Dec 2018 15:09:41 +0100 Subject: [PATCH 252/310] - added rspamd neural network config --- install/lib/installer_base.lib.php | 12 ++++++++ install/tpl/rspamd_neural.conf.master | 31 +++++++++++++++++++++ install/tpl/rspamd_neural_group.conf.master | 18 ++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 install/tpl/rspamd_neural.conf.master create mode 100644 install/tpl/rspamd_neural_group.conf.master diff --git a/install/lib/installer_base.lib.php b/install/lib/installer_base.lib.php index 70e5bbf10..57df2702e 100644 --- a/install/lib/installer_base.lib.php +++ b/install/lib/installer_base.lib.php @@ -1337,6 +1337,18 @@ class installer_base { exec('cp tpl/rspamd_options.inc.master /etc/rspamd/local.d/options.inc'); } + if(file_exists($conf['ispconfig_install_dir'].'/server/conf-custom/install/rspamd_neural.conf.master')) { + exec('cp '.$conf['ispconfig_install_dir'].'/server/conf-custom/install/rspamd_neural.conf.master /etc/rspamd/local.d/neural.conf'); + } else { + exec('cp tpl/rspamd_neural.conf.master /etc/rspamd/local.d/neural.conf'); + } + + if(file_exists($conf['ispconfig_install_dir'].'/server/conf-custom/install/rspamd_neural_group.conf.master')) { + exec('cp '.$conf['ispconfig_install_dir'].'/server/conf-custom/install/rspamd_neural_group.conf.master /etc/rspamd/local.d/neural_group.conf'); + } else { + exec('cp tpl/rspamd_neural_group.conf.master /etc/rspamd/local.d/neural_group.conf'); + } + exec('chmod a+r /etc/rspamd/local.d/* /etc/rspamd/override.d/*'); $tpl = new tpl(); diff --git a/install/tpl/rspamd_neural.conf.master b/install/tpl/rspamd_neural.conf.master new file mode 100644 index 000000000..64b0fa871 --- /dev/null +++ b/install/tpl/rspamd_neural.conf.master @@ -0,0 +1,31 @@ +servers = 127.0.0.1:6379; +enabled = true; + +rules { + "LONG" { + train { + max_trains = 5000; + max_usages = 200; + max_iterations = 25; + learning_rate = 0.01, + spam_score = 8; + ham_score = -2; + } + symbol_spam = "NEURAL_SPAM_LONG"; + symbol_ham = "NEURAL_HAM_LONG"; + ann_expire = 100d; + } + "SHORT" { + train { + max_trains = 100; + max_usages = 2; + max_iterations = 25; + learning_rate = 0.01, + spam_score = 8; + ham_score = -2; + } + symbol_spam = "NEURAL_SPAM_SHORT"; + symbol_ham = "NEURAL_HAM_SHORT"; + ann_expire = 1d; + } +} \ No newline at end of file diff --git a/install/tpl/rspamd_neural_group.conf.master b/install/tpl/rspamd_neural_group.conf.master new file mode 100644 index 000000000..c4f59c52e --- /dev/null +++ b/install/tpl/rspamd_neural_group.conf.master @@ -0,0 +1,18 @@ +symbols = { + "NEURAL_SPAM_LONG" { + weight = 3.0; # sample weight + description = "Neural network spam (long)"; + } + "NEURAL_HAM_LONG" { + weight = -3.0; # sample weight + description = "Neural network ham (long)"; + } + "NEURAL_SPAM_SHORT" { + weight = 2.0; # sample weight + description = "Neural network spam (short)"; + } + "NEURAL_HAM_SHORT" { + weight = -1.0; # sample weight + description = "Neural network ham (short)"; + } +} -- GitLab From 68effaea315c9d1ef952b85071ee2db2eb388ad3 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Wed, 12 Dec 2018 17:55:33 +0100 Subject: [PATCH 253/310] Fixed #5167 DKIM public key for subdomain not saved in dns --- interface/web/mail/mail_domain_edit.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index d7d6ea4c6..645d1fa03 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -312,7 +312,11 @@ class page_action extends tform_actions { //* create dns-record with dkim-values if the zone exists if ( $this->dataRecord['active'] == 'y' && $this->dataRecord['dkim'] == 'y' ) { - $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + $soaDomain = $this->dataRecord['domain'].'.'; + while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); + $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + } if ( isset($soa) && !empty($soa) ) $this->update_dns($this->dataRecord, $soa); } @@ -437,7 +441,10 @@ class page_action extends tform_actions { $selector = @($this->dataRecord['dkim_selector'] != $this->oldDataRecord['dkim_selector']) ? true : false; $dkim_private = @($this->dataRecord['dkim_private'] != $this->oldDataRecord['dkim_private']) ? true : false; - $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $this->dataRecord['domain'].'.'); + while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { + $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); + $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + } if ( ($selector || $dkim_private || $dkim_active) && $dkim_active ) //* create a new record only if the dns-zone exists -- GitLab From 57b164e06074687838a422326fb844762f4ca7f2 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Wed, 12 Dec 2018 18:44:41 +0100 Subject: [PATCH 254/310] Fixed issue with creation of duplicate DKIM DNS records when mail domain is saved. --- interface/web/mail/mail_domain_edit.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index 645d1fa03..e39de91e0 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -440,7 +440,8 @@ class page_action extends tform_actions { $dkim_active = @($this->dataRecord['dkim'] == 'y') ? true : false; $selector = @($this->dataRecord['dkim_selector'] != $this->oldDataRecord['dkim_selector']) ? true : false; $dkim_private = @($this->dataRecord['dkim_private'] != $this->oldDataRecord['dkim_private']) ? true : false; - + + $soaDomain = $this->dataRecord['domain'].'.'; while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); $soaDomain = preg_replace("/^\w+\./","",$soaDomain); @@ -474,10 +475,12 @@ class page_action extends tform_actions { // purge old rr-record(s) $sql = "SELECT * FROM dns_rr WHERE name LIKE ? AND data LIKE 'v=DKIM1%' AND " . $app->tform->getAuthSQL('r') . " ORDER BY serial DESC"; $rec = $app->db->queryAllRecords($sql, '%._domainkey.'.$dataRecord['domain'].'.'); - if (is_array($rec[1])) { - for ($i=1; $i < count($rec); ++$i) - $app->db->datalogDelete('dns_rr', 'id', $rec[$i]['id']); + if(is_array($rec)) { + foreach($rec as $r) { + $app->db->datalogDelete('dns_rr', 'id', $r['id']); + } } + // also delete a dsn-records with same selector $sql = "SELECT * from dns_rr WHERE name ? AND data LIKE 'v=DKIM1%' AND " . $app->tform->getAuthSQL('r'); $rec = $app->db->queryAllRecords($sql, '._domainkey.'.$dataRecord['dkim_selector'].'.', $dataRecord['domain']); -- GitLab From 89e31e52ab2be102dc1cd7d0c57e81163fde9d30 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:23:48 +0100 Subject: [PATCH 255/310] - improved mail sending library, contributed by Timme Hosting --- helper_scripts/test_mailqueue.php | 45 ++++++ install/sql/incremental/upd_0085.sql | 2 +- .../sql/incremental/upd_dev_collection.sql | 9 ++ install/sql/ispconfig3.sql | 15 ++ interface/lib/classes/ispcmail.inc.php | 137 ++++++++++++++---- .../cron.d/100-send_sys_mailqueue.inc.php | 77 ++++++++++ server/lib/classes/ispcmail.inc.php | 137 ++++++++++++++---- 7 files changed, 371 insertions(+), 51 deletions(-) create mode 100644 helper_scripts/test_mailqueue.php create mode 100644 server/lib/classes/cron.d/100-send_sys_mailqueue.inc.php diff --git a/helper_scripts/test_mailqueue.php b/helper_scripts/test_mailqueue.php new file mode 100644 index 000000000..0d5600b39 --- /dev/null +++ b/helper_scripts/test_mailqueue.php @@ -0,0 +1,45 @@ +auth->check_module_permissions('admin'); + +$app->uses('getconf,ispcmail'); +$mail_config = $app->getconf->get_global_config('mail'); +if($mail_config['smtp_enabled'] == 'y') { + $mail_config['use_smtp'] = true; + $app->ispcmail->setOptions($mail_config); +} + +$to = 't.heller@timmehosting.de'; +$subject = 'Test von ISPConfig-Mailqueue'; +$text = '123'."\n\n".date(DATE_RFC822)."\n\n".'SMTP: '.$mail_config['use_smtp']; +$from = 'ispconfig@thomas.timmeserver.de'; +$filepath = ''; +$filetype = 'application/pdf'; +$filename = ''; +$cc = ''; +$bcc = ''; +$from_name = 'ISPConfig'; + +$app->ispcmail->setSender($from, $from_name); +$app->ispcmail->setSubject($subject); +$app->ispcmail->setMailText($text); + +if($filepath != '') { + if(!file_exists($filepath)) $app->error("Mail attachement does not exist ".$filepath); + $app->ispcmail->readAttachFile($filepath); +} + +if($cc != '') $app->ispcmail->setHeader('Cc', $cc); +if($bcc != '') $app->ispcmail->setHeader('Bcc', $bcc); + +$app->ispcmail->send($to); +$app->ispcmail->finish(); + +echo $text; + diff --git a/install/sql/incremental/upd_0085.sql b/install/sql/incremental/upd_0085.sql index 1291262ee..967643683 100644 --- a/install/sql/incremental/upd_0085.sql +++ b/install/sql/incremental/upd_0085.sql @@ -18,4 +18,4 @@ ALTER TABLE `dns_rr` CHANGE `data` `data` TEXT NOT NULL; ALTER TABLE `web_database` CHANGE `database_quota` `database_quota` INT(11) NULL DEFAULT NULL; ALTER TABLE `web_domain` ADD `log_retention` INT NOT NULL DEFAULT '30' ; ALTER TABLE spamfilter_policy CHANGE spam_tag_level spam_tag_level DECIMAL(5,2) NULL DEFAULT NULL, CHANGE spam_tag2_level spam_tag2_level DECIMAL(5,2) NULL DEFAULT NULL, CHANGE spam_kill_level spam_kill_level DECIMAL(5,2) NULL DEFAULT NULL, CHANGE spam_dsn_cutoff_level spam_dsn_cutoff_level DECIMAL(5,2) NULL DEFAULT NULL, CHANGE spam_quarantine_cutoff_level spam_quarantine_cutoff_level DECIMAL(5,2) NULL DEFAULT NULL; -UPDATE `web_database` as d LEFT JOIN `web_domain` as w ON (w.domain_id = d.parent_domain_id) SET d.parent_domain_id = 0 WHERE w.domain_id IS NULL AND d.parent_domain_id != 0 AND (SELECT EXISTS(SELECT * FROM web_domain)); \ No newline at end of file +UPDATE `web_database` as d LEFT JOIN `web_domain` as w ON (w.domain_id = d.parent_domain_id) SET d.parent_domain_id = 0 WHERE w.domain_id IS NULL AND d.parent_domain_id != 0 AND (SELECT EXISTS(SELECT * FROM web_domain)); diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index dc5d4bb45..68228ca52 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -151,3 +151,12 @@ CREATE TABLE IF NOT EXISTS `addons` ( PRIMARY KEY (`addon_id`), UNIQUE KEY `ident` (`addon_ident`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; + +CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `from` varchar(255) NOT NULL DEFAULT '', + `recipients` text NOT NULL, + `mail_content` mediumblob NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 1b168b44b..9f3001346 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1585,6 +1585,21 @@ CREATE TABLE `sys_log` ( -- -------------------------------------------------------- +-- +-- Table structure for table `sys_mailqueue` +-- + +CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `from` varchar(255) NOT NULL DEFAULT '', + `recipients` text NOT NULL, + `mail_content` mediumblob NOT NULL, + `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + -- -- Table structure for table `sys_remoteaction` -- diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php index b818e1e44..a3256b5ff 100644 --- a/interface/lib/classes/ispcmail.inc.php +++ b/interface/lib/classes/ispcmail.inc.php @@ -744,32 +744,22 @@ class ispcmail { } if($this->use_smtp == true) { - if(!$this->_logged_in || !$this->_smtp_conn) { - $result = $this->_smtp_login(); - if(!$result) return false; - } $bcc_cc_sent = false; foreach($recipients as $recipname => $recip) { - if($this->_sent_mails >= $this->smtp_max_mails) { - // close connection to smtp and reconnect - $this->_sent_mails = 0; - $this->_smtp_close(); - $result = $this->_smtp_login(); - if(!$result) return false; - } - $this->_sent_mails += 1; + // Build mail headers, content etc. + + $m_recipients = array(); + $m_mail_content = ''; $recipname = trim(str_replace('"', '', $recipname)); $recip = $this->_encodeHeader($recip, $this->mail_charset); $recipname = $this->_encodeHeader($recipname, $this->mail_charset); //Email From - fputs($this->_smtp_conn, 'MAIL FROM: <' . $this->_mail_sender . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_from = $this->_mail_sender; //Email To - fputs($this->_smtp_conn, 'RCPT TO: <' . $recip . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_recipients[] = $recip; if($bcc_cc_sent == false) { $add_recips = array(); @@ -777,17 +767,12 @@ class ispcmail { if($this->getHeader('Bcc') != '') $add_recips = array_merge($add_recips, $this->_extract_names($this->getHeader('Bcc'))); foreach($add_recips as $add_recip) { if(!$add_recip['mail']) continue; - fputs($this->_smtp_conn, 'RCPT TO: <' . $this->_encodeHeader($add_recip['mail'], $this->mail_charset) . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_recipients[] = $this->_encodeHeader($add_recip['mail'], $this->mail_charset); } unset($add_recips); $bcc_cc_sent = true; } - //The Email - fputs($this->_smtp_conn, 'DATA' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); - //Construct Headers if($recipname && !is_numeric($recipname)) $this->setHeader('To', $recipname . ' <' . $recip . '>'); else $this->setHeader('To', $recip); @@ -797,10 +782,32 @@ class ispcmail { if($this->getHeader('Cc') != '') $mail_content .= 'Cc: ' . $this->_encodeHeader($this->getHeader('Cc'), $this->mail_charset) . $this->_crlf; $mail_content .= implode($this->_crlf, $headers) . $this->_crlf . ($this->_is_signed == false ? $this->_crlf : '') . $this->body; - fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_mail_content = $mail_content; + + // Attempt SMTP login: + + if(!$this->_logged_in || !$this->_smtp_conn) { + $result = $this->_smtp_login(); + } + + if($this->_sent_mails >= $this->smtp_max_mails) { + // close connection to smtp and reconnect + $this->_sent_mails = 0; + $this->_smtp_close(); + $result = $this->_smtp_login(); + } + $this->_sent_mails += 1; + + // Send mail or queue it + + if ($result) { + $this->send_smtp($m_from, $m_recipients, $m_mail_content); + } else { + $this->add_to_queue($m_from, $m_recipients, $m_mail_content); + } + + // hopefully message was correctly sent or queued now - // hopefully message was correctly sent now $result = true; } } else { @@ -828,7 +835,87 @@ class ispcmail { return $result; } + /** + * Send all mails in queue (usually called from cron) + */ + public function send_queue() { + global $app; + + $mails = $app->db->queryAllRecords('SELECT * FROM sys_mailqueue'); + + if (is_array($mails)) { + foreach ($mails as $mail) { + // Open SMTP connections if not open: + + if(!$this->_logged_in || !$this->_smtp_conn) { + $result = $this->_smtp_login(); + } + + if($this->_sent_mails >= $this->smtp_max_mails) { + // close connection to smtp and reconnect + $this->_sent_mails = 0; + $this->_smtp_close(); + $result = $this->_smtp_login(); + } + $this->_sent_mails += 1; + + if (!$result) { + return false; + } + + // Send mail: + + $id = $mail['id']; + $from = $mail['from']; + $recipients = explode("\n", $mail['recipients']); + $mail_content = $mail['mail_content']; + + $this->send_smtp($from, $recipients, $mail_content); + + // Delete from queue: + + $app->db->query('DELETE FROM sys_mailqueue WHERE id = ?', $id); + } + } + } + + /** + * Send mail via SMTP + */ + private function send_smtp($from, $recipients, $mail_content) { + // from: + + fputs($this->_smtp_conn, 'MAIL FROM: <' . $from . '>' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + // recipients (To, Cc or Bcc): + + foreach ($recipients as $recipient) { + fputs($this->_smtp_conn, 'RCPT TO: <' . $recipient . '>' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + } + + // mail content: + fputs($this->_smtp_conn, 'DATA' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + // hopefully message was correctly sent now + $result = true; + + return $result; + } + + /** + * Add mail to queue for sending later + */ + private function add_to_queue($from, $recipients, $mail_content) { + global $app; + $app->db->query('INSERT INTO `sys_mailqueue` (`from`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); + } /** * Close mail connections diff --git a/server/lib/classes/cron.d/100-send_sys_mailqueue.inc.php b/server/lib/classes/cron.d/100-send_sys_mailqueue.inc.php new file mode 100644 index 000000000..2ab46dfc8 --- /dev/null +++ b/server/lib/classes/cron.d/100-send_sys_mailqueue.inc.php @@ -0,0 +1,77 @@ +uses('getconf,ispcmail'); + + $mail_config = $app->getconf->get_global_config('mail'); + if($mail_config['smtp_enabled'] == 'y') { + $mail_config['use_smtp'] = true; + $app->ispcmail->setOptions($mail_config); + + // Mail queue is supported only with SMTP... + $app->ispcmail->send_queue(); + } + + parent::onRunJob(); + } + + /* this function is optional if it contains no custom code */ + public function onAfterRun() { + global $app; + + parent::onAfterRun(); + } + +} + +?> diff --git a/server/lib/classes/ispcmail.inc.php b/server/lib/classes/ispcmail.inc.php index 305b39f35..93d7b6069 100644 --- a/server/lib/classes/ispcmail.inc.php +++ b/server/lib/classes/ispcmail.inc.php @@ -740,32 +740,22 @@ class ispcmail { } if($this->use_smtp == true) { - if(!$this->_logged_in || !$this->_smtp_conn) { - $result = $this->_smtp_login(); - if(!$result) return false; - } $bcc_cc_sent = false; foreach($recipients as $recipname => $recip) { - if($this->_sent_mails >= $this->smtp_max_mails) { - // close connection to smtp and reconnect - $this->_sent_mails = 0; - $this->_smtp_close(); - $result = $this->_smtp_login(); - if(!$result) return false; - } - $this->_sent_mails += 1; + // Build mail headers, content etc. + + $m_recipients = array(); + $m_mail_content = ''; $recipname = trim(str_replace('"', '', $recipname)); $recip = $this->_encodeHeader($recip, $this->mail_charset); $recipname = $this->_encodeHeader($recipname, $this->mail_charset); //Email From - fputs($this->_smtp_conn, 'MAIL FROM: <' . $this->_mail_sender . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_from = $this->_mail_sender; //Email To - fputs($this->_smtp_conn, 'RCPT TO: <' . $recip . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_recipients[] = $recip; if($bcc_cc_sent == false) { $add_recips = array(); @@ -773,17 +763,12 @@ class ispcmail { if($this->getHeader('Bcc') != '') $add_recips = array_merge($add_recips, $this->_extract_names($this->getHeader('Bcc'))); foreach($add_recips as $add_recip) { if(!$add_recip['mail']) continue; - fputs($this->_smtp_conn, 'RCPT TO: <' . $this->_encodeHeader($add_recip['mail'], $this->mail_charset) . '>' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_recipients[] = $this->_encodeHeader($add_recip['mail'], $this->mail_charset); } unset($add_recips); $bcc_cc_sent = true; } - //The Email - fputs($this->_smtp_conn, 'DATA' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); - //Construct Headers if($recipname && !is_numeric($recipname)) $this->setHeader('To', $recipname . ' <' . $recip . '>'); else $this->setHeader('To', $recip); @@ -793,10 +778,32 @@ class ispcmail { if($this->getHeader('Cc') != '') $mail_content .= 'Cc: ' . $this->_encodeHeader($this->getHeader('Cc'), $this->mail_charset) . $this->_crlf; $mail_content .= implode($this->_crlf, $headers) . $this->_crlf . ($this->_is_signed == false ? $this->_crlf : '') . $this->body; - fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf); - $response = fgets($this->_smtp_conn, 515); + $m_mail_content = $mail_content; + + // Attempt SMTP login: + + if(!$this->_logged_in || !$this->_smtp_conn) { + $result = $this->_smtp_login(); + } + + if($this->_sent_mails >= $this->smtp_max_mails) { + // close connection to smtp and reconnect + $this->_sent_mails = 0; + $this->_smtp_close(); + $result = $this->_smtp_login(); + } + $this->_sent_mails += 1; + + // Send mail or queue it + + if ($result) { + $this->send_smtp($m_from, $m_recipients, $m_mail_content); + } else { + $this->add_to_queue($m_from, $m_recipients, $m_mail_content); + } + + // hopefully message was correctly sent or queued now - // hopefully message was correctly sent now $result = true; } } else { @@ -824,7 +831,87 @@ class ispcmail { return $result; } + /** + * Send all mails in queue (usually called from cron) + */ + public function send_queue() { + global $app; + + $mails = $app->db->queryAllRecords('SELECT * FROM sys_mailqueue'); + + if (is_array($mails)) { + foreach ($mails as $mail) { + // Open SMTP connections if not open: + + if(!$this->_logged_in || !$this->_smtp_conn) { + $result = $this->_smtp_login(); + } + + if($this->_sent_mails >= $this->smtp_max_mails) { + // close connection to smtp and reconnect + $this->_sent_mails = 0; + $this->_smtp_close(); + $result = $this->_smtp_login(); + } + $this->_sent_mails += 1; + + if (!$result) { + return false; + } + + // Send mail: + + $id = $mail['id']; + $from = $mail['from']; + $recipients = explode("\n", $mail['recipients']); + $mail_content = $mail['mail_content']; + + $this->send_smtp($from, $recipients, $mail_content); + + // Delete from queue: + + $app->db->query('DELETE FROM sys_mailqueue WHERE id = ?', $id); + } + } + } + + /** + * Send mail via SMTP + */ + private function send_smtp($from, $recipients, $mail_content) { + // from: + + fputs($this->_smtp_conn, 'MAIL FROM: <' . $from . '>' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + // recipients (To, Cc or Bcc): + + foreach ($recipients as $recipient) { + fputs($this->_smtp_conn, 'RCPT TO: <' . $recipient . '>' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + } + + // mail content: + fputs($this->_smtp_conn, 'DATA' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf); + $response = fgets($this->_smtp_conn, 515); + + // hopefully message was correctly sent now + $result = true; + + return $result; + } + + /** + * Add mail to queue for sending later + */ + private function add_to_queue($from, $recipients, $mail_content) { + global $app; + $app->db->query('INSERT INTO `sys_mailqueue` (`from`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); + } /** * Close mail connections -- GitLab From acf3c470ac31cd15272c6ab7c4a4fd7ab8503672 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:39:28 +0100 Subject: [PATCH 256/310] - improved jailkit program listing (textarea instead of input field) --- install/tpl/server.ini.master | 2 +- interface/web/admin/form/server_config.tform.php | 4 ++-- interface/web/admin/server_config_edit.php | 13 +++++++++++++ .../admin/templates/server_config_jailkit_edit.htm | 4 ++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 68f786bf5..8fc724469 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -137,7 +137,7 @@ fastcgi_bin=/usr/bin/php-cgi [jailkit] jailkit_chroot_home=/home/[username] jailkit_chroot_app_sections=basicshell editors extendedshell netutils ssh sftp scp groups jk_lsh -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_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 jailkit_chroot_cron_programs=/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php [vlogger] diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index a5eb6dc06..6bbfd7985 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -1691,13 +1691,13 @@ $form["tabs"]['jailkit'] = array( 'maxlength' => '1000' ), 'jailkit_chroot_app_programs' => array( - 'datatype' => 'VARCHAR', + 'datatype' => 'TEXT', 'formtype' => 'TEXT', 'default' => '', 'validators' => array( 0 => array('type' => 'NOTEMPTY', 'errmsg' => 'jailkit_chroot_app_programs_error_empty'), 1 => array ( 'type' => 'REGEX', - 'regex' => '/^[a-zA-Z0-9\*\.\-\_\/\ ]{1,}$/', + 'regex' => '/^[a-zA-Z0-9\*\.\-\_\/\ \r\n]{1,}$/', 'errmsg'=> 'jailkit_chroot_app_programs_error_regex'), ), 'value' => '', diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index 9c344e074..7b3237d6e 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -80,6 +80,8 @@ class page_action extends tform_actions { $this->dataRecord = $app->getconf->get_server_config($server_id, $section); + $this->dataRecord['jailkit_chroot_app_programs'] = str_replace(' ', "\r\n", $this->dataRecord['jailkit_chroot_app_programs']); + if($section == 'mail'){ $server_config = $app->getconf->get_server_config($server_id, 'server'); $rspamd_url = 'https://'.$server_config['hostname'].':8081/rspamd/'; @@ -122,6 +124,17 @@ class page_action extends tform_actions { } } + if(isset($this->dataRecord['jailkit_chroot_app_programs'])) { + $jailkit_chroot_app_programs = explode("\r\n", $this->dataRecord['jailkit_chroot_app_programs']); + $jailkit_chroot_app_programs = array_unique($jailkit_chroot_app_programs); + foreach ($jailkit_chroot_app_programs as $key => $value) { + if (trim($value)=='') { + unset($jailkit_chroot_app_programs[$key]); + } + } + $this->dataRecord['jailkit_chroot_app_programs'] = implode(' ', $jailkit_chroot_app_programs); + } + if($app->tform->errorMessage == '') { $server_config_array[$section] = $app->tform->encode($this->dataRecord, $section); $server_config_str = $app->ini_parser->get_ini_string($server_config_array); diff --git a/interface/web/admin/templates/server_config_jailkit_edit.htm b/interface/web/admin/templates/server_config_jailkit_edit.htm index b7a749147..47416797a 100644 --- a/interface/web/admin/templates/server_config_jailkit_edit.htm +++ b/interface/web/admin/templates/server_config_jailkit_edit.htm @@ -13,7 +13,7 @@
-
+
@@ -24,4 +24,4 @@
-
+ \ No newline at end of file -- GitLab From 0316d01e81d9d1376059431f51c56519d91f2de9 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:45:59 +0100 Subject: [PATCH 257/310] - added automatic jailkit update, contributed by Timme Hosting --- install/sql/incremental/upd_0086.sql | 2 +- .../sql/incremental/upd_dev_collection.sql | 2 + install/sql/ispconfig3.sql | 1 + .../web/sites/form/web_vhost_domain.tform.php | 6 + .../sites/lib/lang/de_web_vhost_domain.lng | 2 +- .../sites/lib/lang/en_web_vhost_domain.lng | 2 +- .../templates/web_vhost_domain_advanced.htm | 6 + .../lib/classes/cron.d/500-jkupdate.inc.php | 137 ++++++++++++++++++ 8 files changed, 155 insertions(+), 3 deletions(-) create mode 100644 server/lib/classes/cron.d/500-jkupdate.inc.php diff --git a/install/sql/incremental/upd_0086.sql b/install/sql/incremental/upd_0086.sql index 563b2153c..fc1d0c38d 100644 --- a/install/sql/incremental/upd_0086.sql +++ b/install/sql/incremental/upd_0086.sql @@ -2,4 +2,4 @@ ALTER TABLE `web_domain` ADD COLUMN `ssl_letsencrypt_exclude` enum('n','y') NOT ALTER TABLE `remote_user` ADD `remote_access` ENUM('y','n') NOT NULL DEFAULT 'y' AFTER `remote_password`; ALTER TABLE `remote_user` ADD `remote_ips` TEXT AFTER `remote_access`; ALTER TABLE `server_php` ADD `active` enum('y','n') NOT NULL DEFAULT 'y' AFTER `php_fpm_pool_dir`; -ALTER TABLE `web_domain` CHANGE `log_retention` `log_retention` INT(11) NOT NULL DEFAULT '10'; \ No newline at end of file +ALTER TABLE `web_domain` CHANGE `log_retention` `log_retention` INT(11) NOT NULL DEFAULT '10'; diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 68228ca52..bda812f68 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -160,3 +160,5 @@ CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; + +ALTER TABLE `web_domain` ADD `jailkit_jkupdate_cron` enum('n','y') NOT NULL DEFAULT 'y' AFTER `custom_php_ini`; \ No newline at end of file diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 9f3001346..cf0586b61 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1850,6 +1850,7 @@ CREATE TABLE `web_domain` ( `pm_max_requests` int(11) NOT NULL DEFAULT '0', `php_open_basedir` mediumtext, `custom_php_ini` mediumtext, + `jailkit_jkupdate_cron` enum('n','y') NOT NULL DEFAULT 'y', `backup_interval` VARCHAR( 255 ) NOT NULL DEFAULT 'none', `backup_copies` INT NOT NULL DEFAULT '1', `backup_excludes` mediumtext, diff --git a/interface/web/sites/form/web_vhost_domain.tform.php b/interface/web/sites/form/web_vhost_domain.tform.php index ad1d4ff55..84de25dee 100644 --- a/interface/web/sites/form/web_vhost_domain.tform.php +++ b/interface/web/sites/form/web_vhost_domain.tform.php @@ -970,6 +970,12 @@ if($_SESSION["s"]["user"]["typ"] == 'admin' 'value' => '', 'width' => '4', 'maxlength' => '4' + ), + 'jailkit_jkupdate_cron' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'y', + 'value' => array(0 => 'n', 1 => 'y') ) //################################# // ENDE Datatable fields 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 ecfb1994c..674f31157 100644 --- a/interface/web/sites/lib/lang/de_web_vhost_domain.lng +++ b/interface/web/sites/lib/lang/de_web_vhost_domain.lng @@ -155,4 +155,4 @@ $wb['error_server_change_not_possible'] = 'Der Server kann nicht geändert werde $wb['enable_pagespeed_txt'] = 'Enable PageSpeed'; $wb['log_retention_txt'] = 'Log-Dateien Aufbewahrungszeit'; $wb['log_retention_error_regex'] = 'Aufbewahrungszeit in Tagen (Erlaubte Werte: min. 0 - max. 9999)'; -?> +$wb['jailkit_jkupdate_cron_txt'] = 'Automatisches jkupdate'; \ No newline at end of file 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 17d47ed46..85096f4dc 100644 --- a/interface/web/sites/lib/lang/en_web_vhost_domain.lng +++ b/interface/web/sites/lib/lang/en_web_vhost_domain.lng @@ -161,4 +161,4 @@ $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Pleas $wb['error_server_change_not_possible'] = 'The server cannot be changed.'; $wb['log_retention_txt'] = 'Logfiles retention time'; $wb['log_retention_error_regex'] = 'Retention time in days (allowed values: min. 0 - max. 9999)'; -?> +$wb['jailkit_jkupdate_cron_txt'] = 'Automate jkupdate'; \ No newline at end of file diff --git a/interface/web/sites/templates/web_vhost_domain_advanced.htm b/interface/web/sites/templates/web_vhost_domain_advanced.htm index 322748257..d7ed5a53c 100644 --- a/interface/web/sites/templates/web_vhost_domain_advanced.htm +++ b/interface/web/sites/templates/web_vhost_domain_advanced.htm @@ -101,6 +101,12 @@ {tmpl_var name="available_php_directive_snippets_txt"}

 {tmpl_var name="php_directive_snippets_txt"} +
+ +
+ {tmpl_var name='jailkit_jkupdate_cron'} +
+
diff --git a/server/lib/classes/cron.d/500-jkupdate.inc.php b/server/lib/classes/cron.d/500-jkupdate.inc.php new file mode 100644 index 000000000..2eaacdbcf --- /dev/null +++ b/server/lib/classes/cron.d/500-jkupdate.inc.php @@ -0,0 +1,137 @@ +uses('getconf'); + $jailkit_conf = $app->getconf->get_server_config($conf['server_id'], 'jailkit'); + $jailkit_programs = explode(' ', $jailkit_conf['jailkit_chroot_app_programs']); + + $sites = $app->db->queryAllRecords('SELECT domain_id, document_root FROM web_domain WHERE jailkit_jkupdate_cron = \'y\''); + + foreach($sites as $site) { + $users = $app->db->queryOneRecord('SELECT COUNT(*) AS user_count FROM shell_user WHERE parent_domain_id = ? AND active=\'y\' AND chroot=\'jailkit\'', $site['domain_id']); + $crons = $app->db->queryOneRecord('SELECT COUNT(*) AS cron_count FROM cron WHERE parent_domain_id = ? AND active=\'y\' AND type=\'chrooted\'', $site['domain_id']); + if ($users['user_count'] > 0 || $crons['cron_count'] > 0) { + if (!is_dir($site['document_root'])) { + return; + } + + $app->log('Running jailkit updates for '.$site['document_root']); + + $this->run_jk_update($site['document_root']); + $this->run_jk_cp($site['document_root'], $jailkit_programs); + } + } + + parent::onRunJob(); + } + + private function run_jk_update($document_root) { + global $app; + + $return_var = $this->exec_log('/usr/sbin/jk_update -j '.escapeshellarg($document_root)); + + if ($return_var > 0) { + $app->log('jk_update failed with -j, trying again without -j', LOGLEVEL_DEBUG); + $return_var = $this->exec_log('/usr/sbin/jk_update '.escapeshellarg($document_root)); + + if ($return_var > 0) { + $app->log('jk_update failed (with and without -j parameter)', LOGLEVEL_WARN); + } + } + } + + private function run_jk_cp($document_root, $programs) { + global $app; + + foreach($programs as $program) { + if (!file_exists($program)) { + continue; + } + + $return_var = $this->exec_log('/usr/sbin/jk_cp '.escapeshellarg($document_root).' '.escapeshellarg($program)); + + if ($return_var > 0) { + $app->log('jk_cp failed with -j, trying again with -j', LOGLEVEL_DEBUG); + $return_var = $this->exec_log('/usr/sbin/jk_cp '.escapeshellarg($document_root).' '.escapeshellarg($program)); + + if ($return_var > 0) { + $app->log('jk_cp failed (without and with -j parameter)', LOGLEVEL_WARN); + } + } + } + } + + private function exec_log($cmd) { + global $app; + + $app->log("Running $cmd", LOGLEVEL_DEBUG); + + exec($cmd, $output, $return_var); + + if (count($output) > 0) { + $app->log("Output:\n" . implode("\n", $output), LOGLEVEL_DEBUG); + } + + return $return_var; + } + + /* this function is optional if it contains no custom code */ + public function onAfterRun() { + global $app; + + parent::onAfterRun(); + } + +} + +?> -- GitLab From fb42a376593a4ecb31039d3bcd5460e086976bf4 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:49:05 +0100 Subject: [PATCH 258/310] - patch for mail lib improvement from previous commits --- install/sql/incremental/upd_dev_collection.sql | 2 +- install/sql/ispconfig3.sql | 2 +- interface/lib/classes/ispcmail.inc.php | 4 ++-- server/lib/classes/ispcmail.inc.php | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index bda812f68..4fc891f8e 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -154,7 +154,7 @@ CREATE TABLE IF NOT EXISTS `addons` ( CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `from` varchar(255) NOT NULL DEFAULT '', + `from_address` varchar(255) NOT NULL DEFAULT '', `recipients` text NOT NULL, `mail_content` mediumblob NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index cf0586b61..c3d17421d 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1591,7 +1591,7 @@ CREATE TABLE `sys_log` ( CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `from` varchar(255) NOT NULL DEFAULT '', + `from_address` varchar(255) NOT NULL DEFAULT '', `recipients` text NOT NULL, `mail_content` mediumblob NOT NULL, `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php index a3256b5ff..209cb5bd4 100644 --- a/interface/lib/classes/ispcmail.inc.php +++ b/interface/lib/classes/ispcmail.inc.php @@ -866,7 +866,7 @@ class ispcmail { // Send mail: $id = $mail['id']; - $from = $mail['from']; + $from = $mail['from_address']; $recipients = explode("\n", $mail['recipients']); $mail_content = $mail['mail_content']; @@ -914,7 +914,7 @@ class ispcmail { */ private function add_to_queue($from, $recipients, $mail_content) { global $app; - $app->db->query('INSERT INTO `sys_mailqueue` (`from`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); + $app->db->query('INSERT INTO `sys_mailqueue` (`from_address`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); } /** diff --git a/server/lib/classes/ispcmail.inc.php b/server/lib/classes/ispcmail.inc.php index 93d7b6069..3ffabe8c4 100644 --- a/server/lib/classes/ispcmail.inc.php +++ b/server/lib/classes/ispcmail.inc.php @@ -862,7 +862,7 @@ class ispcmail { // Send mail: $id = $mail['id']; - $from = $mail['from']; + $from = $mail['from_address']; $recipients = explode("\n", $mail['recipients']); $mail_content = $mail['mail_content']; @@ -910,7 +910,7 @@ class ispcmail { */ private function add_to_queue($from, $recipients, $mail_content) { global $app; - $app->db->query('INSERT INTO `sys_mailqueue` (`from`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); + $app->db->query('INSERT INTO `sys_mailqueue` (`from_address`, `recipients`, `mail_content`) VALUES (?,?,?)', $from, implode("\n", $recipients), $mail_content); } /** -- GitLab From a0a45277b0ca7d8eaa0fe873b5dfcb55142abe23 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:49:50 +0100 Subject: [PATCH 259/310] - patch for jailkit programs edit --- interface/web/admin/server_config_edit.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index 7b3237d6e..add6c8493 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -125,7 +125,10 @@ class page_action extends tform_actions { } if(isset($this->dataRecord['jailkit_chroot_app_programs'])) { - $jailkit_chroot_app_programs = explode("\r\n", $this->dataRecord['jailkit_chroot_app_programs']); + $app->uses('file'); + $jailkit_chroot_app_programs = $this->dataRecord['jailkit_chroot_app_programs']; + $jailkit_chroot_app_programs = $app->file->unix_nl($jailkit_chroot_app_programs); + $jailkit_chroot_app_programs = explode("\n", $jailkit_chroot_app_programs); $jailkit_chroot_app_programs = array_unique($jailkit_chroot_app_programs); foreach ($jailkit_chroot_app_programs as $key => $value) { if (trim($value)=='') { -- GitLab From 818d002eb1ef08734c826fb3e52196ee6e56e1dd Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:56:43 +0100 Subject: [PATCH 260/310] - implemented datalog viewer and restore, contributed by Timme Hosting --- .../sql/incremental/upd_dev_collection.sql | 3 +- install/sql/ispconfig3.sql | 1 + interface/lib/classes/db_mysql.inc.php | 4 +- interface/lib/classes/finediff.inc.php | 752 ++++++++++++++++++ interface/web/login/index.php | 2 +- interface/web/monitor/dataloghistory_list.php | 54 ++ interface/web/monitor/dataloghistory_undo.php | 70 ++ interface/web/monitor/dataloghistory_view.php | 130 +++ interface/web/monitor/lib/lang/de.lng | 1 + .../lib/lang/de_dataloghistory_list.lng | 8 + .../lib/lang/de_dataloghistory_undo.lng | 6 + .../lib/lang/de_dataloghistory_view.lng | 26 + interface/web/monitor/lib/lang/en.lng | 1 + .../lib/lang/en_dataloghistory_list.lng | 8 + .../lib/lang/en_dataloghistory_undo.lng | 6 + .../lib/lang/en_dataloghistory_view.lng | 26 + interface/web/monitor/lib/module.conf.php | 5 + .../web/monitor/list/dataloghistory.list.php | 91 +++ .../monitor/templates/dataloghistory_list.htm | 54 ++ .../monitor/templates/dataloghistory_undo.htm | 17 + .../monitor/templates/dataloghistory_view.htm | 124 +++ .../default/assets/stylesheets/ispconfig.css | 13 + 22 files changed, 1398 insertions(+), 4 deletions(-) create mode 100644 interface/lib/classes/finediff.inc.php create mode 100644 interface/web/monitor/dataloghistory_list.php create mode 100644 interface/web/monitor/dataloghistory_undo.php create mode 100644 interface/web/monitor/dataloghistory_view.php create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_view.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_view.lng create mode 100644 interface/web/monitor/list/dataloghistory.list.php create mode 100644 interface/web/monitor/templates/dataloghistory_list.htm create mode 100644 interface/web/monitor/templates/dataloghistory_undo.htm create mode 100644 interface/web/monitor/templates/dataloghistory_view.htm diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 4fc891f8e..91488d846 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -161,4 +161,5 @@ CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; -ALTER TABLE `web_domain` ADD `jailkit_jkupdate_cron` enum('n','y') NOT NULL DEFAULT 'y' AFTER `custom_php_ini`; \ No newline at end of file +ALTER TABLE `web_domain` ADD `jailkit_jkupdate_cron` enum('n','y') NOT NULL DEFAULT 'y' AFTER `custom_php_ini`; +ALTER TABLE `sys_datalog` ADD `session_id` varchar(64) NOT NULL DEFAULT '' AFTER `error`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index c3d17421d..23df19732 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1491,6 +1491,7 @@ CREATE TABLE `sys_datalog` ( `data` longtext, `status` set('pending','ok','warning','error') NOT NULL default 'ok', `error` mediumtext, + `session_id` varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (`datalog_id`), KEY `server_id` (`server_id`,`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index b03ad5567..8443d106b 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -719,8 +719,8 @@ class db if($action == 'INSERT') $action = 'i'; if($action == 'UPDATE') $action = 'u'; if($action == 'DELETE') $action = 'd'; - $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES (?, ?, ?, ?, ?, ?, ?)"; - $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr); + $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data,session_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr, session_id()); } return true; diff --git a/interface/lib/classes/finediff.inc.php b/interface/lib/classes/finediff.inc.php new file mode 100644 index 000000000..43b542f36 --- /dev/null +++ b/interface/lib/classes/finediff.inc.php @@ -0,0 +1,752 @@ +copy->insert +* command (swap) for when the inserted segment is exactly the same +* as the deleted one, and with only a copy operation in between. +* TODO: How often this case occurs? Is it worth it? Can only +* be done as a postprocessing method (->optimize()?) +*/ +abstract class FineDiffOp { + abstract public function getFromLen(); + abstract public function getToLen(); + abstract public function getOpcode(); + } + +class FineDiffDeleteOp extends FineDiffOp { + public function __construct($len) { + $this->fromLen = $len; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return 0; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + return 'd'; + } + return "d{$this->fromLen}"; + } + } + +class FineDiffInsertOp extends FineDiffOp { + public function __construct($text) { + $this->text = $text; + } + public function getFromLen() { + return 0; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "i:{$this->text}"; + } + return "i{$to_len}:{$this->text}"; + } + } + +class FineDiffReplaceOp extends FineDiffOp { + public function __construct($fromLen, $text) { + $this->fromLen = $fromLen; + $this->text = $text; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + $del_opcode = 'd'; + } + else { + $del_opcode = "d{$this->fromLen}"; + } + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "{$del_opcode}i:{$this->text}"; + } + return "{$del_opcode}i{$to_len}:{$this->text}"; + } + } + +class FineDiffCopyOp extends FineDiffOp { + public function __construct($len) { + $this->len = $len; + } + public function getFromLen() { + return $this->len; + } + public function getToLen() { + return $this->len; + } + public function getOpcode() { + if ( $this->len === 1 ) { + return 'c'; + } + return "c{$this->len}"; + } + public function increase($size) { + return $this->len += $size; + } + } + +/** +* FineDiff ops +* +* Collection of ops +*/ +class FineDiffOps { + public function appendOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + $edits[] = new FineDiffCopyOp($from_len); + } + else if ( $opcode === 'd' ) { + $edits[] = new FineDiffDeleteOp($from_len); + } + else /* if ( $opcode === 'i' ) */ { + $edits[] = new FineDiffInsertOp(substr($from, $from_offset, $from_len)); + } + } + public $edits = array(); + } + +/** +* FineDiff class +* +* TODO: Document +* +*/ +class FineDiff { + + /**------------------------------------------------------------------------ + * + * Public section + * + */ + + /** + * Constructor + * ... + * The $granularityStack allows FineDiff to be configurable so that + * a particular stack tailored to the specific content of a document can + * be passed. + */ + public function __construct($from_text = '', $to_text = '', $granularityStack = null) { + // setup stack for generic text documents by default + $this->granularityStack = $granularityStack ? $granularityStack : FineDiff::$characterGranularity; + $this->edits = array(); + $this->from_text = $from_text; + $this->doDiff($from_text, $to_text); + } + + public function getOps() { + return $this->edits; + } + + public function getOpcodes() { + $opcodes = array(); + foreach ( $this->edits as $edit ) { + $opcodes[] = $edit->getOpcode(); + } + return implode('', $opcodes); + } + + public function renderDiffToHTML() { + $in_offset = 0; + ob_start(); + foreach ( $this->edits as $edit ) { + $n = $edit->getFromLen(); + if ( $edit instanceof FineDiffCopyOp ) { + FineDiff::renderDiffToHTMLFromOpcode('c', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffDeleteOp ) { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffInsertOp ) { + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + else /* if ( $edit instanceof FineDiffReplaceOp ) */ { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + $in_offset += $n; + } + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Return an opcodes string describing the diff between a "From" and a + * "To" string + */ + public static function getDiffOpcodes($from, $to, $granularities = null) { + $diff = new FineDiff($from, $to, $granularities); + return $diff->getOpcodes(); + } + + /**------------------------------------------------------------------------ + * Return an iterable collection of diff ops from an opcodes string + */ + public static function getDiffOpsFromOpcodes($opcodes) { + $diffops = new FineDiffOps(); + FineDiff::renderFromOpcodes(null, $opcodes, array($diffops,'appendOpcode')); + return $diffops->edits; + } + + /**------------------------------------------------------------------------ + * Re-create the "To" string from the "From" string and an "Opcodes" string + */ + public static function renderToTextFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderToTextFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 unsafe + */ + public static function renderDiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 safe + */ + public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderUTF8FromOpcode($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + public static function renderFromOpcodes($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else if ( $opcode === 'd' ) { // delete n characters from source + call_user_func($callback, 'd', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + call_user_func($callback, 'i', $opcodes, $opcodes_offset + 1, $n); + $opcodes_offset += 1 + $n; + } + } + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + private static function renderUTF8FromOpcode($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $from_len = strlen($from); + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + $last_to_chars = ''; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' || $opcode === 'd' ) { + $beg = $from_offset; + $end = $from_offset + $n; + while ( $beg > 0 && (ord($from[$beg]) & 0xC0) === 0x80 ) { $beg--; } + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $beg, $end - $beg, ''); + $last_to_chars = substr($from, $beg, $end - $beg); + } + else /* if ( $opcode === 'd' ) */ { // delete n characters from source + call_user_func($callback, 'd', $from, $beg, $end - $beg, ''); + } + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + $opcodes_offset += 1; + if ( strlen($last_to_chars) > 0 && (ord($opcodes[$opcodes_offset]) & 0xC0) === 0x80 ) { + $beg = strlen($last_to_chars) - 1; + while ( $beg > 0 && (ord($last_to_chars[$beg]) & 0xC0) === 0x80 ) { $beg--; } + $prefix = substr($last_to_chars, $beg); + } else { + $prefix = ''; + } + $end = $from_offset; + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + $toInsert = $prefix . substr($opcodes, $opcodes_offset, $n) . substr($from, $end, $end - $from_offset); + call_user_func($callback, 'i', $toInsert, 0, strlen($toInsert)); + $opcodes_offset += $n; + $last_to_chars = $toInsert; + } + } + } + + /** + * Stock granularity stacks and delimiters + */ + + const paragraphDelimiters = "\n\r"; + public static $paragraphGranularity = array( + FineDiff::paragraphDelimiters + ); + const sentenceDelimiters = ".\n\r"; + public static $sentenceGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters + ); + const wordDelimiters = " \t.\n\r"; + public static $wordGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters + ); + const characterDelimiters = ""; + public static $characterGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters, + FineDiff::characterDelimiters + ); + + public static $textStack = array( + ".", + " \t.\n\r", + "" + ); + + /**------------------------------------------------------------------------ + * + * Private section + * + */ + + /** + * Entry point to compute the diff. + */ + private function doDiff($from_text, $to_text) { + $this->last_edit = false; + $this->stackpointer = 0; + $this->from_text = $from_text; + $this->from_offset = 0; + // can't diff without at least one granularity specifier + if ( empty($this->granularityStack) ) { + return; + } + $this->_processGranularity($from_text, $to_text); + } + + /** + * This is the recursive function which is responsible for + * handling/increasing granularity. + * + * Incrementally increasing the granularity is key to compute the + * overall diff in a very efficient way. + */ + private function _processGranularity($from_segment, $to_segment) { + $delimiters = $this->granularityStack[$this->stackpointer++]; + $has_next_stage = $this->stackpointer < count($this->granularityStack); + foreach ( FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit ) { + // increase granularity + if ( $fragment_edit instanceof FineDiffReplaceOp && $has_next_stage ) { + $this->_processGranularity( + substr($this->from_text, $this->from_offset, $fragment_edit->getFromLen()), + $fragment_edit->getText() + ); + } + // fuse copy ops whenever possible + else if ( $fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp ) { + $this->edits[count($this->edits)-1]->increase($fragment_edit->getFromLen()); + $this->from_offset += $fragment_edit->getFromLen(); + } + else { + /* $fragment_edit instanceof FineDiffCopyOp */ + /* $fragment_edit instanceof FineDiffDeleteOp */ + /* $fragment_edit instanceof FineDiffInsertOp */ + $this->edits[] = $this->last_edit = $fragment_edit; + $this->from_offset += $fragment_edit->getFromLen(); + } + } + $this->stackpointer--; + } + + /** + * This is the core algorithm which actually perform the diff itself, + * fragmenting the strings as per specified delimiters. + * + * This function is naturally recursive, however for performance purpose + * a local job queue is used instead of outright recursivity. + */ + private static function doFragmentDiff($from_text, $to_text, $delimiters) { + // Empty delimiter means character-level diffing. + // In such case, use code path optimized for character-level + // diffing. + if ( empty($delimiters) ) { + return FineDiff::doCharDiff($from_text, $to_text); + } + + $result = array(); + + // fragment-level diffing + $from_text_len = strlen($from_text); + $to_text_len = strlen($to_text); + $from_fragments = FineDiff::extractFragments($from_text, $delimiters); + $to_fragments = FineDiff::extractFragments($to_text, $delimiters); + + $jobs = array(array(0, $from_text_len, 0, $to_text_len)); + + $cached_array_keys = array(); + + while ( $job = array_pop($jobs) ) { + + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + + // catch easy cases first + $from_segment_length = $from_segment_end - $from_segment_start; + $to_segment_length = $to_segment_end - $to_segment_start; + if ( !$from_segment_length || !$to_segment_length ) { + if ( $from_segment_length ) { + $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length); + } + else if ( $to_segment_length ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length)); + } + continue; + } + + // find longest copy operation for the current segments + $best_copy_length = 0; + + $from_base_fragment_index = $from_segment_start; + + $cached_array_keys_for_current_segment = array(); + + while ( $from_base_fragment_index < $from_segment_end ) { + $from_base_fragment = $from_fragments[$from_base_fragment_index]; + $from_base_fragment_length = strlen($from_base_fragment); + // performance boost: cache array keys + if ( !isset($cached_array_keys_for_current_segment[$from_base_fragment]) ) { + if ( !isset($cached_array_keys[$from_base_fragment]) ) { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true); + } + else { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment]; + } + // get only indices which falls within current segment + if ( $to_segment_start > 0 || $to_segment_end < $to_text_len ) { + $to_fragment_indices = array(); + foreach ( $to_all_fragment_indices as $to_fragment_index ) { + if ( $to_fragment_index < $to_segment_start ) { continue; } + if ( $to_fragment_index >= $to_segment_end ) { break; } + $to_fragment_indices[] = $to_fragment_index; + } + $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices; + } + else { + $to_fragment_indices = $to_all_fragment_indices; + } + } + else { + $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment]; + } + // iterate through collected indices + foreach ( $to_fragment_indices as $to_base_fragment_index ) { + $fragment_index_offset = $from_base_fragment_length; + // iterate until no more match + for (;;) { + $fragment_from_index = $from_base_fragment_index + $fragment_index_offset; + if ( $fragment_from_index >= $from_segment_end ) { + break; + } + $fragment_to_index = $to_base_fragment_index + $fragment_index_offset; + if ( $fragment_to_index >= $to_segment_end ) { + break; + } + if ( $from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index] ) { + break; + } + $fragment_length = strlen($from_fragments[$fragment_from_index]); + $fragment_index_offset += $fragment_length; + } + if ( $fragment_index_offset > $best_copy_length ) { + $best_copy_length = $fragment_index_offset; + $best_from_start = $from_base_fragment_index; + $best_to_start = $to_base_fragment_index; + } + } + $from_base_fragment_index += strlen($from_base_fragment); + // If match is larger than half segment size, no point trying to find better + // TODO: Really? + if ( $best_copy_length >= $from_segment_length / 2) { + break; + } + // no point to keep looking if what is left is less than + // current best match + if ( $from_base_fragment_index + $best_copy_length >= $from_segment_end ) { + break; + } + } + + if ( $best_copy_length ) { + $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start); + $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length); + $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end); + } + else { + $result[$from_segment_start * 4 ] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); + } + } + + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Perform a character-level diff. + * + * The algorithm is quite similar to doFragmentDiff(), except that + * the code path is optimized for character-level diff -- strpos() is + * used to find out the longest common subequence of characters. + * + * We try to find a match using the longest possible subsequence, which + * is at most the length of the shortest of the two strings, then incrementally + * reduce the size until a match is found. + * + * I still need to study more the performance of this function. It + * appears that for long strings, the generic doFragmentDiff() is more + * performant. For word-sized strings, doCharDiff() is somewhat more + * performant. + */ + private static function doCharDiff($from_text, $to_text) { + $result = array(); + $jobs = array(array(0, strlen($from_text), 0, strlen($to_text))); + while ( $job = array_pop($jobs) ) { + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + $from_segment_len = $from_segment_end - $from_segment_start; + $to_segment_len = $to_segment_end - $to_segment_start; + + // catch easy cases first + if ( !$from_segment_len || !$to_segment_len ) { + if ( $from_segment_len ) { + $result[$from_segment_start * 4 + 0] = new FineDiffDeleteOp($from_segment_len); + } + else if ( $to_segment_len ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_len)); + } + continue; + } + if ( $from_segment_len >= $to_segment_len ) { + $copy_len = $to_segment_len; + while ( $copy_len ) { + $to_copy_start = $to_segment_start; + $to_copy_start_max = $to_segment_end - $copy_len; + while ( $to_copy_start <= $to_copy_start_max ) { + $from_copy_start = strpos(substr($from_text, $from_segment_start, $from_segment_len), substr($to_text, $to_copy_start, $copy_len)); + if ( $from_copy_start !== false ) { + $from_copy_start += $from_segment_start; + break 2; + } + $to_copy_start++; + } + $copy_len--; + } + } + else { + $copy_len = $from_segment_len; + while ( $copy_len ) { + $from_copy_start = $from_segment_start; + $from_copy_start_max = $from_segment_end - $copy_len; + while ( $from_copy_start <= $from_copy_start_max ) { + $to_copy_start = strpos(substr($to_text, $to_segment_start, $to_segment_len), substr($from_text, $from_copy_start, $copy_len)); + if ( $to_copy_start !== false ) { + $to_copy_start += $to_segment_start; + break 2; + } + $from_copy_start++; + } + $copy_len--; + } + } + // match found + if ( $copy_len ) { + $jobs[] = array($from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start); + $result[$from_copy_start * 4 + 2] = new FineDiffCopyOp($copy_len); + $jobs[] = array($from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end); + } + // no match, so delete all, insert all + else { + $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_len, substr($to_text, $to_segment_start, $to_segment_len)); + } + } + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Efficiently fragment the text into an array according to + * specified delimiters. + * No delimiters means fragment into single character. + * The array indices are the offset of the fragments into + * the input string. + * A sentinel empty fragment is always added at the end. + * Careful: No check is performed as to the validity of the + * delimiters. + */ + private static function extractFragments($text, $delimiters) { + // special case: split into characters + if ( empty($delimiters) ) { + $chars = str_split($text, 1); + $chars[strlen($text)] = ''; + return $chars; + } + $fragments = array(); + $start = $end = 0; + for (;;) { + $end += strcspn($text, $delimiters, $end); + $end += strspn($text, $delimiters, $end); + if ( $end === $start ) { + break; + } + $fragments[$start] = substr($text, $start, $end - $start); + $start = $end; + } + $fragments[$start] = ''; + return $fragments; + } + + /** + * Stock opcode renderers + */ + private static function renderToTextFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' || $opcode === 'i' ) { + echo substr($from, $from_offset, $from_len); + } + } + + private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + echo htmlspecialchars(substr($from, $from_offset, $from_len)); + } + else if ( $opcode === 'd' ) { + $deletion = substr($from, $from_offset, $from_len); + if ( strcspn($deletion, " \n\r") === 0 ) { + $deletion = str_replace(array("\n","\r"), array('\n','\r'), $deletion); + } + echo '', htmlspecialchars($deletion), ''; + } + else /* if ( $opcode === 'i' ) */ { + echo '', htmlspecialchars(substr($from, $from_offset, $from_len)), ''; + } + } + } + diff --git a/interface/web/login/index.php b/interface/web/login/index.php index 5fb94d800..b55ac74f1 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -262,7 +262,7 @@ if(count($_POST) > 0) { $app->plugin->raiseEvent('login', $username); //* Save successfull login message to var - $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s'); + $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id(); $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); diff --git a/interface/web/monitor/dataloghistory_list.php b/interface/web/monitor/dataloghistory_list.php new file mode 100644 index 000000000..cab8da8a3 --- /dev/null +++ b/interface/web/monitor/dataloghistory_list.php @@ -0,0 +1,54 @@ +auth->check_module_permissions('monitor'); + +$app->uses('listform_actions'); + +$app->listform_actions->SQLOrderBy = "ORDER BY sys_datalog.tstamp DESC, sys_datalog.datalog_id DESC"; + +$app->listform_actions->onLoad(); + + +?> diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php new file mode 100644 index 000000000..5ff08faa0 --- /dev/null +++ b/interface/web/monitor/dataloghistory_undo.php @@ -0,0 +1,70 @@ +auth->check_module_permissions('monitor'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_undo.htm'); + +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_undo.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$dbidx = explode(':', $record['dbidx']); + +$old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); + +if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); +} else { + $app->tpl->setVar('success', false); +} + +$app->tpl_defaults(); +$app->tpl->pparse(); + +?> diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php new file mode 100644 index 000000000..e3b5e7b63 --- /dev/null +++ b/interface/web/monitor/dataloghistory_view.php @@ -0,0 +1,130 @@ +auth->check_module_permissions('monitor'); + +$app->load('finediff'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_view.htm'); + +$app->load_language_file('web/monitor/lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$out['id'] = $id; + +$out['timestamp'] = date($app->lng('conf_format_datetime'), $record['tstamp']); +$out['table'] = $record['dbtable']; + +$out['action_char'] = $record['action']; +$out['action_name'] = $app->lng($record['action']); + +$out['session_id'] = $record['session_id']; + +if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); +} + +switch ($record['action']) { + case 'i': + $inserts = array(); + foreach ($data['new'] as $key=>$value) { + $inserts[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('inserts', $inserts); + break; + case 'u': + $updates = array(); + foreach ($data['new'] as $key=>$value) { + if ($value != $data['old'][$key]) { + $old = $data['old'][$key]; + $new = $value; + $changes = show_diff_if_needed($old, $new); + $updates[] = array( + 'key' => $key, + 'is_diff' => $changes['is_diff'], + 'old' => nl2br($changes['old']), + 'new' => nl2br($changes['new']), + 'diff' => nl2br($changes['diff']), + ); + } + } + if (count($updates) > 0) { + $app->tpl->setLoop('updates', $updates); + } else { + $out['no_changes'] = true; + } + break; + case 'd': + $deletes = array(); + foreach ($data['old'] as $key=>$value) { + $deletes[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('deletes', $deletes); + break; +} + +$app->tpl->setVar($out); + +$app->tpl_defaults(); +$app->tpl->pparse(); + +function show_diff_if_needed($old, $new) { + global $app; + + $diff_min_lines = 6; + + if (substr_count($old, "\n") >= $diff_min_lines || substr_count($new, "\n") >= $diff_min_lines) { + $opcodes = FineDiff::getDiffOpcodes($old, $new); + $html = FineDiff::renderUTF8DiffToHTMLFromOpcodes($old, $opcodes); + return array('is_diff'=>true, 'old'=>'', 'new'=>'', 'diff'=>$html); + } else { + return array('is_diff'=>false, 'old'=>$old, 'new'=>$new, 'diff'=>''); + } +} + +?> diff --git a/interface/web/monitor/lib/lang/de.lng b/interface/web/monitor/lib/lang/de.lng index 8e70741ef..33998b5ed 100644 --- a/interface/web/monitor/lib/lang/de.lng +++ b/interface/web/monitor/lib/lang/de.lng @@ -40,6 +40,7 @@ $wb['Show Clamav-Log'] = 'ClamAV Protokoll anzeigen'; $wb['Show ISPConfig-Log'] = 'ISPConfig Protokoll anzeigen'; $wb['Show RKHunter-Log'] = 'RKHunter Protokoll anzeigen'; $wb['Show Jobqueue'] = 'Jobwarteschlange anzeigen'; +$wb['Show Data Log History'] = 'Datalog-History anzeigen'; $wb['Show ISPC Cron-Log'] = 'Cron Protokoll anzeigen'; $wb['no_data_updates_txt'] = 'Derzeit stehen keine Daten über Updates zur Verfügung. Bitte später erneut überprüfen.'; $wb['no_data_raid_txt'] = 'Derzeit stehen keine Daten über RAID zur Verfügung. Bitte später erneut überprüfen.'; diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_list.lng b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng new file mode 100644 index 000000000..2c2b6c9fc --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng new file mode 100644 index 000000000..c47a6c658 --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng new file mode 100644 index 000000000..e91d341ca --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index 3721f692e..baa0252ce 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -46,6 +46,7 @@ $wb['Show Clamav-Log'] = 'Show Clamav-Log'; $wb['Show ISPConfig-Log'] = 'Show ISPConfig-Log'; $wb['Show RKHunter-Log'] = 'Show RKHunter-Log'; $wb['Show Jobqueue'] = 'Show Jobqueue'; +$wb['Show Data Log History'] = 'Show Data Log History'; $wb['Show fail2ban-Log'] = 'Show fail2ban-Log'; $wb['Show MongoDB-Log'] = 'Show MongoDB-Log'; $wb['Show IPTables'] = 'Show IPTables'; diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_list.lng b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng new file mode 100644 index 000000000..9f9afd634 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng new file mode 100644 index 000000000..258d88669 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng new file mode 100644 index 000000000..df9ddd286 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/lib/module.conf.php b/interface/web/monitor/lib/module.conf.php index 1f40d7b4d..0bba401ad 100644 --- a/interface/web/monitor/lib/module.conf.php +++ b/interface/web/monitor/lib/module.conf.php @@ -26,6 +26,11 @@ $items[] = array( 'title' => 'Show Jobqueue', 'link' => 'monitor/datalog_list.php', 'html_id' => 'jobqueue'); +$items[] = array( 'title' => 'Show Data Log History', + 'target' => 'content', + 'link' => 'monitor/dataloghistory_list.php', + 'html_id' => 'dataloghistory'); + $module["nav"][] = array( 'title' => 'System State (All Servers)', 'open' => 1, 'items' => $items); diff --git a/interface/web/monitor/list/dataloghistory.list.php b/interface/web/monitor/list/dataloghistory.list.php new file mode 100644 index 000000000..1757125e8 --- /dev/null +++ b/interface/web/monitor/list/dataloghistory.list.php @@ -0,0 +1,91 @@ + "tstamp", + 'datatype' => "DATETIME", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ""); + + +$liste['item'][] = array( 'field' => 'server_id', + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} ORDER BY server_name', + 'keyfield'=> 'server_id', + 'valuefield'=> 'server_name' + ), + 'width' => '', + 'value' => ''); + +$liste["item"][] = array( 'field' => "action", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('i' => "Insert", 'u' => "Update", 'd' => "Delete")); + + +$liste["item"][] = array( 'field' => "dbtable", + 'datatype' => "VARCHAR", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "%", + 'suffix' => "%", + 'width' => "", + 'value' => ""); + + +?> diff --git a/interface/web/monitor/templates/dataloghistory_list.htm b/interface/web/monitor/templates/dataloghistory_list.htm new file mode 100644 index 000000000..0cd3c4f4d --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_list.htm @@ -0,0 +1,54 @@ + + + +

+ + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
  + +
{tmpl_var name="tstamp"}{tmpl_var name="server_id"}{tmpl_var name="action"}{tmpl_var name="dbtable"}
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ +
diff --git a/interface/web/monitor/templates/dataloghistory_undo.htm b/interface/web/monitor/templates/dataloghistory_undo.htm new file mode 100644 index 000000000..997231a88 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_undo.htm @@ -0,0 +1,17 @@ + + + + + + + + + + +
+
+ +
+
diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm new file mode 100644 index 000000000..0ce595e26 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -0,0 +1,124 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +

+
+ +

+
+ +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
( / )
+
+
+
+ +
+
+ + {tmpl_var name='undo_txt'} + + +
+
diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css index 049322f29..449c05cdb 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.css +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css @@ -809,3 +809,16 @@ span.pbvaluemargin { .ip_suggestion_server { font-weight: bold; } +.finediff { + font-family: monospace; +} +.finediff ins { + color: green; + background: #dfd; + text-decoration: none; +} +.finediff del { + color: red; + background: #fdd; + text-decoration: none; +} \ No newline at end of file -- GitLab From 06b26aa21920f80371e03d61e3bccabafadd0e2d Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 12:59:15 +0100 Subject: [PATCH 261/310] - patches for jailkit update feature, contributed by Timme Hosting --- .../sites/lib/lang/de_web_vhost_domain.lng | 3 +- .../sites/lib/lang/en_web_vhost_domain.lng | 3 +- .../templates/web_vhost_domain_advanced.htm | 4 +- .../lib/classes/cron.d/500-jkupdate.inc.php | 67 +++++++++++++++++-- 4 files changed, 66 insertions(+), 11 deletions(-) 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 674f31157..f401e0f4c 100644 --- a/interface/web/sites/lib/lang/de_web_vhost_domain.lng +++ b/interface/web/sites/lib/lang/de_web_vhost_domain.lng @@ -155,4 +155,5 @@ $wb['error_server_change_not_possible'] = 'Der Server kann nicht geändert werde $wb['enable_pagespeed_txt'] = 'Enable PageSpeed'; $wb['log_retention_txt'] = 'Log-Dateien Aufbewahrungszeit'; $wb['log_retention_error_regex'] = 'Aufbewahrungszeit in Tagen (Erlaubte Werte: min. 0 - max. 9999)'; -$wb['jailkit_jkupdate_cron_txt'] = 'Automatisches jkupdate'; \ No newline at end of file +$wb['jailkit_jkupdate_cron_txt'] = 'Automatisches Jailkit-Update'; +$wb['ttip_jailkit_jkupdate_cron_txt'] = 'Wenn diese Website mind. einen Jailkit-SSH-Benutzer hat, wird das Jailkit durch einen täglichen Cron Job aktuell gehalten.'; \ No newline at end of file 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 85096f4dc..7a99f632d 100644 --- a/interface/web/sites/lib/lang/en_web_vhost_domain.lng +++ b/interface/web/sites/lib/lang/en_web_vhost_domain.lng @@ -161,4 +161,5 @@ $wb['error_domain_change_forbidden'] = 'The domain name cannot be changed. Pleas $wb['error_server_change_not_possible'] = 'The server cannot be changed.'; $wb['log_retention_txt'] = 'Logfiles retention time'; $wb['log_retention_error_regex'] = 'Retention time in days (allowed values: min. 0 - max. 9999)'; -$wb['jailkit_jkupdate_cron_txt'] = 'Automate jkupdate'; \ No newline at end of file +$wb['jailkit_jkupdate_cron_txt'] = 'Automatic Jailkit update'; +$wb['ttip_jailkit_jkupdate_cron_txt'] = 'If this site has at least one Jailkit SSH user, the jailkit will be kept up to date through a daily cron job.'; \ No newline at end of file diff --git a/interface/web/sites/templates/web_vhost_domain_advanced.htm b/interface/web/sites/templates/web_vhost_domain_advanced.htm index d7ed5a53c..7ecfe9608 100644 --- a/interface/web/sites/templates/web_vhost_domain_advanced.htm +++ b/interface/web/sites/templates/web_vhost_domain_advanced.htm @@ -101,8 +101,8 @@ {tmpl_var name="available_php_directive_snippets_txt"}

 {tmpl_var name="php_directive_snippets_txt"}
-
- +
+
{tmpl_var name='jailkit_jkupdate_cron'}
diff --git a/server/lib/classes/cron.d/500-jkupdate.inc.php b/server/lib/classes/cron.d/500-jkupdate.inc.php index 2eaacdbcf..1fb292347 100644 --- a/server/lib/classes/cron.d/500-jkupdate.inc.php +++ b/server/lib/classes/cron.d/500-jkupdate.inc.php @@ -53,27 +53,72 @@ class cronjob_jkupdate extends cronjob { $app->uses('getconf'); $jailkit_conf = $app->getconf->get_server_config($conf['server_id'], 'jailkit'); - $jailkit_programs = explode(' ', $jailkit_conf['jailkit_chroot_app_programs']); + //$jailkit_programs = explode(' ', $jailkit_conf['jailkit_chroot_app_programs']); + $jailkit_programs = preg_split("/[\s,]+/", $jailkit_conf['jailkit_chroot_app_programs']); + $jailkit_sections = trim($jailkit_conf['jailkit_chroot_app_sections']); - $sites = $app->db->queryAllRecords('SELECT domain_id, document_root FROM web_domain WHERE jailkit_jkupdate_cron = \'y\''); + $sites = $app->db->queryAllRecords("SELECT domain_id, document_root, fastcgi_php_version FROM web_domain WHERE jailkit_jkupdate_cron = 'y' AND type = 'vhost' AND parent_domain_id = 0 AND document_root != '' ORDER BY domain_id"); foreach($sites as $site) { - $users = $app->db->queryOneRecord('SELECT COUNT(*) AS user_count FROM shell_user WHERE parent_domain_id = ? AND active=\'y\' AND chroot=\'jailkit\'', $site['domain_id']); - $crons = $app->db->queryOneRecord('SELECT COUNT(*) AS cron_count FROM cron WHERE parent_domain_id = ? AND active=\'y\' AND type=\'chrooted\'', $site['domain_id']); + $set_php_symlink = false; + + $users = $app->db->queryOneRecord("SELECT COUNT(*) AS user_count FROM shell_user WHERE parent_domain_id = ? AND active='y' AND chroot='jailkit'", intval($site['domain_id'])); + $crons = $app->db->queryOneRecord("SELECT COUNT(*) AS cron_count FROM cron WHERE parent_domain_id = ? AND active='y' AND type='chrooted'", $site['domain_id']); if ($users['user_count'] > 0 || $crons['cron_count'] > 0) { + if (!is_dir($site['document_root'])) { return; } + + //$app->log('Running jailkit init for '.$site['document_root']); + //if($jailkit_sections != '') $this->run_jk_init($site['document_root'], $jailkit_sections); $app->log('Running jailkit updates for '.$site['document_root']); $this->run_jk_update($site['document_root']); - $this->run_jk_cp($site['document_root'], $jailkit_programs); + if(preg_match('@(\d\d?\.\d\d?\.\d\d?)@', $site['fastcgi_php_version'], $matches)){ + if(!in_array('/opt/php-'.$matches[1].'/bin/php', $jailkit_programs)) $jailkit_programs[] = '/opt/php-'.$matches[1].'/bin/php'; + if(!in_array('/opt/php-'.$matches[1].'/include', $jailkit_programs)) $jailkit_programs[] = '/opt/php-'.$matches[1].'/include'; + if(!in_array('/opt/php-'.$matches[1].'/lib', $jailkit_programs)) $jailkit_programs[] = '/opt/php-'.$matches[1].'/lib'; + if(!in_array('/opt/th-php-libs', $jailkit_programs)) $jailkit_programs[] = '/opt/th-php-libs'; + + $set_php_symlink = true; + + } + if(is_array($jailkit_programs) && !empty($jailkit_programs)) $this->run_jk_cp($site['document_root'], $jailkit_programs); + + if($set_php_symlink){ + // create symlink from /usr/bin/php to current PHP version + if(preg_match('@(\d\d?\.\d\d?\.\d\d?)@', $site['fastcgi_php_version'], $matches) && (!file_exists($site['document_root'].'/usr/bin/php') || is_link($site['document_root'].'/usr/bin/php'))){ + @unlink($site['document_root'].'/usr/bin/php'); + @symlink('/opt/php-'.$matches[1].'/bin/php', $site['document_root'].'/usr/bin/php'); + } + } } } + + if(file_exists('/dev/tty')){ + chmod('/dev/tty', 0666); + } parent::onRunJob(); } + + private function run_jk_init($document_root, $sections){ + global $app; + + $return_var = $this->exec_log('/usr/sbin/jk_init -f -k -c /etc/jailkit/jk_init.ini -j '.escapeshellarg($document_root).' '.$sections); + + if ($return_var > 0) { + $app->log('jk_init failed with -j, trying again without -j', LOGLEVEL_DEBUG); + + $return_var = $this->exec_log('/usr/sbin/jk_init -f -k -c /etc/jailkit/jk_init.ini '.escapeshellarg($document_root).' '.$sections); + + if ($return_var > 0) { + $app->log('jk_init failed (with and without -j parameter)', LOGLEVEL_WARN); + } + } + } private function run_jk_update($document_root) { global $app; @@ -94,10 +139,14 @@ class cronjob_jkupdate extends cronjob { global $app; foreach($programs as $program) { + $program = trim($program); + if($program == ''){ + continue; + } if (!file_exists($program)) { continue; } - + $return_var = $this->exec_log('/usr/sbin/jk_cp '.escapeshellarg($document_root).' '.escapeshellarg($program)); if ($return_var > 0) { @@ -109,6 +158,10 @@ class cronjob_jkupdate extends cronjob { } } } + + if(file_exists($document_root.'/dev/tty')){ + chmod($document_root.'/dev/tty', 0666); + } } private function exec_log($cmd) { @@ -134,4 +187,4 @@ class cronjob_jkupdate extends cronjob { } -?> +?> \ No newline at end of file -- GitLab From e96019c5924a7f99f11a7758d2dff59cbac66b90 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:00:15 +0100 Subject: [PATCH 262/310] - changed default jailkit programs --- install/tpl/server.ini.master | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/tpl/server.ini.master b/install/tpl/server.ini.master index 8fc724469..996c388f2 100644 --- a/install/tpl/server.ini.master +++ b/install/tpl/server.ini.master @@ -137,7 +137,7 @@ fastcgi_bin=/usr/bin/php-cgi [jailkit] jailkit_chroot_home=/home/[username] jailkit_chroot_app_sections=basicshell editors extendedshell netutils ssh sftp scp groups jk_lsh -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 +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 /usr/bin/rsync /usr/bin/jpegoptim /usr/bin/optipng /usr/share/ca-certificates/ /etc/ssl/certs/ /opt/th-php-libs/ /etc/ld.so.conf.d/ /bin/bzip2 /usr/local/bin/composer /usr/lib/ssl /usr/bin/env /usr/bin/xargs jailkit_chroot_cron_programs=/usr/bin/php /usr/bin/perl /usr/share/perl /usr/share/php [vlogger] -- GitLab From b6936b38a36eb325a3e215e44d58f10b6a552400 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:02:12 +0100 Subject: [PATCH 263/310] - jailkit update cron improvements --- .../lib/classes/cron.d/500-jkupdate.inc.php | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/server/lib/classes/cron.d/500-jkupdate.inc.php b/server/lib/classes/cron.d/500-jkupdate.inc.php index 1fb292347..09ec9c1ed 100644 --- a/server/lib/classes/cron.d/500-jkupdate.inc.php +++ b/server/lib/classes/cron.d/500-jkupdate.inc.php @@ -86,6 +86,7 @@ class cronjob_jkupdate extends cronjob { } if(is_array($jailkit_programs) && !empty($jailkit_programs)) $this->run_jk_cp($site['document_root'], $jailkit_programs); + $this->fix_broken_symlinks($site['document_root']); if($set_php_symlink){ // create symlink from /usr/bin/php to current PHP version @@ -163,6 +164,30 @@ class cronjob_jkupdate extends cronjob { chmod($document_root.'/dev/tty', 0666); } } + + private function fix_broken_symlinks($document_root){ + global $app; + + exec('cd '.escapeshellarg($document_root).' && find . -type l \( ! -name web \) -xtype l', $output, $retval); + + if(is_array($output) && !empty($output)){ + foreach($output as $link){ + $link = trim($link); + if(preg_match('@\.so(\.\d+)*$@',$link)){ + if(substr($link, 0, 1) == '.') $link = substr($link, 1); + //echo $link."\n"; + $path = $document_root.$link; + //if(is_link($path)) echo "Ist Link\n"; + //if(!file_exists($path)) echo "Aber Link ist kaputt!\n"; + if(is_link($path) && !file_exists($path)){ + //echo $path."\n"; + @unlink($path); + $this->run_jk_cp($document_root, array($link)); + } + } + } + } + } private function exec_log($cmd) { global $app; @@ -187,4 +212,4 @@ class cronjob_jkupdate extends cronjob { } -?> \ No newline at end of file +?> -- GitLab From 336b8380a319d326c17d12c1c035b6245b8fb782 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:02:55 +0100 Subject: [PATCH 264/310] - further jailkit cron improvements --- server/lib/classes/cron.d/500-jkupdate.inc.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/server/lib/classes/cron.d/500-jkupdate.inc.php b/server/lib/classes/cron.d/500-jkupdate.inc.php index 09ec9c1ed..fcf07912d 100644 --- a/server/lib/classes/cron.d/500-jkupdate.inc.php +++ b/server/lib/classes/cron.d/500-jkupdate.inc.php @@ -31,7 +31,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class cronjob_jkupdate extends cronjob { // job schedule - protected $_schedule = '45 22 * * *'; + protected $_schedule = '45 22 3 * *'; protected $_run_at_new = true; /* this function is optional if it contains no custom code */ @@ -70,8 +70,11 @@ class cronjob_jkupdate extends cronjob { return; } - //$app->log('Running jailkit init for '.$site['document_root']); - //if($jailkit_sections != '') $this->run_jk_init($site['document_root'], $jailkit_sections); + //* Protect web folders + $app->system->web_folder_protection($site['document_root'], false); + + $app->log('Running jailkit init for '.$site['document_root']); + if($jailkit_sections != '') $this->run_jk_init($site['document_root'], $jailkit_sections); $app->log('Running jailkit updates for '.$site['document_root']); @@ -95,6 +98,9 @@ class cronjob_jkupdate extends cronjob { @symlink('/opt/php-'.$matches[1].'/bin/php', $site['document_root'].'/usr/bin/php'); } } + + //* Protect web folders + $app->system->web_folder_protection($site['document_root'], true); } } -- GitLab From 0a329cdfac800bf5727f677e17ba25ffa1c8506c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:08:45 +0100 Subject: [PATCH 265/310] - added dns bulk editor, contributed by Timme Hosting --- interface/web/dns/dns_bulk_editor.php | 329 ++++++++++++++++++ interface/web/dns/lib/lang/de.lng | 2 +- .../web/dns/lib/lang/de_dns_bulk_editor.lng | 33 ++ interface/web/dns/lib/lang/en.lng | 2 +- .../web/dns/lib/lang/en_dns_bulk_editor.lng | 33 ++ interface/web/dns/lib/module.conf.php | 4 + .../web/dns/templates/dns_bulk_editor.htm | 140 ++++++++ .../dns/templates/dns_bulk_editor_result.htm | 26 ++ .../assets/stylesheets/bootstrap.min.css | 2 +- 9 files changed, 568 insertions(+), 3 deletions(-) create mode 100644 interface/web/dns/dns_bulk_editor.php create mode 100644 interface/web/dns/lib/lang/de_dns_bulk_editor.lng create mode 100644 interface/web/dns/lib/lang/en_dns_bulk_editor.lng create mode 100644 interface/web/dns/templates/dns_bulk_editor.htm create mode 100644 interface/web/dns/templates/dns_bulk_editor_result.htm diff --git a/interface/web/dns/dns_bulk_editor.php b/interface/web/dns/dns_bulk_editor.php new file mode 100644 index 000000000..d94f9892e --- /dev/null +++ b/interface/web/dns/dns_bulk_editor.php @@ -0,0 +1,329 @@ +auth->check_module_permissions('dns'); + +// Loading the template +$app->uses('tpl,tfrom_base,validate_dns,functions'); +$app->tpl->newTemplate("form.tpl.htm"); + +include 'lib/lang/'.$_SESSION['s']['language'].'_dns_bulk_editor.lng'; +$app->tpl->setVar($wb); + +// Load clients (if admin): + +if ($app->auth->is_admin()) { + $clients = $app->db->queryAllRecords("SELECT sys_group.groupid,CONCAT(IF(client.company_name != '', CONCAT(client.company_name, ' :: '), ''), IF(client.contact_firstname != '', CONCAT(client.contact_firstname, ' '), ''), client.contact_name, ' (', client.username, IF(client.customer_no != '', CONCAT(', ', client.customer_no), ''), ')') as name FROM sys_group, client WHERE sys_group.groupid != 1 AND sys_group.client_id = client.client_id ORDER BY client.company_name, client.contact_name"); + + $clients_select_options = ''; + + foreach($clients as $client) { + $selected = (intval($_POST["client_group_id"]) == $client['groupid'])?'SELECTED':''; + $clients_select_options .= "\r\n"; + } + + $app->tpl->setVar('clients_select_options', $clients_select_options); +} + +// Load zones: + +if ($app->auth->is_admin()) { + if (isset($_POST["client_group_id"])) { + $client_group_ids = intval($_POST["client_group_id"]); + } +} else { + $client_group_ids = $_SESSION['s']['user']['groups']; +} + +if(isset($client_group_ids)) { + $sql = 'SELECT id, origin FROM dns_soa WHERE sys_groupid IN ('.$client_group_ids.') AND '.$app->tform_base->getAuthSQL('u'); + + $zones = $app->db->queryAllRecords($sql); + + $zones_rows = array(); // All zones (for output) + + foreach ($zones as $zone) { + $zones_rows[] = array( + 'zone_id'=>$zone['id'], + 'zone_name'=>$zone['origin'], + 'zone_selected'=>isset($_POST['zone_'.$zone['id']]), + ); + + } + + $app->tpl->setLoop('zones_rows', $zones_rows); + $app->tpl->setVar('zones_rows_count', count($zones_rows)); + + $update_zones = array(); // Currently selected zones in form (if any) + + foreach ($zones as $zone) { + if (isset($_POST['zone_'.$zone['id']])) { + $update_zones[$zone['id']] = $zone['origin']; + } + } +} else { + $app->tpl->setVar('zones_rows_count', 0); +} + +if (isset($_GET['submitted'])) { + validate_and_update($update_zones); +} + +$app->tpl_defaults(); + +if (isset($result)) { + $app->tpl->setVar('result', $result); + $app->tpl->setInclude('content_tpl', 'templates/dns_bulk_editor_result.htm'); +} else { + $app->tpl->setInclude('content_tpl', 'templates/dns_bulk_editor.htm'); +} + +$app->tpl->pparse(); + +function validate_and_update($update_zones) { + global $app, $wb, $client_group_ids, $result; + + // Validate: + + if ($client_group_ids == 0) { + $app->tpl->setVar('error', $wb['error_no_client_txt']); + return; + } + + if (!isset($_POST['action'])) { + $app->tpl->setVar('error', $wb['error_no_action_txt']); + return; + } + + switch ($_POST['action']) { + case 'a_records': + $app->tpl->setVar('action_a_records', true); + $app->tpl->setVar('a_records_search', htmlspecialchars($_POST['a_records_search'])); + $app->tpl->setVar('a_records_replace', htmlspecialchars($_POST['a_records_replace'])); + + if (!validate_ips($_POST['a_records_search'], $_POST['a_records_replace'])) { + // Error message is set in validate_ips + return; + } + + break; + case 'mx_records': + $app->tpl->setVar('action_mx_records', true); + $app->tpl->setVar('mx_records_search', htmlspecialchars($_POST['mx_records_search'])); + $app->tpl->setVar('mx_records_replace', htmlspecialchars($_POST['mx_records_replace'])); + + if (!validate_zone($_POST['mx_records_search']) || !validate_zone($_POST['mx_records_replace'])) { + $app->tpl->setVar('error', $wb['error_invalid_dns_zone_txt']); + return; + } + + break; + case 'ttl': + $app->tpl->setVar('action_ttl', true); + $app->tpl->setVar('ttl', htmlspecialchars($_POST['ttl'])); + + if (trim($_POST['ttl']) == '' || !is_numeric($_POST['ttl']) || intval($_POST['ttl']) < 60) { + $app->tpl->setVar('error', $wb['error_no_ttl_txt']); + return; + } + + break; + } + + if (!(isset($update_zones) && count($update_zones) > 0)) { + $app->tpl->setVar('error', $wb['error_no_zone_txt']); + return; + } + + foreach ($update_zones as $id=>$origin) { + $sql = 'SELECT id FROM dns_soa WHERE id = ? AND '.$app->tform_base->getAuthSQL('u'); + if (!is_array($app->db->queryOneRecord($sql, $id))) { + $app->tpl->setVar('error', $wb['error_invalid_zone_txt']); + return; + } + } + + // Update: + + switch ($_POST['action']) { + case 'a_records': + $result = '

'.$wb['a_records_txt'].'

'; + + foreach ($update_zones as $id=>$origin) { + $result .= "

".$wb['zone_txt']." $origin

"; + + $records = $app->db->queryAllRecords('SELECT id, type, name FROM dns_rr WHERE zone = ? AND data = ? AND type IN (\'A\', \'AAAA\') ORDER BY 2,3', $id, $_POST['a_records_search']); + + if (count($records) == 0) { + // Zone has no records or no matching records + $result .= $wb['no_matches_txt']; + continue; + } + + $result .= "
    "; + + foreach ($records as $record) { + $app->db->datalogUpdate('dns_rr', "data='".$app->db->escape($_POST['a_records_replace'])."'", 'id', $record['id']); + $result .= '
  • '.$record['type']." ".$record['name']." ".htmlentities($_POST['a_records_search']).' ➡ '.htmlentities($_POST['a_records_replace']).'
  • '; + } + + $result .= "
"; + + if (count($records) > 0) { + soa_increase_serial($id); + } + } + + break; + case 'mx_records': + $result = '

'.$wb['mx_records_txt'].'

'; + + foreach ($update_zones as $id=>$origin) { + $result .= "

".$wb['zone_txt']." $origin

"; + + $search_zone = normalize_zone($_POST['mx_records_search']); + $replace_zone = normalize_zone($_POST['mx_records_replace']); + + $records = $app->db->queryAllRecords('SELECT id, type, name FROM dns_rr WHERE zone = ? AND data = ? AND type = \'MX\' ORDER BY 2,3', $id, $search_zone); + + if (count($records) == 0) { + // Zone has no records or no matching records + echo 'No matches'; + $result .= $wb['no_matches_txt']; + continue; + } + + $result .= "
    "; + + foreach ($records as $record) { + $app->db->datalogUpdate('dns_rr', "data='".$app->db->escape($replace_zone)."'", 'id', $record['id']); + $result .= '
  • '.$record['type']." ".$record['name']." ".$search_zone.' ➡ '.$replace_zone.'
  • '; + } + + $result .= "
"; + + if (count($records) > 0) { + soa_increase_serial($id); + } + } + + break; + case 'ttl': + $result = '

'.$wb['ttl_txt'].'

'; + + $ttl = intval($_POST['ttl']); + + foreach ($update_zones as $id=>$origin) { + $result .= "

".$wb['zone_txt']." $origin

"; + + $records = $app->db->queryAllRecords('SELECT id, type, name FROM dns_rr WHERE zone = ? AND type IN (\'A\', \'AAAA\', \'MX\') ORDER BY 2,3', $id); + + if (count($records) == 0) { + // Zone has no records? + $result .= $wb['no_matches_txt']; + continue; + } + + $result .= "
    "; + + foreach ($records as $record) { + $app->db->datalogUpdate('dns_rr', "ttl=$ttl", 'id', $record['id']); + $result .= "
  • ".$record['type']." ".$record['name']." $ttl
  • "; + } + + $result .= "
"; + + if (count($records) > 0) { + soa_increase_serial($id); + } + } + + break; + } +} + +function validate_ips($search, $replace) { + global $app, $wb; + + if (trim($search) == '' || trim($replace) == '') { + $app->tpl->setVar('error', $wb['error_no_search_replace_txt']); + return false; + } + + $search_ip_type = get_ip_type($search); + $replace_ip_type = get_ip_type($replace); + + if ($search_ip_type == 'none' || $replace_ip_type == 'none') { + $app->tpl->setVar('error', $wb['error_invalid_ip_txt']); + return false; + } + + if ($search_ip_type != $replace_ip_type) { + $app->tpl->setVar('error', $wb['error_ip_type_mismatch_txt']); + return false; + } + + return true; +} + +function get_ip_type($s) { + if (filter_var($s, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) return 'IPv4'; + if (filter_var($s, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) return 'IPv6'; + return 'none'; +} + +function validate_zone($zone) { + $s = normalize_zone($zone); + $result = preg_match('/^[a-z0-9\.\-\*]{1,255}$/', $s) === 1; + return $result; +} + +function normalize_zone($zone) { + global $app; + + $s = trim($zone); + $s = strtolower($s); + $s = $app->functions->idn_encode($s); + return $s; +} + +function soa_increase_serial($id) { + global $app; + + $soa = $app->db->queryOneRecord('SELECT serial FROM dns_soa WHERE id = ?', $id); + $serial = $app->validate_dns->increase_serial($soa['serial']); + $app->db->datalogUpdate('dns_soa', "serial=$serial", 'id', $id); +} + +?> diff --git a/interface/web/dns/lib/lang/de.lng b/interface/web/dns/lib/lang/de.lng index 822fcd6a7..b195f9d27 100644 --- a/interface/web/dns/lib/lang/de.lng +++ b/interface/web/dns/lib/lang/de.lng @@ -19,4 +19,4 @@ $wb['Add DNS Zone'] = 'DNS Zone hinzufügen'; $wb['Templates'] = 'Vorlagen'; $wb['Secondary Zones'] = 'Slave DNS-Zonen'; $wb['Import Zone File'] = 'Zonen-Datei-Import'; -?> +$wb['Bulk Editor'] = 'Bulk-Editor'; diff --git a/interface/web/dns/lib/lang/de_dns_bulk_editor.lng b/interface/web/dns/lib/lang/de_dns_bulk_editor.lng new file mode 100644 index 000000000..cf31ed17e --- /dev/null +++ b/interface/web/dns/lib/lang/de_dns_bulk_editor.lng @@ -0,0 +1,33 @@ +.

Wenn Sie eine Subdomain Ihrer Domain angeben und und die Domain weglassen (z.B. www statt www.meinedomain.de), dann geben Sie bitte keinen Punkt am Ende an.'; +$wb['ttip_ttl_txt'] = 'Bitte geben Sie den gewünschten TTL-Wert als Ganzzahl in Sekunden ein.'; +?> diff --git a/interface/web/dns/lib/lang/en.lng b/interface/web/dns/lib/lang/en.lng index 3758933c3..8c8025754 100644 --- a/interface/web/dns/lib/lang/en.lng +++ b/interface/web/dns/lib/lang/en.lng @@ -20,4 +20,4 @@ $wb['Add DNS Zone'] = 'Add DNS-Zone'; $wb['Templates'] = 'Templates'; $wb['Secondary Zones'] = 'Secondary DNS-Zones'; $wb['Import Zone File'] = 'Zone-File Import'; -?> \ No newline at end of file +$wb['Bulk Editor'] = 'Bulk Editor'; \ No newline at end of file diff --git a/interface/web/dns/lib/lang/en_dns_bulk_editor.lng b/interface/web/dns/lib/lang/en_dns_bulk_editor.lng new file mode 100644 index 000000000..b9947520f --- /dev/null +++ b/interface/web/dns/lib/lang/en_dns_bulk_editor.lng @@ -0,0 +1,33 @@ +.

If you enter a subdomain of your domain, please enter only the subdomain and no dot at the end, for example www.'; +$wb['ttip_ttl_txt'] = 'Please enter the desired TTL value in seconds.'; +?> diff --git a/interface/web/dns/lib/module.conf.php b/interface/web/dns/lib/module.conf.php index 75b17a98e..efa446ae5 100644 --- a/interface/web/dns/lib/module.conf.php +++ b/interface/web/dns/lib/module.conf.php @@ -25,6 +25,10 @@ if($_SESSION["s"]["user"]["typ"] == 'admin') { 'html_id' => 'dns_template_list'); } +$items[] = array( 'title' => "Bulk Editor", + 'target' => 'content', + 'link' => 'dns/dns_bulk_editor.php', + 'html_id' => 'dns_bulk_editor'); $module["nav"][] = array( 'title' => 'DNS Wizard', 'open' => 1, diff --git a/interface/web/dns/templates/dns_bulk_editor.htm b/interface/web/dns/templates/dns_bulk_editor.htm new file mode 100644 index 000000000..6cfcf7dd1 --- /dev/null +++ b/interface/web/dns/templates/dns_bulk_editor.htm @@ -0,0 +1,140 @@ + + + +

+ + +
+
+
+
    +
  1. +
+
+
+
+ +
+
+
+ + + + +
+ +
+ +
+
+
+ + + +
+
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+
+
+ +
+ + +
+ +
+ +
+ +
+
+ +
+
+
+ +
+ +
+
+ +
+
{tmpl_var name='ttl_desc_txt'}
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='zone_txt'}
{tmpl_var name='zone_name'}
{tmpl_var name='check_uncheck_all_txt'}
+
+ +
+ +
+
+
+
+ diff --git a/interface/web/dns/templates/dns_bulk_editor_result.htm b/interface/web/dns/templates/dns_bulk_editor_result.htm new file mode 100644 index 000000000..3e11a4c1d --- /dev/null +++ b/interface/web/dns/templates/dns_bulk_editor_result.htm @@ -0,0 +1,26 @@ + + + +

+ + +
+
+
+
    +
  1. +
+
+
+
+ +
+
+
+ + +
+
+
diff --git a/interface/web/themes/default/assets/stylesheets/bootstrap.min.css b/interface/web/themes/default/assets/stylesheets/bootstrap.min.css index 4af8905e5..e351b378a 100644 --- a/interface/web/themes/default/assets/stylesheets/bootstrap.min.css +++ b/interface/web/themes/default/assets/stylesheets/bootstrap.min.css @@ -2,4 +2,4 @@ * Bootstrap v3.3.0 (http://getbootstrap.com) * Copyright 2011-2014 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px;line-height:1.5 \0}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px;line-height:1.33 \0}_:-ms-fullscreen,:root input[type=date],_:-ms-fullscreen,:root input[type=time],_:-ms-fullscreen,:root input[type=datetime-local],_:-ms-fullscreen,:root input[type=month]{line-height:1.42857143}_:-ms-fullscreen.input-sm,:root input[type=date].input-sm,_:-ms-fullscreen.input-sm,:root input[type=time].input-sm,_:-ms-fullscreen.input-sm,:root input[type=datetime-local].input-sm,_:-ms-fullscreen.input-sm,:root input[type=month].input-sm{line-height:1.5}_:-ms-fullscreen.input-lg,:root input[type=date].input-lg,_:-ms-fullscreen.input-lg,:root input[type=time].input-lg,_:-ms-fullscreen.input-lg,:root input[type=datetime-local].input-lg,_:-ms-fullscreen.input-lg,:root input[type=month].input-lg{line-height:1.33}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file + *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}.form-control[type=radio]{-webkit-box-shadow: none;box-shadow: none;}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px;line-height:1.5 \0}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px;line-height:1.33 \0}_:-ms-fullscreen,:root input[type=date],_:-ms-fullscreen,:root input[type=time],_:-ms-fullscreen,:root input[type=datetime-local],_:-ms-fullscreen,:root input[type=month]{line-height:1.42857143}_:-ms-fullscreen.input-sm,:root input[type=date].input-sm,_:-ms-fullscreen.input-sm,:root input[type=time].input-sm,_:-ms-fullscreen.input-sm,:root input[type=datetime-local].input-sm,_:-ms-fullscreen.input-sm,:root input[type=month].input-sm{line-height:1.5}_:-ms-fullscreen.input-lg,:root input[type=date].input-lg,_:-ms-fullscreen.input-lg,:root input[type=time].input-lg,_:-ms-fullscreen.input-lg,:root input[type=datetime-local].input-lg,_:-ms-fullscreen.input-lg,:root input[type=month].input-lg{line-height:1.33}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file -- GitLab From b25bf4f5389bcc0cef93b4f1dec7c9eb79911833 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 13:18:41 +0100 Subject: [PATCH 266/310] - backported datalog viewer from 3.2, contributed by Timme Hosting --- install/sql/incremental/upd_dev_collection.sql | 2 +- install/sql/ispconfig3.sql | 1 + interface/lib/classes/db_mysql.inc.php | 4 ++-- interface/web/login/index.php | 2 +- interface/web/monitor/lib/lang/de.lng | 1 + interface/web/monitor/lib/lang/en.lng | 1 + interface/web/monitor/lib/module.conf.php | 5 +++++ .../themes/default/assets/stylesheets/ispconfig.css | 13 +++++++++++++ 8 files changed, 25 insertions(+), 4 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 8b1378917..872ebfb46 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -1 +1 @@ - +ALTER TABLE `sys_datalog` ADD `session_id` varchar(64) NOT NULL DEFAULT '' AFTER `error`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index d3737a3ed..aacd2ecdb 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1631,6 +1631,7 @@ CREATE TABLE `sys_datalog` ( `data` longtext, `status` set('pending','ok','warning','error') NOT NULL default 'ok', `error` mediumtext, + `session_id` varchar(64) NOT NULL DEFAULT '', PRIMARY KEY (`datalog_id`), KEY `server_id` (`server_id`,`status`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index b03ad5567..8443d106b 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -719,8 +719,8 @@ class db if($action == 'INSERT') $action = 'i'; if($action == 'UPDATE') $action = 'u'; if($action == 'DELETE') $action = 'd'; - $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data) VALUES (?, ?, ?, ?, ?, ?, ?)"; - $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr); + $sql = "INSERT INTO sys_datalog (dbtable,dbidx,server_id,action,tstamp,user,data,session_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; + $app->db->query($sql, $db_table, $dbidx, $server_id, $action, time(), $username, $diffstr, session_id()); } return true; diff --git a/interface/web/login/index.php b/interface/web/login/index.php index 558896acb..47030e438 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -262,7 +262,7 @@ if(count($_POST) > 0) { $app->plugin->raiseEvent('login', $username); //* Save successfull login message to var - $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s'); + $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id(); $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); diff --git a/interface/web/monitor/lib/lang/de.lng b/interface/web/monitor/lib/lang/de.lng index 78954daee..f8fabe799 100644 --- a/interface/web/monitor/lib/lang/de.lng +++ b/interface/web/monitor/lib/lang/de.lng @@ -40,6 +40,7 @@ $wb['Show Clamav-Log'] = 'ClamAV Protokoll anzeigen'; $wb['Show ISPConfig-Log'] = 'ISPConfig Protokoll anzeigen'; $wb['Show RKHunter-Log'] = 'RKHunter Protokoll anzeigen'; $wb['Show Jobqueue'] = 'Jobwarteschlange anzeigen'; +$wb['Show Data Log History'] = 'Datalog-History anzeigen'; $wb['Show ISPC Cron-Log'] = 'Cron Protokoll anzeigen'; $wb['no_data_updates_txt'] = 'Derzeit stehen keine Daten über Updates zur Verfügung. Bitte später erneut überprüfen.'; $wb['no_data_raid_txt'] = 'Derzeit stehen keine Daten über RAID zur Verfügung. Bitte später erneut überprüfen.'; diff --git a/interface/web/monitor/lib/lang/en.lng b/interface/web/monitor/lib/lang/en.lng index f4dbbeff9..194bbc503 100644 --- a/interface/web/monitor/lib/lang/en.lng +++ b/interface/web/monitor/lib/lang/en.lng @@ -46,6 +46,7 @@ $wb['Show Clamav-Log'] = 'Show Clamav-Log'; $wb['Show ISPConfig-Log'] = 'Show ISPConfig-Log'; $wb['Show RKHunter-Log'] = 'Show RKHunter-Log'; $wb['Show Jobqueue'] = 'Show Jobqueue'; +$wb['Show Data Log History'] = 'Show Data Log History'; $wb['Show fail2ban-Log'] = 'Show fail2ban-Log'; $wb['Show MongoDB-Log'] = 'Show MongoDB-Log'; $wb['Show IPTables'] = 'Show IPTables'; diff --git a/interface/web/monitor/lib/module.conf.php b/interface/web/monitor/lib/module.conf.php index cd84ff3b1..ddb4972aa 100644 --- a/interface/web/monitor/lib/module.conf.php +++ b/interface/web/monitor/lib/module.conf.php @@ -26,6 +26,11 @@ $items[] = array( 'title' => 'Show Jobqueue', 'link' => 'monitor/datalog_list.php', 'html_id' => 'jobqueue'); +$items[] = array( 'title' => 'Show Data Log History', + 'target' => 'content', + 'link' => 'monitor/dataloghistory_list.php', + 'html_id' => 'dataloghistory'); + $module["nav"][] = array( 'title' => 'System State (All Servers)', 'open' => 1, 'items' => $items); diff --git a/interface/web/themes/default/assets/stylesheets/ispconfig.css b/interface/web/themes/default/assets/stylesheets/ispconfig.css index 5cd1bd141..f5e8c46ab 100644 --- a/interface/web/themes/default/assets/stylesheets/ispconfig.css +++ b/interface/web/themes/default/assets/stylesheets/ispconfig.css @@ -782,3 +782,16 @@ span.notification_text { font-family: inherit; color: white; } +.finediff { + font-family: monospace; +} +.finediff ins { + color: green; + background: #dfd; + text-decoration: none; +} +.finediff del { + color: red; + background: #fdd; + text-decoration: none; +} \ No newline at end of file -- GitLab From f08ea8ff939628438dcc93ce0882b8c38be90d8f Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 14:26:28 +0100 Subject: [PATCH 267/310] - fixed charset encoding --- .../lib/lang/de_dataloghistory_undo.lng | 6 +++--- .../lib/lang/de_dataloghistory_view.lng | 20 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng index c47a6c658..306f7c5ea 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -1,6 +1,6 @@ diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng index e91d341ca..81123a69c 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -9,18 +9,18 @@ $wb['table_txt'] = 'Tabelle'; $wb['action_txt'] = 'Aktion'; $wb['session_id_txt'] = 'Session-ID'; $wb['fields_txt'] = 'Felder'; -$wb['fields_inserted_txt'] = 'Eingefügte Felder'; -$wb['fields_updated_txt'] = 'Geänderte Felder'; -$wb['fields_deleted_txt'] = 'Gelöschte Felder'; -$wb['no_changes_txt'] = 'Keine Änderungen (Resync)'; -$wb['is_diff_txt'] = 'Die Änderungen werden hervorgehoben angezeigt'; -$wb['is_diff_inserts_txt'] = 'Einfügungen'; -$wb['is_diff_deletes_txt'] = 'Löschungen'; +$wb['fields_inserted_txt'] = 'Eingefügte Felder'; +$wb['fields_updated_txt'] = 'Geänderte Felder'; +$wb['fields_deleted_txt'] = 'Gelöschte Felder'; +$wb['no_changes_txt'] = 'Keine Änderungen (Resync)'; +$wb['is_diff_txt'] = 'Die Änderungen werden hervorgehoben angezeigt'; +$wb['is_diff_inserts_txt'] = 'Einfügungen'; +$wb['is_diff_deletes_txt'] = 'Löschungen'; $wb['field_txt'] = 'Feld'; $wb['value_txt'] = 'Wert'; $wb['old_txt'] = 'Alt'; $wb['new_txt'] = 'Neu'; -$wb['btn_cancel_txt'] = 'Zurück'; -$wb['undo_txt'] = 'Rückgängig machen'; -$wb['undo_confirmation_txt'] = 'Soll diese Änderung wirklich rückgängig gemacht werden?'; +$wb['btn_cancel_txt'] = 'Zurück'; +$wb['undo_txt'] = 'Rückgängig machen'; +$wb['undo_confirmation_txt'] = 'Soll diese Änderung wirklich rückgängig gemacht werden?'; ?> -- GitLab From 28bfeb97a4f75386a801ca8bcb7d0f1ddedca2b7 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 14:28:51 +0100 Subject: [PATCH 268/310] - datalog history view and restore added missing files --- interface/lib/classes/finediff.inc.php | 752 ++++++++++++++++++ interface/web/monitor/dataloghistory_list.php | 54 ++ interface/web/monitor/dataloghistory_undo.php | 70 ++ interface/web/monitor/dataloghistory_view.php | 130 +++ .../lib/lang/de_dataloghistory_list.lng | 8 + .../lib/lang/de_dataloghistory_undo.lng | 6 + .../lib/lang/de_dataloghistory_view.lng | 26 + .../lib/lang/en_dataloghistory_list.lng | 8 + .../lib/lang/en_dataloghistory_undo.lng | 6 + .../lib/lang/en_dataloghistory_view.lng | 26 + .../web/monitor/list/dataloghistory.list.php | 91 +++ .../monitor/templates/dataloghistory_list.htm | 54 ++ .../monitor/templates/dataloghistory_undo.htm | 17 + .../monitor/templates/dataloghistory_view.htm | 124 +++ 14 files changed, 1372 insertions(+) create mode 100644 interface/lib/classes/finediff.inc.php create mode 100644 interface/web/monitor/dataloghistory_list.php create mode 100644 interface/web/monitor/dataloghistory_undo.php create mode 100644 interface/web/monitor/dataloghistory_view.php create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/de_dataloghistory_view.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_list.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_undo.lng create mode 100644 interface/web/monitor/lib/lang/en_dataloghistory_view.lng create mode 100644 interface/web/monitor/list/dataloghistory.list.php create mode 100644 interface/web/monitor/templates/dataloghistory_list.htm create mode 100644 interface/web/monitor/templates/dataloghistory_undo.htm create mode 100644 interface/web/monitor/templates/dataloghistory_view.htm diff --git a/interface/lib/classes/finediff.inc.php b/interface/lib/classes/finediff.inc.php new file mode 100644 index 000000000..43b542f36 --- /dev/null +++ b/interface/lib/classes/finediff.inc.php @@ -0,0 +1,752 @@ +copy->insert +* command (swap) for when the inserted segment is exactly the same +* as the deleted one, and with only a copy operation in between. +* TODO: How often this case occurs? Is it worth it? Can only +* be done as a postprocessing method (->optimize()?) +*/ +abstract class FineDiffOp { + abstract public function getFromLen(); + abstract public function getToLen(); + abstract public function getOpcode(); + } + +class FineDiffDeleteOp extends FineDiffOp { + public function __construct($len) { + $this->fromLen = $len; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return 0; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + return 'd'; + } + return "d{$this->fromLen}"; + } + } + +class FineDiffInsertOp extends FineDiffOp { + public function __construct($text) { + $this->text = $text; + } + public function getFromLen() { + return 0; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "i:{$this->text}"; + } + return "i{$to_len}:{$this->text}"; + } + } + +class FineDiffReplaceOp extends FineDiffOp { + public function __construct($fromLen, $text) { + $this->fromLen = $fromLen; + $this->text = $text; + } + public function getFromLen() { + return $this->fromLen; + } + public function getToLen() { + return strlen($this->text); + } + public function getText() { + return $this->text; + } + public function getOpcode() { + if ( $this->fromLen === 1 ) { + $del_opcode = 'd'; + } + else { + $del_opcode = "d{$this->fromLen}"; + } + $to_len = strlen($this->text); + if ( $to_len === 1 ) { + return "{$del_opcode}i:{$this->text}"; + } + return "{$del_opcode}i{$to_len}:{$this->text}"; + } + } + +class FineDiffCopyOp extends FineDiffOp { + public function __construct($len) { + $this->len = $len; + } + public function getFromLen() { + return $this->len; + } + public function getToLen() { + return $this->len; + } + public function getOpcode() { + if ( $this->len === 1 ) { + return 'c'; + } + return "c{$this->len}"; + } + public function increase($size) { + return $this->len += $size; + } + } + +/** +* FineDiff ops +* +* Collection of ops +*/ +class FineDiffOps { + public function appendOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + $edits[] = new FineDiffCopyOp($from_len); + } + else if ( $opcode === 'd' ) { + $edits[] = new FineDiffDeleteOp($from_len); + } + else /* if ( $opcode === 'i' ) */ { + $edits[] = new FineDiffInsertOp(substr($from, $from_offset, $from_len)); + } + } + public $edits = array(); + } + +/** +* FineDiff class +* +* TODO: Document +* +*/ +class FineDiff { + + /**------------------------------------------------------------------------ + * + * Public section + * + */ + + /** + * Constructor + * ... + * The $granularityStack allows FineDiff to be configurable so that + * a particular stack tailored to the specific content of a document can + * be passed. + */ + public function __construct($from_text = '', $to_text = '', $granularityStack = null) { + // setup stack for generic text documents by default + $this->granularityStack = $granularityStack ? $granularityStack : FineDiff::$characterGranularity; + $this->edits = array(); + $this->from_text = $from_text; + $this->doDiff($from_text, $to_text); + } + + public function getOps() { + return $this->edits; + } + + public function getOpcodes() { + $opcodes = array(); + foreach ( $this->edits as $edit ) { + $opcodes[] = $edit->getOpcode(); + } + return implode('', $opcodes); + } + + public function renderDiffToHTML() { + $in_offset = 0; + ob_start(); + foreach ( $this->edits as $edit ) { + $n = $edit->getFromLen(); + if ( $edit instanceof FineDiffCopyOp ) { + FineDiff::renderDiffToHTMLFromOpcode('c', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffDeleteOp ) { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + } + else if ( $edit instanceof FineDiffInsertOp ) { + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + else /* if ( $edit instanceof FineDiffReplaceOp ) */ { + FineDiff::renderDiffToHTMLFromOpcode('d', $this->from_text, $in_offset, $n); + FineDiff::renderDiffToHTMLFromOpcode('i', $edit->getText(), 0, $edit->getToLen()); + } + $in_offset += $n; + } + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Return an opcodes string describing the diff between a "From" and a + * "To" string + */ + public static function getDiffOpcodes($from, $to, $granularities = null) { + $diff = new FineDiff($from, $to, $granularities); + return $diff->getOpcodes(); + } + + /**------------------------------------------------------------------------ + * Return an iterable collection of diff ops from an opcodes string + */ + public static function getDiffOpsFromOpcodes($opcodes) { + $diffops = new FineDiffOps(); + FineDiff::renderFromOpcodes(null, $opcodes, array($diffops,'appendOpcode')); + return $diffops->edits; + } + + /**------------------------------------------------------------------------ + * Re-create the "To" string from the "From" string and an "Opcodes" string + */ + public static function renderToTextFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderToTextFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 unsafe + */ + public static function renderDiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderFromOpcodes($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Render the diff to an HTML string -- UTF8 safe + */ + public static function renderUTF8DiffToHTMLFromOpcodes($from, $opcodes) { + ob_start(); + FineDiff::renderUTF8FromOpcode($from, $opcodes, array('FineDiff','renderDiffToHTMLFromOpcode')); + return ob_get_clean(); + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + public static function renderFromOpcodes($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else if ( $opcode === 'd' ) { // delete n characters from source + call_user_func($callback, 'd', $from, $from_offset, $n, ''); + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + call_user_func($callback, 'i', $opcodes, $opcodes_offset + 1, $n); + $opcodes_offset += 1 + $n; + } + } + } + + /**------------------------------------------------------------------------ + * Generic opcodes parser, user must supply callback for handling + * single opcode + */ + private static function renderUTF8FromOpcode($from, $opcodes, $callback) { + if ( !is_callable($callback) ) { + return; + } + $from_len = strlen($from); + $opcodes_len = strlen($opcodes); + $from_offset = $opcodes_offset = 0; + $last_to_chars = ''; + while ( $opcodes_offset < $opcodes_len ) { + $opcode = substr($opcodes, $opcodes_offset, 1); + $opcodes_offset++; + $n = intval(substr($opcodes, $opcodes_offset)); + if ( $n ) { + $opcodes_offset += strlen(strval($n)); + } + else { + $n = 1; + } + if ( $opcode === 'c' || $opcode === 'd' ) { + $beg = $from_offset; + $end = $from_offset + $n; + while ( $beg > 0 && (ord($from[$beg]) & 0xC0) === 0x80 ) { $beg--; } + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + if ( $opcode === 'c' ) { // copy n characters from source + call_user_func($callback, 'c', $from, $beg, $end - $beg, ''); + $last_to_chars = substr($from, $beg, $end - $beg); + } + else /* if ( $opcode === 'd' ) */ { // delete n characters from source + call_user_func($callback, 'd', $from, $beg, $end - $beg, ''); + } + $from_offset += $n; + } + else /* if ( $opcode === 'i' ) */ { // insert n characters from opcodes + $opcodes_offset += 1; + if ( strlen($last_to_chars) > 0 && (ord($opcodes[$opcodes_offset]) & 0xC0) === 0x80 ) { + $beg = strlen($last_to_chars) - 1; + while ( $beg > 0 && (ord($last_to_chars[$beg]) & 0xC0) === 0x80 ) { $beg--; } + $prefix = substr($last_to_chars, $beg); + } else { + $prefix = ''; + } + $end = $from_offset; + while ( $end < $from_len && (ord($from[$end]) & 0xC0) === 0x80 ) { $end++; } + $toInsert = $prefix . substr($opcodes, $opcodes_offset, $n) . substr($from, $end, $end - $from_offset); + call_user_func($callback, 'i', $toInsert, 0, strlen($toInsert)); + $opcodes_offset += $n; + $last_to_chars = $toInsert; + } + } + } + + /** + * Stock granularity stacks and delimiters + */ + + const paragraphDelimiters = "\n\r"; + public static $paragraphGranularity = array( + FineDiff::paragraphDelimiters + ); + const sentenceDelimiters = ".\n\r"; + public static $sentenceGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters + ); + const wordDelimiters = " \t.\n\r"; + public static $wordGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters + ); + const characterDelimiters = ""; + public static $characterGranularity = array( + FineDiff::paragraphDelimiters, + FineDiff::sentenceDelimiters, + FineDiff::wordDelimiters, + FineDiff::characterDelimiters + ); + + public static $textStack = array( + ".", + " \t.\n\r", + "" + ); + + /**------------------------------------------------------------------------ + * + * Private section + * + */ + + /** + * Entry point to compute the diff. + */ + private function doDiff($from_text, $to_text) { + $this->last_edit = false; + $this->stackpointer = 0; + $this->from_text = $from_text; + $this->from_offset = 0; + // can't diff without at least one granularity specifier + if ( empty($this->granularityStack) ) { + return; + } + $this->_processGranularity($from_text, $to_text); + } + + /** + * This is the recursive function which is responsible for + * handling/increasing granularity. + * + * Incrementally increasing the granularity is key to compute the + * overall diff in a very efficient way. + */ + private function _processGranularity($from_segment, $to_segment) { + $delimiters = $this->granularityStack[$this->stackpointer++]; + $has_next_stage = $this->stackpointer < count($this->granularityStack); + foreach ( FineDiff::doFragmentDiff($from_segment, $to_segment, $delimiters) as $fragment_edit ) { + // increase granularity + if ( $fragment_edit instanceof FineDiffReplaceOp && $has_next_stage ) { + $this->_processGranularity( + substr($this->from_text, $this->from_offset, $fragment_edit->getFromLen()), + $fragment_edit->getText() + ); + } + // fuse copy ops whenever possible + else if ( $fragment_edit instanceof FineDiffCopyOp && $this->last_edit instanceof FineDiffCopyOp ) { + $this->edits[count($this->edits)-1]->increase($fragment_edit->getFromLen()); + $this->from_offset += $fragment_edit->getFromLen(); + } + else { + /* $fragment_edit instanceof FineDiffCopyOp */ + /* $fragment_edit instanceof FineDiffDeleteOp */ + /* $fragment_edit instanceof FineDiffInsertOp */ + $this->edits[] = $this->last_edit = $fragment_edit; + $this->from_offset += $fragment_edit->getFromLen(); + } + } + $this->stackpointer--; + } + + /** + * This is the core algorithm which actually perform the diff itself, + * fragmenting the strings as per specified delimiters. + * + * This function is naturally recursive, however for performance purpose + * a local job queue is used instead of outright recursivity. + */ + private static function doFragmentDiff($from_text, $to_text, $delimiters) { + // Empty delimiter means character-level diffing. + // In such case, use code path optimized for character-level + // diffing. + if ( empty($delimiters) ) { + return FineDiff::doCharDiff($from_text, $to_text); + } + + $result = array(); + + // fragment-level diffing + $from_text_len = strlen($from_text); + $to_text_len = strlen($to_text); + $from_fragments = FineDiff::extractFragments($from_text, $delimiters); + $to_fragments = FineDiff::extractFragments($to_text, $delimiters); + + $jobs = array(array(0, $from_text_len, 0, $to_text_len)); + + $cached_array_keys = array(); + + while ( $job = array_pop($jobs) ) { + + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + + // catch easy cases first + $from_segment_length = $from_segment_end - $from_segment_start; + $to_segment_length = $to_segment_end - $to_segment_start; + if ( !$from_segment_length || !$to_segment_length ) { + if ( $from_segment_length ) { + $result[$from_segment_start * 4] = new FineDiffDeleteOp($from_segment_length); + } + else if ( $to_segment_length ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_length)); + } + continue; + } + + // find longest copy operation for the current segments + $best_copy_length = 0; + + $from_base_fragment_index = $from_segment_start; + + $cached_array_keys_for_current_segment = array(); + + while ( $from_base_fragment_index < $from_segment_end ) { + $from_base_fragment = $from_fragments[$from_base_fragment_index]; + $from_base_fragment_length = strlen($from_base_fragment); + // performance boost: cache array keys + if ( !isset($cached_array_keys_for_current_segment[$from_base_fragment]) ) { + if ( !isset($cached_array_keys[$from_base_fragment]) ) { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment] = array_keys($to_fragments, $from_base_fragment, true); + } + else { + $to_all_fragment_indices = $cached_array_keys[$from_base_fragment]; + } + // get only indices which falls within current segment + if ( $to_segment_start > 0 || $to_segment_end < $to_text_len ) { + $to_fragment_indices = array(); + foreach ( $to_all_fragment_indices as $to_fragment_index ) { + if ( $to_fragment_index < $to_segment_start ) { continue; } + if ( $to_fragment_index >= $to_segment_end ) { break; } + $to_fragment_indices[] = $to_fragment_index; + } + $cached_array_keys_for_current_segment[$from_base_fragment] = $to_fragment_indices; + } + else { + $to_fragment_indices = $to_all_fragment_indices; + } + } + else { + $to_fragment_indices = $cached_array_keys_for_current_segment[$from_base_fragment]; + } + // iterate through collected indices + foreach ( $to_fragment_indices as $to_base_fragment_index ) { + $fragment_index_offset = $from_base_fragment_length; + // iterate until no more match + for (;;) { + $fragment_from_index = $from_base_fragment_index + $fragment_index_offset; + if ( $fragment_from_index >= $from_segment_end ) { + break; + } + $fragment_to_index = $to_base_fragment_index + $fragment_index_offset; + if ( $fragment_to_index >= $to_segment_end ) { + break; + } + if ( $from_fragments[$fragment_from_index] !== $to_fragments[$fragment_to_index] ) { + break; + } + $fragment_length = strlen($from_fragments[$fragment_from_index]); + $fragment_index_offset += $fragment_length; + } + if ( $fragment_index_offset > $best_copy_length ) { + $best_copy_length = $fragment_index_offset; + $best_from_start = $from_base_fragment_index; + $best_to_start = $to_base_fragment_index; + } + } + $from_base_fragment_index += strlen($from_base_fragment); + // If match is larger than half segment size, no point trying to find better + // TODO: Really? + if ( $best_copy_length >= $from_segment_length / 2) { + break; + } + // no point to keep looking if what is left is less than + // current best match + if ( $from_base_fragment_index + $best_copy_length >= $from_segment_end ) { + break; + } + } + + if ( $best_copy_length ) { + $jobs[] = array($from_segment_start, $best_from_start, $to_segment_start, $best_to_start); + $result[$best_from_start * 4 + 2] = new FineDiffCopyOp($best_copy_length); + $jobs[] = array($best_from_start + $best_copy_length, $from_segment_end, $best_to_start + $best_copy_length, $to_segment_end); + } + else { + $result[$from_segment_start * 4 ] = new FineDiffReplaceOp($from_segment_length, substr($to_text, $to_segment_start, $to_segment_length)); + } + } + + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Perform a character-level diff. + * + * The algorithm is quite similar to doFragmentDiff(), except that + * the code path is optimized for character-level diff -- strpos() is + * used to find out the longest common subequence of characters. + * + * We try to find a match using the longest possible subsequence, which + * is at most the length of the shortest of the two strings, then incrementally + * reduce the size until a match is found. + * + * I still need to study more the performance of this function. It + * appears that for long strings, the generic doFragmentDiff() is more + * performant. For word-sized strings, doCharDiff() is somewhat more + * performant. + */ + private static function doCharDiff($from_text, $to_text) { + $result = array(); + $jobs = array(array(0, strlen($from_text), 0, strlen($to_text))); + while ( $job = array_pop($jobs) ) { + // get the segments which must be diff'ed + list($from_segment_start, $from_segment_end, $to_segment_start, $to_segment_end) = $job; + $from_segment_len = $from_segment_end - $from_segment_start; + $to_segment_len = $to_segment_end - $to_segment_start; + + // catch easy cases first + if ( !$from_segment_len || !$to_segment_len ) { + if ( $from_segment_len ) { + $result[$from_segment_start * 4 + 0] = new FineDiffDeleteOp($from_segment_len); + } + else if ( $to_segment_len ) { + $result[$from_segment_start * 4 + 1] = new FineDiffInsertOp(substr($to_text, $to_segment_start, $to_segment_len)); + } + continue; + } + if ( $from_segment_len >= $to_segment_len ) { + $copy_len = $to_segment_len; + while ( $copy_len ) { + $to_copy_start = $to_segment_start; + $to_copy_start_max = $to_segment_end - $copy_len; + while ( $to_copy_start <= $to_copy_start_max ) { + $from_copy_start = strpos(substr($from_text, $from_segment_start, $from_segment_len), substr($to_text, $to_copy_start, $copy_len)); + if ( $from_copy_start !== false ) { + $from_copy_start += $from_segment_start; + break 2; + } + $to_copy_start++; + } + $copy_len--; + } + } + else { + $copy_len = $from_segment_len; + while ( $copy_len ) { + $from_copy_start = $from_segment_start; + $from_copy_start_max = $from_segment_end - $copy_len; + while ( $from_copy_start <= $from_copy_start_max ) { + $to_copy_start = strpos(substr($to_text, $to_segment_start, $to_segment_len), substr($from_text, $from_copy_start, $copy_len)); + if ( $to_copy_start !== false ) { + $to_copy_start += $to_segment_start; + break 2; + } + $from_copy_start++; + } + $copy_len--; + } + } + // match found + if ( $copy_len ) { + $jobs[] = array($from_segment_start, $from_copy_start, $to_segment_start, $to_copy_start); + $result[$from_copy_start * 4 + 2] = new FineDiffCopyOp($copy_len); + $jobs[] = array($from_copy_start + $copy_len, $from_segment_end, $to_copy_start + $copy_len, $to_segment_end); + } + // no match, so delete all, insert all + else { + $result[$from_segment_start * 4] = new FineDiffReplaceOp($from_segment_len, substr($to_text, $to_segment_start, $to_segment_len)); + } + } + ksort($result, SORT_NUMERIC); + return array_values($result); + } + + /** + * Efficiently fragment the text into an array according to + * specified delimiters. + * No delimiters means fragment into single character. + * The array indices are the offset of the fragments into + * the input string. + * A sentinel empty fragment is always added at the end. + * Careful: No check is performed as to the validity of the + * delimiters. + */ + private static function extractFragments($text, $delimiters) { + // special case: split into characters + if ( empty($delimiters) ) { + $chars = str_split($text, 1); + $chars[strlen($text)] = ''; + return $chars; + } + $fragments = array(); + $start = $end = 0; + for (;;) { + $end += strcspn($text, $delimiters, $end); + $end += strspn($text, $delimiters, $end); + if ( $end === $start ) { + break; + } + $fragments[$start] = substr($text, $start, $end - $start); + $start = $end; + } + $fragments[$start] = ''; + return $fragments; + } + + /** + * Stock opcode renderers + */ + private static function renderToTextFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' || $opcode === 'i' ) { + echo substr($from, $from_offset, $from_len); + } + } + + private static function renderDiffToHTMLFromOpcode($opcode, $from, $from_offset, $from_len) { + if ( $opcode === 'c' ) { + echo htmlspecialchars(substr($from, $from_offset, $from_len)); + } + else if ( $opcode === 'd' ) { + $deletion = substr($from, $from_offset, $from_len); + if ( strcspn($deletion, " \n\r") === 0 ) { + $deletion = str_replace(array("\n","\r"), array('\n','\r'), $deletion); + } + echo '', htmlspecialchars($deletion), ''; + } + else /* if ( $opcode === 'i' ) */ { + echo '', htmlspecialchars(substr($from, $from_offset, $from_len)), ''; + } + } + } + diff --git a/interface/web/monitor/dataloghistory_list.php b/interface/web/monitor/dataloghistory_list.php new file mode 100644 index 000000000..cab8da8a3 --- /dev/null +++ b/interface/web/monitor/dataloghistory_list.php @@ -0,0 +1,54 @@ +auth->check_module_permissions('monitor'); + +$app->uses('listform_actions'); + +$app->listform_actions->SQLOrderBy = "ORDER BY sys_datalog.tstamp DESC, sys_datalog.datalog_id DESC"; + +$app->listform_actions->onLoad(); + + +?> diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php new file mode 100644 index 000000000..5ff08faa0 --- /dev/null +++ b/interface/web/monitor/dataloghistory_undo.php @@ -0,0 +1,70 @@ +auth->check_module_permissions('monitor'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_undo.htm'); + +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_undo.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$dbidx = explode(':', $record['dbidx']); + +$old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); + +if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); +} else { + $app->tpl->setVar('success', false); +} + +$app->tpl_defaults(); +$app->tpl->pparse(); + +?> diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php new file mode 100644 index 000000000..e3b5e7b63 --- /dev/null +++ b/interface/web/monitor/dataloghistory_view.php @@ -0,0 +1,130 @@ +auth->check_module_permissions('monitor'); + +$app->load('finediff'); + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', 'templates/dataloghistory_view.htm'); + +$app->load_language_file('web/monitor/lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +require('lib/lang/'.$_SESSION['s']['language'].'_dataloghistory_view.lng'); +$app->tpl->setvar($wb); + +$id = intval($_GET['id']); + +$record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); + +$out['id'] = $id; + +$out['timestamp'] = date($app->lng('conf_format_datetime'), $record['tstamp']); +$out['table'] = $record['dbtable']; + +$out['action_char'] = $record['action']; +$out['action_name'] = $app->lng($record['action']); + +$out['session_id'] = $record['session_id']; + +if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); +} + +switch ($record['action']) { + case 'i': + $inserts = array(); + foreach ($data['new'] as $key=>$value) { + $inserts[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('inserts', $inserts); + break; + case 'u': + $updates = array(); + foreach ($data['new'] as $key=>$value) { + if ($value != $data['old'][$key]) { + $old = $data['old'][$key]; + $new = $value; + $changes = show_diff_if_needed($old, $new); + $updates[] = array( + 'key' => $key, + 'is_diff' => $changes['is_diff'], + 'old' => nl2br($changes['old']), + 'new' => nl2br($changes['new']), + 'diff' => nl2br($changes['diff']), + ); + } + } + if (count($updates) > 0) { + $app->tpl->setLoop('updates', $updates); + } else { + $out['no_changes'] = true; + } + break; + case 'd': + $deletes = array(); + foreach ($data['old'] as $key=>$value) { + $deletes[] = array( + 'key' => $key, + 'value' => nl2br($value), + ); + } + $app->tpl->setLoop('deletes', $deletes); + break; +} + +$app->tpl->setVar($out); + +$app->tpl_defaults(); +$app->tpl->pparse(); + +function show_diff_if_needed($old, $new) { + global $app; + + $diff_min_lines = 6; + + if (substr_count($old, "\n") >= $diff_min_lines || substr_count($new, "\n") >= $diff_min_lines) { + $opcodes = FineDiff::getDiffOpcodes($old, $new); + $html = FineDiff::renderUTF8DiffToHTMLFromOpcodes($old, $opcodes); + return array('is_diff'=>true, 'old'=>'', 'new'=>'', 'diff'=>$html); + } else { + return array('is_diff'=>false, 'old'=>$old, 'new'=>$new, 'diff'=>''); + } +} + +?> diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_list.lng b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng new file mode 100644 index 000000000..2c2b6c9fc --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng new file mode 100644 index 000000000..306f7c5ea --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng new file mode 100644 index 000000000..81123a69c --- /dev/null +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_list.lng b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng new file mode 100644 index 000000000..9f9afd634 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_list.lng @@ -0,0 +1,8 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng new file mode 100644 index 000000000..258d88669 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -0,0 +1,6 @@ + diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng new file mode 100644 index 000000000..df9ddd286 --- /dev/null +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -0,0 +1,26 @@ + diff --git a/interface/web/monitor/list/dataloghistory.list.php b/interface/web/monitor/list/dataloghistory.list.php new file mode 100644 index 000000000..1757125e8 --- /dev/null +++ b/interface/web/monitor/list/dataloghistory.list.php @@ -0,0 +1,91 @@ + "tstamp", + 'datatype' => "DATETIME", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => ""); + + +$liste['item'][] = array( 'field' => 'server_id', + 'datatype' => 'INTEGER', + 'formtype' => 'SELECT', + 'op' => '=', + 'prefix' => '', + 'suffix' => '', + 'datasource' => array ( 'type' => 'SQL', + 'querystring' => 'SELECT server_id,server_name FROM server WHERE {AUTHSQL} ORDER BY server_name', + 'keyfield'=> 'server_id', + 'valuefield'=> 'server_name' + ), + 'width' => '', + 'value' => ''); + +$liste["item"][] = array( 'field' => "action", + 'datatype' => "VARCHAR", + 'formtype' => "SELECT", + 'op' => "=", + 'prefix' => "", + 'suffix' => "", + 'width' => "", + 'value' => array('i' => "Insert", 'u' => "Update", 'd' => "Delete")); + + +$liste["item"][] = array( 'field' => "dbtable", + 'datatype' => "VARCHAR", + 'formtype' => "TEXT", + 'op' => "like", + 'prefix' => "%", + 'suffix' => "%", + 'width' => "", + 'value' => ""); + + +?> diff --git a/interface/web/monitor/templates/dataloghistory_list.htm b/interface/web/monitor/templates/dataloghistory_list.htm new file mode 100644 index 000000000..0cd3c4f4d --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_list.htm @@ -0,0 +1,54 @@ + + + +

+ + +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{tmpl_var name='search_limit'}
  + +
{tmpl_var name="tstamp"}{tmpl_var name="server_id"}{tmpl_var name="action"}{tmpl_var name="dbtable"}
{tmpl_var name='globalsearch_noresults_text_txt'}
+
+ +
diff --git a/interface/web/monitor/templates/dataloghistory_undo.htm b/interface/web/monitor/templates/dataloghistory_undo.htm new file mode 100644 index 000000000..997231a88 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_undo.htm @@ -0,0 +1,17 @@ + + + + + + + + + + +
+
+ +
+
diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm new file mode 100644 index 000000000..0ce595e26 --- /dev/null +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -0,0 +1,124 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +

+
+ +

+
+ +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
( / )
+
+
+
+ +
+
+ + {tmpl_var name='undo_txt'} + + +
+
-- GitLab From 880e4c71f5eeffdf2fa4f1f0b2bad391f4778408 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 15:07:54 +0100 Subject: [PATCH 269/310] - added undelete to datalog history viewer --- interface/lib/classes/db_mysql.inc.php | 3 ++ interface/web/monitor/dataloghistory_undo.php | 34 ++++++++++++++----- interface/web/monitor/dataloghistory_view.php | 1 + .../lib/lang/de_dataloghistory_undo.lng | 1 + .../lib/lang/en_dataloghistory_undo.lng | 1 + .../monitor/templates/dataloghistory_view.htm | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 8443d106b..c4764cb55 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -759,6 +759,9 @@ class db $old_rec = array(); $index_value = $this->insertID(); + if(!$index_value && isset($insert_data[$index_field])) { + $index_value = $insert_data[$index_field]; + } $new_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $this->datalogSave($tablename, 'INSERT', $index_field, $index_value, $old_rec, $new_rec); diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php index 5ff08faa0..455f8c9d0 100644 --- a/interface/web/monitor/dataloghistory_undo.php +++ b/interface/web/monitor/dataloghistory_undo.php @@ -50,18 +50,36 @@ $dbidx = explode(':', $record['dbidx']); $old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); -if (is_array($old_record)) { - if(!$data = unserialize(stripslashes($record['data']))) { - $data = unserialize($record['data']); +if($record['action'] === 'u') { + if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); + } else { + $app->tpl->setVar('success', false); } +} elseif($record['action'] === 'd') { + if(is_array($old_record)) { + $app->tpl->setVar('success', false); + $app->tpl->setVar('error_txt', $wb['error_undelete_txt']); + } else { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } - $new_record = $data['old']; + $new_record = $data['old']; + /* TODO: maybe check some data, e. g. server_id -> server still there?, sys_groupid -> sys_group/sys_user still there? */ - $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + $app->db->datalogInsert($record['dbtable'], $new_record, $dbidx[0]); - $app->tpl->setVar('success', true); -} else { - $app->tpl->setVar('success', false); + $app->tpl->setVar('success', true); + } } $app->tpl_defaults(); diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index e3b5e7b63..2b5ea1e03 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -109,6 +109,7 @@ switch ($record['action']) { } $app->tpl->setVar($out); +$app->tpl->setVar('can_undo', ($out['action_char'] === 'u' || $out['action_char'] === 'd')); $app->tpl_defaults(); $app->tpl->pparse(); diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng index 306f7c5ea..9bae987d5 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Datalog-History-Eintrag'; $wb['success_txt'] = 'Erfolgreich zurückgesetzt'; $wb['error_txt'] = 'Fehler beim Zurücksetzen: Eintrag existiert nicht mehr'; +$wb['error_undelete_txt'] = 'Fehler beim Wiederherstellen: Eintrag mit dieser Id existiert bereits'; $wb['btn_cancel_txt'] = 'Zurück'; ?> diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng index 258d88669..0e040a3e7 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Data Log History Entry'; $wb['success_txt'] = 'Undo successful'; $wb['error_txt'] = 'Error during undo: Record does not exist anymore'; +$wb['error_undelete_txt'] = 'Error during undelete: Record with primary id already existing.'; $wb['btn_cancel_txt'] = 'Back'; ?> diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm index 0ce595e26..4ba82bbf0 100644 --- a/interface/web/monitor/templates/dataloghistory_view.htm +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -116,7 +116,7 @@
- + {tmpl_var name='undo_txt'} -- GitLab From fcfeb80627ba486e48dc659a445ab9bf6473c1a5 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 14 Dec 2018 16:25:13 +0100 Subject: [PATCH 270/310] - added datalog undelete to viewer --- interface/lib/classes/db_mysql.inc.php | 3 ++ interface/web/monitor/dataloghistory_undo.php | 34 ++++++++++++++----- interface/web/monitor/dataloghistory_view.php | 1 + .../lib/lang/de_dataloghistory_undo.lng | 1 + .../lib/lang/en_dataloghistory_undo.lng | 1 + .../monitor/templates/dataloghistory_view.htm | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/interface/lib/classes/db_mysql.inc.php b/interface/lib/classes/db_mysql.inc.php index 8443d106b..c4764cb55 100644 --- a/interface/lib/classes/db_mysql.inc.php +++ b/interface/lib/classes/db_mysql.inc.php @@ -759,6 +759,9 @@ class db $old_rec = array(); $index_value = $this->insertID(); + if(!$index_value && isset($insert_data[$index_field])) { + $index_value = $insert_data[$index_field]; + } $new_rec = $this->queryOneRecord("SELECT * FROM ?? WHERE ?? = ?", $tablename, $index_field, $index_value); $this->datalogSave($tablename, 'INSERT', $index_field, $index_value, $old_rec, $new_rec); diff --git a/interface/web/monitor/dataloghistory_undo.php b/interface/web/monitor/dataloghistory_undo.php index 5ff08faa0..455f8c9d0 100644 --- a/interface/web/monitor/dataloghistory_undo.php +++ b/interface/web/monitor/dataloghistory_undo.php @@ -50,18 +50,36 @@ $dbidx = explode(':', $record['dbidx']); $old_record = $app->db->queryOneRecord('SELECT * FROM ?? WHERE ??=?', $record['dbtable'], $dbidx[0], $dbidx[1]); -if (is_array($old_record)) { - if(!$data = unserialize(stripslashes($record['data']))) { - $data = unserialize($record['data']); +if($record['action'] === 'u') { + if (is_array($old_record)) { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } + + $new_record = $data['old']; + + $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + + $app->tpl->setVar('success', true); + } else { + $app->tpl->setVar('success', false); } +} elseif($record['action'] === 'd') { + if(is_array($old_record)) { + $app->tpl->setVar('success', false); + $app->tpl->setVar('error_txt', $wb['error_undelete_txt']); + } else { + if(!$data = unserialize(stripslashes($record['data']))) { + $data = unserialize($record['data']); + } - $new_record = $data['old']; + $new_record = $data['old']; + /* TODO: maybe check some data, e. g. server_id -> server still there?, sys_groupid -> sys_group/sys_user still there? */ - $app->db->datalogUpdate($record['dbtable'], $new_record, $dbidx[0], $dbidx[1]); + $app->db->datalogInsert($record['dbtable'], $new_record, $dbidx[0]); - $app->tpl->setVar('success', true); -} else { - $app->tpl->setVar('success', false); + $app->tpl->setVar('success', true); + } } $app->tpl_defaults(); diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index e3b5e7b63..2b5ea1e03 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -109,6 +109,7 @@ switch ($record['action']) { } $app->tpl->setVar($out); +$app->tpl->setVar('can_undo', ($out['action_char'] === 'u' || $out['action_char'] === 'd')); $app->tpl_defaults(); $app->tpl->pparse(); diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng index 306f7c5ea..9bae987d5 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Datalog-History-Eintrag'; $wb['success_txt'] = 'Erfolgreich zurückgesetzt'; $wb['error_txt'] = 'Fehler beim Zurücksetzen: Eintrag existiert nicht mehr'; +$wb['error_undelete_txt'] = 'Fehler beim Wiederherstellen: Eintrag mit dieser Id existiert bereits'; $wb['btn_cancel_txt'] = 'Zurück'; ?> diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng index 258d88669..0e040a3e7 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_undo.lng @@ -2,5 +2,6 @@ $wb['list_head_txt'] = 'Data Log History Entry'; $wb['success_txt'] = 'Undo successful'; $wb['error_txt'] = 'Error during undo: Record does not exist anymore'; +$wb['error_undelete_txt'] = 'Error during undelete: Record with primary id already existing.'; $wb['btn_cancel_txt'] = 'Back'; ?> diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm index 0ce595e26..4ba82bbf0 100644 --- a/interface/web/monitor/templates/dataloghistory_view.htm +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -116,7 +116,7 @@
- + {tmpl_var name='undo_txt'} -- GitLab From f66e8c9fdea10f7d3928516b1dd70f5b262070f4 Mon Sep 17 00:00:00 2001 From: Game Over! Date: Fri, 14 Dec 2018 21:47:59 +0100 Subject: [PATCH 271/310] Add new "Farsi/Persian" translation file --- interface/lib/lang/fa.lng | 166 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 interface/lib/lang/fa.lng diff --git a/interface/lib/lang/fa.lng b/interface/lib/lang/fa.lng new file mode 100644 index 000000000..c961d7a69 --- /dev/null +++ b/interface/lib/lang/fa.lng @@ -0,0 +1,166 @@ + \ No newline at end of file -- GitLab From ecd82f7b7602eef501614d7aa147f67f6325aa2b Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 14:44:49 +0100 Subject: [PATCH 272/310] Add new "fa_resellers_list.lng" translation file --- interface/web/client/lib/lang/fa_resellers_list.lng | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_resellers_list.lng diff --git a/interface/web/client/lib/lang/fa_resellers_list.lng b/interface/web/client/lib/lang/fa_resellers_list.lng new file mode 100644 index 000000000..3f0c881ca --- /dev/null +++ b/interface/web/client/lib/lang/fa_resellers_list.lng @@ -0,0 +1,11 @@ + \ No newline at end of file -- GitLab From cdb7fb003d9e01f7bcc3bc8362a9079b3e133fda Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 14:47:09 +0100 Subject: [PATCH 273/310] Add new "fa_domain_list.lng" file --- interface/web/client/lib/lang/fa_domain_list.lng | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_domain_list.lng diff --git a/interface/web/client/lib/lang/fa_domain_list.lng b/interface/web/client/lib/lang/fa_domain_list.lng new file mode 100644 index 000000000..a6434f5a4 --- /dev/null +++ b/interface/web/client/lib/lang/fa_domain_list.lng @@ -0,0 +1,6 @@ + \ No newline at end of file -- GitLab From 64d71adde15d0d200ae300b222b55cee4d4459f5 Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:07:13 +0100 Subject: [PATCH 274/310] Add new "fa_domain.lng" file --- interface/web/client/lib/lang/fa_domain.lng | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_domain.lng diff --git a/interface/web/client/lib/lang/fa_domain.lng b/interface/web/client/lib/lang/fa_domain.lng new file mode 100644 index 000000000..7288bfee2 --- /dev/null +++ b/interface/web/client/lib/lang/fa_domain.lng @@ -0,0 +1,6 @@ + -- GitLab From e054c36ea9e9d0c5e449448656a3ce90661a9d0d Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:08:16 +0100 Subject: [PATCH 275/310] Add new "fa_clients_list.lng" file --- interface/web/client/lib/lang/fa_clients_list.lng | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_clients_list.lng diff --git a/interface/web/client/lib/lang/fa_clients_list.lng b/interface/web/client/lib/lang/fa_clients_list.lng new file mode 100644 index 000000000..0285e38c6 --- /dev/null +++ b/interface/web/client/lib/lang/fa_clients_list.lng @@ -0,0 +1,14 @@ + \ No newline at end of file -- GitLab From 67848045bd6f55c86eb86ff69ca822b38d8158c0 Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:09:08 +0100 Subject: [PATCH 276/310] Add new "fa_client_template_list.lng" file --- interface/web/client/lib/lang/fa_client_template_list.lng | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_client_template_list.lng diff --git a/interface/web/client/lib/lang/fa_client_template_list.lng b/interface/web/client/lib/lang/fa_client_template_list.lng new file mode 100644 index 000000000..150a9055c --- /dev/null +++ b/interface/web/client/lib/lang/fa_client_template_list.lng @@ -0,0 +1,7 @@ + -- GitLab From 6ba86a76ad0331783c802c191bdfeb9702ecb2d2 Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:09:55 +0100 Subject: [PATCH 277/310] Add new "fa_client_message_template_list.lng" file --- .../web/client/lib/lang/fa_client_message_template_list.lng | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_client_message_template_list.lng diff --git a/interface/web/client/lib/lang/fa_client_message_template_list.lng b/interface/web/client/lib/lang/fa_client_message_template_list.lng new file mode 100644 index 000000000..13ee5d914 --- /dev/null +++ b/interface/web/client/lib/lang/fa_client_message_template_list.lng @@ -0,0 +1,5 @@ + \ No newline at end of file -- GitLab From 91db5d14e9f77e89b798431dac822616f5e8d72f Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:10:51 +0100 Subject: [PATCH 278/310] Add new "fa_client_message.lng" file --- .../web/client/lib/lang/fa_client_message.lng | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_client_message.lng diff --git a/interface/web/client/lib/lang/fa_client_message.lng b/interface/web/client/lib/lang/fa_client_message.lng new file mode 100644 index 000000000..b11ce20ff --- /dev/null +++ b/interface/web/client/lib/lang/fa_client_message.lng @@ -0,0 +1,20 @@ + \ No newline at end of file -- GitLab From 358620bf27898c933449af476aad3478a0c2878a Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:11:45 +0100 Subject: [PATCH 279/310] Add new "fa_client_circle_list.lng" file --- .../web/client/lib/lang/fa_client_circle_list.lng | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_client_circle_list.lng diff --git a/interface/web/client/lib/lang/fa_client_circle_list.lng b/interface/web/client/lib/lang/fa_client_circle_list.lng new file mode 100644 index 000000000..e51ad368e --- /dev/null +++ b/interface/web/client/lib/lang/fa_client_circle_list.lng @@ -0,0 +1,10 @@ + \ No newline at end of file -- GitLab From bbfff551f8a366c29290dd5603238eac646cd274 Mon Sep 17 00:00:00 2001 From: Game Over! Date: Mon, 17 Dec 2018 16:12:33 +0100 Subject: [PATCH 280/310] Add new "fa_client_circle.lng" file --- interface/web/client/lib/lang/fa_client_circle.lng | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 interface/web/client/lib/lang/fa_client_circle.lng diff --git a/interface/web/client/lib/lang/fa_client_circle.lng b/interface/web/client/lib/lang/fa_client_circle.lng new file mode 100644 index 000000000..72fb91642 --- /dev/null +++ b/interface/web/client/lib/lang/fa_client_circle.lng @@ -0,0 +1,9 @@ + \ No newline at end of file -- GitLab From c53767c43a7f5ef130dd970b1897f7f6d258f8c3 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Mon, 17 Dec 2018 19:06:08 +0100 Subject: [PATCH 281/310] - missing changes from previous merge --- .../classes/plugin_webserver_nginx.inc.php | 840 +++++ .../plugins-available/apache2_plugin.inc.php | 3035 +--------------- server/plugins-available/nginx_plugin.inc.php | 3064 +---------------- 3 files changed, 948 insertions(+), 5991 deletions(-) create mode 100644 server/lib/classes/plugin_webserver_nginx.inc.php diff --git a/server/lib/classes/plugin_webserver_nginx.inc.php b/server/lib/classes/plugin_webserver_nginx.inc.php new file mode 100644 index 000000000..3002f4b0f --- /dev/null +++ b/server/lib/classes/plugin_webserver_nginx.inc.php @@ -0,0 +1,840 @@ +getconf->get_server_config($conf['server_id'], 'web'); + + // PHP-FPM + // Support for multiple PHP versions + if($data['new']['php'] == 'php-fpm'){ + if(trim($data['new']['fastcgi_php_version']) != ''){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } else { + if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ + $default_php_fpm = false; + list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); + if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; + } else { + $default_php_fpm = true; + } + } + + if($default_php_fpm){ + $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); + } else { + $pool_dir = $custom_php_fpm_pool_dir; + } + $pool_dir = trim($pool_dir); + if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; + $pool_name = 'web'.$data['new']['domain_id']; + $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); + if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; + + if($data['new']['php_fpm_chroot'] == 'y'){ + $php_fpm_chroot = 1; + $php_fpm_nochroot = 0; + } else { + $php_fpm_chroot = 0; + $php_fpm_nochroot = 1; + } + if($data['new']['php_fpm_use_socket'] == 'y'){ + $use_tcp = 0; + $use_socket = 1; + } else { + $use_tcp = 1; + $use_socket = 0; + } + $tpl->setVar('use_tcp', $use_tcp); + $tpl->setVar('use_socket', $use_socket); + $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); + $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); + $fpm_socket = $socket_dir.$pool_name.'.sock'; + $tpl->setVar('fpm_socket', $fpm_socket); + $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); + $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; + + // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. + if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; + + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processRewriteRules(&$tpl, &$data, &$vhost_data) { + global $app, $conf; + + $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); + + // Custom rewrite rules + $final_rewrite_rules = array(); + + if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { + $custom_rewrite_rules = trim($data['new']['rewrite_rules']); + $custom_rewrites_are_valid = true; + // use this counter to make sure all curly brackets are properly closed + $if_level = 0; + // Make sure we only have Unix linebreaks + $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); + $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); + $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); + if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ + foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ + // ignore comments + if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // empty lines + if(trim($custom_rewrite_rule_line) == ''){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // rewrite + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // if + if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // if - check for files, directories, etc. + if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level += 1; + continue; + } + // break + if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code [ text ] + if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // return code URL + // return URL + if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // set + if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + continue; + } + // closing curly bracket + if(trim($custom_rewrite_rule_line) == '}'){ + $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); + $if_level -= 1; + continue; + } + $custom_rewrites_are_valid = false; + break; + } + } + if(!$custom_rewrites_are_valid || $if_level != 0){ + $final_rewrite_rules = array(); + } + } + $tpl->setLoop('rewrite_rules', $final_rewrite_rules); + + // Rewrite rules + $own_rewrite_rules = array(); + $rewrite_rules = array(); + $local_rewrite_rules = array(); + if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { + if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; + if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ + if($data['new']['redirect_type'] != 'proxy'){ + $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); + } else { + $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); + } + } + + // Custom proxy directives + if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $data['new']['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + switch($data['new']['subdomain']) { + case 'www': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + case '*': + $exclude_own_hostname = ''; + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + + //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + break; + default: + if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path + $exclude_own_hostname = ''; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); + break; + } + $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + } else { // URL - check if URL is local + $tmp_redirect_path = $data['new']['redirect_path']; + if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ + // URL is local + if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); + if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; + //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; + $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; + break; + } else { + $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + $exclude_own_hostname = $tmp_redirect_path_parts['host']; + } + } else { + // external URL + $rewrite_exclude = '(.?)/'; + if($data['new']['redirect_type'] == 'proxy'){ + $vhost_data['use_proxy'] = 'y'; + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + } + unset($tmp_redirect_path); + unset($tmp_redirect_path_parts); + } + $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), + 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], + 'rewrite_target' => $data['new']['redirect_path'], + 'rewrite_exclude' => $rewrite_exclude, + 'rewrite_subdir' => $rewrite_subdir, + 'exclude_own_hostname' => $exclude_own_hostname, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); + } + } + + $server_alias = array(); + $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); + $client_id = intval($client['client_id']); + unset($client); + + // get autoalias + $auto_alias = $web_config['website_autoalias']; + if($auto_alias != '') { + // get the client username + $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); + $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); + $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); + $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); + unset($client); + unset($aa_search); + unset($aa_replace); + $server_alias[] .= $auto_alias; + } + + // get alias domains (co-domains and subdomains) + $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); + $alias_seo_redirects = array(); + switch($data['new']['subdomain']) { + case 'www': + $server_alias[] = 'www.'.$data['new']['domain']; + break; + case '*': + $server_alias[] = '*.'.$data['new']['domain']; + break; + } + if(is_array($aliases)) { + foreach($aliases as $alias) { + switch($alias['subdomain']) { + case 'www': + $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; + break; + case '*': + $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; + break; + default: + $server_alias[] .= $alias['domain']; + break; + } + $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); + + if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { + // Add SEO redirects for alias domains + if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects[] = $tmp_seo_redirects; + } + } + } + + // Custom proxy directives + if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ + $final_proxy_directives = array(); + $proxy_directives = $alias['proxy_directives']; + // Make sure we only have Unix linebreaks + $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); + $proxy_directives = str_replace("\r", "\n", $proxy_directives); + $proxy_directive_lines = explode("\n", $proxy_directives); + if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ + foreach($proxy_directive_lines as $proxy_directive_line){ + $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); + } + } + } else { + $final_proxy_directives = false; + } + + + // Local Rewriting (inside vhost server {} container) + if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; + switch($alias['subdomain']) { + case 'www': + // example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + + // www.example.com + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + case '*': + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', + 'local_redirect_operator' => '~*', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + break; + default: + $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], + 'local_redirect_operator' => '=', + 'local_redirect_exclude' => $rewrite_exclude, + 'local_redirect_target' => $alias['redirect_path'], + 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); + } + } + + // External Rewriting (extra server {} containers) + if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { + if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; + if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ + if($alias['redirect_type'] != 'proxy'){ + $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); + } else { + $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); + } + } + + switch($alias['subdomain']) { + case 'www': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www', 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + case '*': + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + break; + default: + if($alias['redirect_type'] == 'proxy'){ + $tmp_redirect_path = $alias['redirect_path']; + $tmp_redirect_path_parts = parse_url($tmp_redirect_path); + $rewrite_subdir = $tmp_redirect_path_parts['path']; + if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); + if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; + if($rewrite_subdir == '/') $rewrite_subdir = ''; + } + + if($alias['redirect_type'] != 'proxy'){ + if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); + } + if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); + else $domain_rule = $alias['domain']; + // Add SEO redirects for alias domains + $alias_seo_redirects2 = array(); + if($alias['seo_redirect'] != ''){ + if(substr($alias['domain'], 0, 2) === '*.'){ + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', false, 'nginx'); + } else { + $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none', 'nginx'); + } + if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ + $alias_seo_redirects2[] = $tmp_seo_redirects; + } + } + $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, + 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], + 'rewrite_target' => $alias['redirect_path'], + 'rewrite_subdir' => $rewrite_subdir, + 'proxy_directives' => $final_proxy_directives, + 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), + 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), + 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); + } + } + } + } + + //* If we have some alias records + if(count($server_alias) > 0) { + $server_alias_str = ''; + foreach($server_alias as $tmp_alias) { + $server_alias_str .= $tmp_alias; + } + unset($tmp_alias); + + $tpl->setVar('alias', trim($server_alias_str)); + } else { + $tpl->setVar('alias', ''); + } + + if(count($rewrite_rules) > 0) { + $tpl->setLoop('redirects', $rewrite_rules); + } + if(count($own_rewrite_rules) > 0) { + $tpl->setLoop('own_redirects', $own_rewrite_rules); + } + if(count($local_rewrite_rules) > 0) { + $tpl->setLoop('local_redirects', $local_rewrite_rules); + } + if(count($alias_seo_redirects) > 0) { + $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); + } + return; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + * @param array $fpm_data + */ + public function processCustomDirectives(&$tpl, &$data, &$vhost_data, $fpm_data) { + global $app, $conf; + + // Custom nginx directives + if(intval($data['new']['directive_snippets_id']) > 0){ + $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); + if(isset($snippet['snippet'])){ + $nginx_directives = $snippet['snippet']; + } else { + $nginx_directives = $data['new']['nginx_directives']; + } + } else { + $nginx_directives = $data['new']['nginx_directives']; + } + + $final_nginx_directives = array(); + if($data['new']['enable_pagespeed'] == 'y'){ + // if PageSpeed is already enabled, don't add configuration again + if(stripos($nginx_directives, 'pagespeed') !== false){ + $vhost_data['enable_pagespeed'] = false; + } else { + $vhost_data['enable_pagespeed'] = true; + } + } else { + $vhost_data['enable_pagespeed'] = false; + } + + $web_folder = $app->plugin_webserver_base->getWebFolder($data, 'web'); + $username = escapeshellcmd($data['new']['system_user']); + $groupname = escapeshellcmd($data['new']['system_group']); + + // folder_directive_snippets + if(trim($data['new']['folder_directive_snippets']) != ''){ + $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); + $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); + $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); + + if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ + foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ + list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); + + $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); + $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); + + if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ + if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; + if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); + + $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); + if(isset($master_snippet['snippet'])){ + $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); + $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); + $nginx_directives .= "\n\n".$master_snippet['snippet']; + + // create folder it it does not exist + if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ + $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); + $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); + $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); + } + } + } + } + } + } + + // use vLib for template logic + if(trim($nginx_directives) != '') { + $nginx_directives_new = ''; + $ngx_conf_tpl = new tpl(); + $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); + file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); + $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); + $ngx_conf_tpl->setVar('use_tcp', $fpm_data['use_tcp']); + $ngx_conf_tpl->setVar('use_socket', $fpm_data['use_socket']); + $ngx_conf_tpl->setVar('fpm_socket', $fpm_data['fpm_socket']); + $ngx_conf_tpl->setVar($vhost_data); + $nginx_directives_new = $ngx_conf_tpl->grab(); + if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); + if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; + unset($nginx_directives_new); + } + + // Make sure we only have Unix linebreaks + $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); + $nginx_directives = str_replace("\r", "\n", $nginx_directives); + $nginx_directive_lines = explode("\n", $nginx_directives); + if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ + $trans = array( + '{DOCROOT}' => $vhost_data['web_document_root_www'], + '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], + '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_data['fpm_socket'] : '127.0.0.1:'.$fpm_data['fpm_port']).';' + ); + foreach($nginx_directive_lines as $nginx_directive_line){ + $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); + } + } + $tpl->setLoop('nginx_directives', $final_nginx_directives); + + return; + } + + + public function getStatsFolder($data) { + $stats_web_folder = 'web'; + if($data['new']['type'] == 'vhost'){ + if($data['new']['web_folder'] != ''){ + if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); + if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); + } + $stats_web_folder .= '/'.$data['new']['web_folder']; + } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { + $stats_web_folder = $data['new']['web_folder']; + } + return $stats_web_folder; + } + + /** + * This method may alter the $tpl template as well as $data and/or $vhost_data array! + * + * @param tpl $tpl + * @param array $data + * @param array $vhost_data + */ + public function processStatsAuth(&$tpl, &$data, &$vhost_data) { + + $stats_web_folder = $this->getStatsFolder($data); + + //* Create basic http auth for website statistics + $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); + + // Create basic http auth for other directories + $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); + if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); + + return; + } + + private function _create_web_folder_auth_configuration($website){ + global $app; + + //* Create the domain.auth file which is included in the vhost configuration file + + $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); + $basic_auth_locations = array(); + if(is_array($website_auth_locations) && !empty($website_auth_locations)){ + foreach($website_auth_locations as $website_auth_location){ + if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); + if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); + if($website_auth_location['path'] != ''){ + $website_auth_location['path'] .= '/'; + } + $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], + 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); + } + } + return $basic_auth_locations; + } + + public function testWebserverConfig() { + global $app; + + // if no output is given, check again + $tmp_output = null; + $tmp_retval = 0; + exec('nginx -t 2>&1', $tmp_output, $tmp_retval); + if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ + $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); + $app->dbmaster->datalogError(implode("\n", $tmp_output)); + } + unset($tmp_output, $tmp_retval); + } +} diff --git a/server/plugins-available/apache2_plugin.inc.php b/server/plugins-available/apache2_plugin.inc.php index 68b29b222..ccb7a81e0 100644 --- a/server/plugins-available/apache2_plugin.inc.php +++ b/server/plugins-available/apache2_plugin.inc.php @@ -30,2544 +30,123 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class apache2_plugin { - var $plugin_name = 'apache2_plugin'; - var $class_name = 'apache2_plugin'; + var $plugin_name; + var $class_name; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; - //* This function is called during ispconfig installation to determine - // if a symlink shall be created for this plugin. - function onInstall() { - global $conf; - - if($conf['services']['web'] == true) { - return true; - } else { - return false; - } - - } - - - /* - This function is called when the plugin is loaded - */ - - function onLoad() { - global $app; - - /* - Register for the events - */ - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); - - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('server_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_update', $this->plugin_name, 'server_ip'); - - $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav'); - $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav'); - - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); - - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); - - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); - - $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete'); - - $app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed'); - } - - private function get_master_php_ini_content($web_data) { - global $app, $conf; - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - $php_ini_content = ''; - $master_php_ini_path = ''; - - if($web_data['php'] == 'mod') { - $master_php_ini_path = $web_config['php_ini_path_apache']; - } else { - // check for custom php - if($web_data['fastcgi_php_version'] != '') { - $tmp = explode(':', $web_data['fastcgi_php_version']); - if(isset($tmp[2])) { - $tmppath = $tmp[2]; - if(substr($tmppath, -7) != 'php.ini') { - if(substr($tmppath, -1) != '/') $tmppath .= '/'; - $tmppath .= 'php.ini'; - } - if(file_exists($tmppath)) { - $master_php_ini_path = $tmppath; - } - unset($tmppath); - } - unset($tmp); - } - - if(!$master_php_ini_path) { - if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } elseif($web_data['php'] == 'php-fpm' && file_exists($web_config['php_fpm_ini_path'])) { - $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"]; - } else { - $master_php_ini_path = $web_config['php_ini_path_cgi']; - } - } - } - - // Resolve inconsistant path settings - if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) { - $master_php_ini_path .= '/php.ini'; - } - - // Load the custom php.ini content - if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) { - $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n"; - } - - return $php_ini_content; - } - - // Handle php.ini changes - function php_ini_changed($event_name, $data) { - global $app, $conf; - - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - /* $data contains an array with these keys: - * file -> full path of changed php_ini - * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm or '' for all except 'mod') - * php_version -> php ini path that changed (additional php versions) - */ - - $param = ''; - $qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''"; - if($data['mode'] == 'mod') { - $qrystr .= " AND php = 'mod'"; - } elseif($data['mode'] == 'fast-cgi') { - $qrystr .= " AND php = 'fast-cgi'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version']; - } - } elseif($data['mode'] == 'php-fpm') { - $qrystr .= " AND php = 'php-fpm'"; - if($data['php_version']) { - $qrystr .= " AND fastcgi_php_version LIKE ?"; - $param = '%:' . $data['php_version'] . ':%'; - } - } else { - $qrystr .= " AND php != 'mod' AND php != 'fast-cgi'"; - } - - - //** Get all the webs - $web_domains = $app->db->queryAllRecords($qrystr, $param); - foreach($web_domains as $web_data) { - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user']; - $web_folder = 'web'; - if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') { - $web_folder = $web_data['web_folder']; - $custom_php_ini_dir .= '_' . $web_folder; - } - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($web_data); - - if(intval($web_data['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $web_data['custom_php_ini'] .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini'])); - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - $app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG); - } - - if(count($web_domains) > 0) { - //* We do not check the apache config here - we only changed the php.ini - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); - } else { - $apache_chrooted = false; - } - - $app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG); - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } else { - $app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG); - } - } - - // Handle the creation of SSL certificates - function ssl($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - $bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Create a SSL Certificate, but only if this is not a mirror server. - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file, $key_file.'.bak'); - $app->system->chmod($key_file.'.bak', 0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2, $key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak', 0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_md = sha256 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " - " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." - " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." - " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - ";//challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file2 = escapeshellcmd($key_file2); - $openssl_cmd_key_file2 = $key_file2; - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $key_file = escapeshellcmd($key_file); - $openssl_cmd_key_file = $key_file; - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - $openssl_cmd_csr_file = $csr_file; - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - $openssl_cmd_crt_file = $crt_file; - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); - exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); - }; - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - - } - - $app->system->chmod($key_file2, 0400); - $app->system->chmod($key_file, 0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->system->file_get_contents($csr_file); - $ssl_cert = $app->system->file_get_contents($crt_file); - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - - //* Check that the SSL key is not password protected - if($data["new"]["ssl_action"] == 'save') { - if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* and check that SSL cert does not contain subdomain of domain acme.invalid - if($data["new"]["ssl_action"] == 'save') { - $tmp = array(); - $crt_data = ''; - exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); - $crt_data = implode("\n",$tmp); - if(stristr($crt_data,'.acme.invalid')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file, $key_file.'~'); - $app->system->chmod($key_file.'~', 0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2, $key_file2.'~'); - $app->system->chmod($key_file2.'~', 0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); - if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); - if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) { - // In apache 2.4.8 and newer, the ssl crt file contains the bundle, so we need no separate bundle file - $tmp_data = ''; - if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n"; - if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"]; - if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data); - } else { - // Write separate crt and bundle file - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); - if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]); - } - - //* Write the key file, if field is empty then import the key into the db - if(trim($data["new"]["ssl_key"]) != '') { - $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); - $app->system->chmod($key_file, 0400); - } else { - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key, $data['new']['domain']); - } - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); - $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - $app->system->unlink($bundle_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - } - - - function insert($event_name, $data) { - global $app, $conf; - - $this->action = 'insert'; - // just run the update function - $this->update($event_name, $data); - - - } - - - function update($event_name, $data) { - global $app, $conf; - - if($this->action != 'insert') $this->action = 'update'; - - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name, $data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); - } else { - $apache_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); - return 0; - } - if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false - || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { - $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty', LOGLEVEL_WARN); - return 0; - } - - $web_folder = 'web'; - $log_folder = 'log'; - $old_web_folder = 'web'; - $old_log_folder = 'log'; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - // new one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - $web_folder = $data['new']['web_folder']; - $log_folder .= '/' . $subdomain_host; - unset($tmp); - - if(isset($data['old']['parent_domain_id'])) { - // old one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $old_web_folder = $data['old']['web_folder']; - $old_log_folder .= '/' . $subdomain_host; - unset($tmp); - } - } - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - //* Remove protection of old folders - $app->system->web_folder_protection($data['old']['document_root'], false); - - if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { - //* Move the site data - $tmp_docroot = explode('/', $data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/', $tmp_docroot); - - $tmp_docroot = explode('/', $data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/', $tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); - } - - //* Unmount the old log directory bfore we move the log dir - //exec('fuser -km '.escapeshellcmd($old_dir.'/log')); - exec('umount -l '.escapeshellcmd($data['old']['document_root'].'/log')); - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'], false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - /* - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - */ - - $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - - if($web_config['network_filesystem'] == 'y') { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } - - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'], false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - - if(!is_dir($data['new']['document_root'].'/.ssh')) { - $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); - $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); - $app->system->chown($data['new']['document_root'].'/.ssh', $username); - $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); - } - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - } - - - // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - - //* Unmount log directory - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; - $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); - } - - $app->system->web_folder_protection($data['new']['document_root'], true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { - // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - //* Copy the web skeleton files only when there is no index.ph or index.html file yet - if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - //} - } else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } else { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - $mb_soft = $data['new']['hd_quota']; - $mb_hard = $mb_soft + 1; - } else { - $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; - } - - // get the primitive folder for document_root and the filesystem, will need it later. - $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); - $file_system = $df_output[0]; - $primitive_root = $df_output[1]; - - if($file_system == 'xfs') { - exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); - - // xfs only supports timers globally, not per user. - exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); - - unset($project_uid, $username_position, $xfs_projects); - unset($primitive_root, $df_output, $mb_hard, $mb_soft); - } else { - if($app->system->is_installed('setquota')) { - exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - } - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'], false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0711); - $app->system->chmod($data['new']['document_root'].'/webdav', 0710); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - - // make tmp directory writable for Apache and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $app->system->_exec($command); - } - - //* if we have a chrooted Apache environment - if($apache_chrooted) { - $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the apache user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user'])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0755); - $app->system->chmod($data['new']['document_root'].'/webdav', 0755); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); - - // make temp directory writable for Apache and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - $app->system->chown($data['new']['document_root'].'/webdav', $username); - $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname); - } - } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && - (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { - - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'], true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - } - - //* Write the custom php.ini file, if custom_php_ini fieled is not empty - $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user']; - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $custom_php_ini_dir .= '_' . $web_folder; - if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf'); - - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - if(trim($data['new']['fastcgi_php_version']) != ''){ - list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir); - if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1); - } - - //* Create custom php.ini - if(trim($data['new']['custom_php_ini']) != '') { - $has_custom_php_ini = true; - if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir); - - $php_ini_content = $this->get_master_php_ini_content($data['new']); - $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini'])); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $php_ini_content .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content); - } else { - $has_custom_php_ini = false; - if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini'); - } - - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('vhost.conf.master'); - - $vhost_data = $data['new']; - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - $vhost_data['security_level'] = $web_config['security_level']; - $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override']; - $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $vhost_data['ssl_domain'] = $data['new']['ssl_domain']; - $vhost_data['has_custom_php_ini'] = $has_custom_php_ini; - $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir); - $vhost_data['logging'] = $web_config['logging']; - - // Custom Apache directives - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $vhost_data['apache_directives'] = $snippet['snippet']; - } - } - // Make sure we only have Unix linebreaks - $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']); - $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']); - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'] - ); - $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans); - - $app->uses('letsencrypt'); - // Check if a SSL cert exists - $tmp = $app->letsencrypt->get_website_certificate_paths($data); - $domain = $tmp['domain']; - $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; - $crt_file = $tmp['crt']; - $bundle_file = $tmp['bundle']; - unset($tmp); - - $data['new']['ssl_domain'] = $domain; - $vhost_data['ssl_domain'] = $domain; - $vhost_data['ssl_crt_file'] = $crt_file; - $vhost_data['ssl_key_file'] = $key_file; - $vhost_data['ssl_bundle_file'] = $bundle_file; - - //* Generate Let's Encrypt SSL certificat - if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server - ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration - || ($data['old']['domain'] != $data['new']['domain']) // we have domain update - || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain - || $this->update_letsencrypt == true - )) { - - $success = $app->letsencrypt->request_certificates($data); - if($success) { - /* we don't need to store it. - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } else { - $data['new']['ssl_letsencrypt'] = 'n'; - if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); - } - } - - if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1; - - // HTTP/2.0 ? - $vhost_data['enable_http2'] = 'n'; - if($vhost_data['enable_spdy'] == 'y'){ - // check if apache supports http_v2 - exec("2>&1 apachectl -M | grep http2_module", $tmp_output, $tmp_retval); - if($tmp_retval == 0){ - $vhost_data['enable_http2'] = 'y'; - } - unset($tmp_output, $tmp_retval); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new']); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - $tpl->setVar($vhost_data); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // Rewrite rules - $rewrite_rules = array(); - $rewrite_wildcard_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8); - } else { - $rewrite_target = $data['new']['redirect_path']; - $rewrite_target_ssl = $data['new']['redirect_path']; - } - /* Disabled path extension - if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { - $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; - } - */ - - switch($data['new']['subdomain']) { - case 'www': - $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_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')); - break; - case '*': - $rewrite_wildcard_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')); - break; - default: - $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')); - } - } - - $server_alias = array(); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain']; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain']; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - switch($alias['subdomain']) { - case 'www': - $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain']; - break; - case '*': - $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain']; - break; - default: - $server_alias[] .= $alias['domain']; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - - // Rewriting - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') { - if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - $rewrite_target = 'http'.substr($alias['redirect_path'], 8); - $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8); - } else { - $rewrite_target = $alias['redirect_path']; - $rewrite_target_ssl = $alias['redirect_path']; - } - /* Disabled the path extension - if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') { - $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/'; - } - */ - - switch($alias['subdomain']) { - case 'www': - $rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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.'.$alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - case '*': - $rewrite_wildcard_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($alias['domain']), - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - break; - default: - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2)); - else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']); - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':'['.$alias['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')); - } - } - } - } - - //* If we have some alias records - if($server_alias) { - //* begin a new ServerAlias line after 32 alias domains to avoid apache bugs - $server_alias_str = 'ServerAlias '.$server_alias[0]; - for($n=1;$nsetVar('alias', $server_alias_str); - unset($server_alias_str); - unset($n); - } else { - $tpl->setVar('alias', ''); - } - - if (count($rewrite_wildcard_rules) > 0) $rewrite_rules = array_merge($rewrite_rules, $rewrite_wildcard_rules); // Append wildcard rules to the end of rules - - if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0 || $data['new']['rewrite_to_https'] == 'y') { - $tpl->setVar('rewrite_enabled', 1); - } else { - $tpl->setVar('rewrite_enabled', 0); - } - - //$tpl->setLoop('redirects',$rewrite_rules); - - /** - * install fast-cgi starter script and add script aliasd config - * first we create the script directory if not already created, then copy over the starter script - * settings are copied over from the server ini config for now - * TODO: Create form for fastcgi configs per site. - */ - - - if ($data['new']['php'] == 'fast-cgi') { - - $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - - if (!is_dir($fastcgi_starter_path)) { - $app->system->mkdirpath($fastcgi_starter_path); - //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); - - - $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG); - } - - //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path)); - $app->system->chown($fastcgi_starter_path, $data['new']['system_user']); - $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']); - if($web_config['security_level'] == 10) { - $app->system->chmod($fastcgi_starter_path, 0755); - } else { - $app->system->chmod($fastcgi_starter_path, 0550); - } - - $fcgi_tpl = new tpl(); - $fcgi_tpl->newTemplate('php-fcgi-starter.master'); - $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion()); - $fcgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // Support for multiple PHP versions (FastCGI) - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_fastcgi_php = false; - if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/'; - } else { - $default_fastcgi_php = true; - } - - if($has_custom_php_ini) { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); - } else { - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); - } else { - $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir)); - } - } - $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); - $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children'])); - $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests'])); - if($default_fastcgi_php){ - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin'])); - } else { - $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable)); - } - $fcgi_tpl->setVar('security_level', intval($web_config['security_level'])); - $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain'])); - - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); - - $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab()); - unset($fcgi_tpl); - - $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG); - - if($web_config['security_level'] == 10) { - $app->system->chmod($fcgi_starter_script, 0755); - } else { - $app->system->chmod($fcgi_starter_script, 0550); - } - $app->system->chown($fcgi_starter_script, $data['new']['system_user']); - $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']); - - $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']); - $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path); - $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']); - $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']); - - } else { - //remove the php fastgi starter script if available - $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : ''); - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path); - if($data['old']['type'] == 'vhost') { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path); - } else { - if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script); - } - } - } - - - - /** - * PHP-FPM - */ - // Support for multiple PHP versions - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - - /** - * install cgi starter script and add script alias to config. - * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!) - * first we create the script directory if not already created, then copy over the starter script. - * TODO: we have to fetch the data from the server-settings. - */ - if ($data['new']['php'] == 'cgi') { - //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi'); - - $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : ''); - $cgi_config['cgi_bin'] = '/usr/bin/php-cgi'; - - $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']); - $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path); - - if (!is_dir($cgi_starter_path)) { - $app->system->mkdirpath($cgi_starter_path); - $app->system->chown($cgi_starter_path, $data['new']['system_user']); - $app->system->chgrp($cgi_starter_path, $data['new']['system_group']); - if($web_config['security_level'] == 10) { - $app->system->chmod($cgi_starter_path, 0755); - } else { - $app->system->chmod($cgi_starter_path, 0550); - } - - $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG); - } - - $cgi_tpl = new tpl(); - $cgi_tpl->newTemplate('php-cgi-starter.master'); - $cgi_tpl->setVar('apache_version', $app->system->getapacheversion()); - $cgi_tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - // This works because PHP "rewrites" a symlink to the physical path - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir']; - $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir)); - $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root'])); - - // This will NOT work! - //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']); - $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']); - $cgi_tpl->setVar('security_level', $web_config['security_level']); - - $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini); - if($has_custom_php_ini) { - $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir)); - } else { - $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path'])); - } - - $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab()); - unset($cgi_tpl); - - $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG); - - - if($web_config['security_level'] == 10) { - $app->system->chmod($cgi_starter_script, 0755); - } else { - $app->system->chmod($cgi_starter_script, 0550); - } - $app->system->chown($cgi_starter_script, $data['new']['system_user']); - $app->system->chgrp($cgi_starter_script, $data['new']['system_group']); - - $tpl->setVar('cgi_starter_path', $cgi_starter_path); - $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].(($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') ? '_web' . $data['new']['domain_id'] : '')); - - } - - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~'); - - //* create empty vhost array - $vhosts = array(); - - //* Add vhost for ipv4 IP - - //* use ip-mapping for web-mirror - if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { - $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; - $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); - $data['new']['ip_address'] = $newip['destination_ip']; - unset($newip); - } - - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv4 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443'); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects; - if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects); - $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Add vhost for IPv6 IP - if($data['new']['ipv6_address'] != '') { - //* rewrite ipv6 on mirrors - /* chang $conf to $web_config */ - if ($web_config['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($web_config['serverconfig']['server']['v6_prefix']) && $web_config['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $web_config['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - } - } - if($data['new']['ipv6_address'] == '*') $data['new']['ipv6_address'] = '::'; - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr); - - //* Add vhost for ipv6 IP with SSL - if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443'); - if(count($rewrite_rules) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules); - $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects; - if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){ - for($i=0;$i 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects); - $vhosts[] = $tmp_vhost_arr; - unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects); - $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG); - } - } - - //* Set the vhost loop - $tpl->setLoop('vhosts', $vhosts); - - //* Write vhost file - $app->system->file_put_contents($vhost_file, $tpl->grab()); - $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - /* - * maybe we have some webdav - user. If so, add them... - */ - $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav'); - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file, $vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); - } - - //* Create .htaccess and .htpasswd file for website statistics - //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) { - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats'); - $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user"; - $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file); - $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755); - unset($ht_file); - //} - - if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file); - $app->system->web_folder_protection($data['new']['document_root'], true); - $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - $this->awstats_update($data, $web_config); - } - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - - if($web_config['check_apache_config'] == 'y') { - //* Test if apache starts with the new configuration file - $apache_online_status_before_restart = $this->_checkTcp('localhost', 80); - $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the apache status again - $apache_online_status_after_restart = false; - sleep(2); - for($i = 0; $i < 5; $i++) { - $apache_online_status_after_restart = $this->_checkTcp('localhost', 80); - if($apache_online_status_after_restart) break; - sleep(1); - } - //* Check if apache restarted successfully if it was online before - $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) { - $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - // if no output is given, check again - $webserver_binary = ''; - exec('which apache2ctl apache2 httpd2 httpd apache 2>/dev/null', $webserver_check_output, $webserver_check_retval); - if($webserver_check_retval == 0){ - $webserver_binary = reset($webserver_check_output); - } - if($webserver_binary != ''){ - exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - } - $app->system->copy($vhost_file, $vhost_file.'.err'); - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~', $vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - if($this->ssl_certificate_changed === true) { - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file, $key_file.'.err'); - $app->system->chmod($key_file.'.err', 0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2, $key_file2.'.err'); - $app->system->chmod($key_file2.'.err', 0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); - if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); - if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file); - - $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); - } - - $app->services->restartService('httpd', 'restart'); - } - } else { - //* We do not check the apache config after changes (is faster) - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); - - //* Unset action to clean it for next processed vhost. - $this->action = ''; - } - - function delete($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; - } else { - $apache_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // get log folder from /etc/fstab - /* - $bind_mounts = $app->system->file_get_contents('/etc/fstab'); - $bind_mount_lines = explode("\n", $bind_mounts); - if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ - foreach($bind_mount_lines as $bind_mount_line){ - $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); - $bind_mount_parts = explode(' ', $bind_mount_line); - if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ - if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ - $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); - } - } - } - } - */ - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - } - } else { - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount -l '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - } - - // remove letsencrypt if it exists (renew will always fail otherwise) - - $old_domain = $data['old']['domain']; - if(substr($old_domain, 0, 2) === '*.') { - // wildcard domain not yet supported by letsencrypt! - $old_domain = substr($old_domain, 2); - } - $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; - @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - // just run the update function - $this->update($event_name, $data); - - } else { - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot, '..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains and alias with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data, $web_config); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // delete the symlink - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($apache_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data, $web_config); - } - - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $app->system->web_folder_protection($parent_web_document_root, true); - } - - if($apache_chrooted) { - $app->services->restartServiceDelayed('httpd', 'restart'); - } else { - // request a httpd reload when all records have been processed - $app->services->restartServiceDelayed('httpd', 'reload'); - } - - //* Delete the web-backups - if($data['old']['type'] == 'vhost') { - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - $backup_dir = $server_config['backup_dir']; - $mount_backup = true; - if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { - //* mount backup directory, if necessary - if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; - - if($mount_backup){ - $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; - //** do not use rm -rf $web_backup_dir because database(s) may exits - exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); - //* cleanup database - $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; - $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - - $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); - } - } - } - } - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); + public function __construct() { + $this->plugin_name = get_class($this); + $this->class_name = get_class($this); } - //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered - function server_ip($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('apache_ispconfig.conf.master'); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('logging', $web_config['logging']); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - $records = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ? AND virtualhost = 'y'", $conf['server_id']); - - $records_out= array(); - if(is_array($records)) { - foreach($records as $rec) { - if($rec['ip_type'] == 'IPv6') { - $ip_address = '['.$rec['ip_address'].']'; - } else { - $ip_address = $rec['ip_address']; - } - $ports = explode(',', $rec['virtualhost_port']); - if(is_array($ports)) { - foreach($ports as $port) { - $port = intval($port); - if($port > 0 && $port < 65536 && $ip_address != '') { - $records_out[] = array('ip_address' => $ip_address, 'port' => $port); - } - } - } - } - } - - - if(count($records_out) > 0) { - $tpl->setLoop('ip_adresses', $records_out); - } - - $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf'); - $app->system->file_put_contents($vhost_file, $tpl->grab()); - $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - } - - //* Create or update the .htaccess folder protection - function web_folder_user($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; + //* This function is called during ispconfig installation to determine + // if a symlink shall be created for this plugin. + function onInstall() { + global $conf; - //* Check if the resulting path is inside the docroot - if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); + if($conf['services']['web'] == true) { + return true; + } else { return false; } - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); - } + } - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd', 0751); - $app->system->chown($folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } + /* + This function is called when the plugin is loaded + */ - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); - $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); - } - } + function onLoad() { + global $app; + /* + Register for the events + */ + $app->plugin_webserver_base->registerEvents('apache'); + } - //* Create the .htaccess file - //if(!is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + // Handle php.ini changes + function php_ini_changed($event_name, $data) { + global $app; - if(file_exists($folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($folder_path.'.htaccess'); + $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'apache'); - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } - unset($old_content); + } - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->system->chmod($folder_path.'.htaccess', 0751); - $app->system->chown($folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - //} + // Handle the creation of SSL certificates + function ssl($event_name, $data) { + global $app; + $app->plugin_webserver_base->eventSsl($event_name, $data, 'apache'); } - //* Remove .htaccess and .htpasswd file, when folder protection is removed - function web_folder_delete($event_name, $data) { - global $app, $conf; - $folder_id = $data['old']['web_folder_id']; + function insert($event_name, $data) { + $this->action = 'insert'; + // just run the update function + $this->update($event_name, $data); + } - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } + function update($event_name, $data) { + global $app; - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; + if($this->action != 'insert') $this->action = 'update'; $app->plugin_webserver_base->eventUpdate($event_name, $data, $this->action, 'apache'); - //* Check if the resulting path is inside the docroot - if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - //* Remove .htaccess file - if(is_file($folder_path.'.htaccess')) { - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - - $ht_file = $app->system->file_get_contents($folder_path.'.htaccess'); - - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } - - if(trim($ht_file) == '') { - $app->system->unlink($folder_path.'.htaccess'); - $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + //* Unset action to clean it for next processed vhost. + $this->action = ''; } - //* Update folder protection, when path has been changed - function web_folder_update($event_name, $data) { - global $app, $conf; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); - if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; - - if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); - if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); - - $begin_marker = '### ISPConfig folder protection begin ###'; - $end_marker = "### ISPConfig folder protection end ###\n\n"; - - if($data['old']['path'] != $data['new']['path']) { - - - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - //* delete old .htaccess file - if(is_file($old_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess'); - - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } + function delete($event_name, $data) { + global $app; - if(trim($ht_file) == '') { - $app->system->unlink($old_folder_path.'.htaccess'); - $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventDelete($event_name, $data, 'apache'); + } - } + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered + function server_ip($event_name, $data) { + global $app; - //* Create the .htaccess file - if($data['new']['active'] == 'y') { - $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker; + $app->plugin_webserver_base->eventServerIp($event_name, $data, 'apache'); - if(file_exists($new_folder_path.'.htaccess')) { - $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess'); + } - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) { - $ht_file = str_replace($matches[0], $ht_file, $old_content); - } else { - $ht_file .= $old_content; - } - } + //* Create or update the .htaccess folder protection + function web_folder_user($event_name, $data) { + global $app; - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->system->chmod($new_folder_path.'.htaccess', 0751); - $app->system->chown($new_folder_path.'.htaccess', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']); - $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($new_folder_path.'.htpasswd'); - $app->system->chmod($new_folder_path.'.htpasswd', 0751); - $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'apache'); - //* Remove .htaccess file - if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) { - $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess'); + } - if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) { - $ht_file = str_replace($matches[0], '', $ht_file); - } else { - $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file); - } + //* Remove .htaccess and .htpasswd file, when folder protection is removed + function web_folder_delete($event_name, $data) { + global $app; - if(trim($ht_file) == '') { - $app->system->unlink($new_folder_path.'.htaccess'); - $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } else { - $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file); - $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'apache'); + } + //* Update folder protection, when path has been changed + function web_folder_update($event_name, $data) { + global $app; + $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'apache'); } public function ftp_user_delete($event_name, $data) { - global $app, $conf; + global $app; $ftpquota_file = $data['old']['dir'].'/.ftpquota'; if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); - } - - /** * This function is called when a Webdav-User is inserted, updated or deleted. * @@ -2598,10 +177,10 @@ class apache2_plugin { /* Check if this is a chrooted setup */ if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $apache_chrooted = true; + $is_chrooted = true; $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG); } else { - $apache_chrooted = false; + $is_chrooted = false; } //* We dont want to have relative paths here @@ -2659,12 +238,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($apache_chrooted) { + if($is_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -2691,12 +270,12 @@ class apache2_plugin { * Next step, patch the vhost - file */ $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost'); - $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); + $app->plugin_webserver_base->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav'); /* * Last, restart apache */ - if($apache_chrooted) { + if($is_chrooted) { $app->services->restartServiceDelayed('httpd', 'restart'); } else { // request a httpd reload when all records have been processed @@ -2713,7 +292,7 @@ class apache2_plugin { * @param string $filename The name of the digest-file * @param string $username The name of the webdav-user * @param string $authname The name of the realm - * @param string $pwd The password-hash of the user + * @param string $pwdhash The password-hash of the user */ private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) { global $app; @@ -2761,475 +340,11 @@ class apache2_plugin { } } - /** - * This function patches the vhost-file and adds all webdav - user. - * This function is written, because the creation of the vhost - file is sophisticated and - * i don't want to make it more "heavy" by also adding this code too... - * @author Oliver Vogel - * @param string $fileName The Name of the .vhost-File (path included) - * @param string $webdavRoot The root of the webdav-folder - */ - private function _patchVhostWebdav($fileName, $webdavRoot) { - global $app; - $in = fopen($fileName, 'r'); - $output = ''; - $inWebdavSection = false; - //* read line by line and search for the username and authname - while ($line = fgets($in)) { - //* is the "replace-comment" found... - if (trim($line) == '# WEBDAV BEGIN') { - //* The begin of the webdav - section is found, so ignore all lines til the end is found - $inWebdavSection = true; - $output .= "# WEBDAV BEGIN\n"; - //* add all the webdav-dirs to the webdav-section - $files = @scandir($webdavRoot); - if(is_array($files)) { - foreach($files as $file) { - if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) { - //* found a htdigest - file, so add it to webdav - $fn = substr($file, 0, strlen($file) - strlen('.htdigest')); - $output .= "\n"; - $output .= "Alias /webdav/$fn $webdavRoot/$fn\n"; - $output .= "\n"; - $output .= "DAV On\n"; - $output .= "BrowserMatch MSIE AuthDigestEnableQueryStringHack=On\n"; - $output .= "AuthType Digest\n"; - if($fn != '' && $fn != '/') { - $output .= "AuthName \"" . $fn . "\"\n"; - } else { - $output .= "AuthName \"Restricted Area\"\n"; - } - $output .= "AuthUserFile $webdavRoot/$file\n"; - $output .= "Require valid-user\n"; - $output .= "Options +Indexes\n"; - if($app->system->getapacheversion()<=2.2) - $output .= "Order allow,deny\nAllow from all\n"; - $output .= "\n"; - } - } - } - } - //* is the "replace-comment-end" found... - if (trim($line) == '# WEBDAV END') { - //* The end of the webdav - section is found, so stop ignoring - $inWebdavSection = false; - } - //* Write the line to the output, if it is not in the section - if (!$inWebdavSection) { - $output .= $line; - } - } - fclose($in); - //* Now lets write the new file - $app->system->file_put_contents($fileName, $output); - } - - //* Update the awstats configuration file - private function awstats_update ($data, $web_config) { - global $app; - - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - if (is_file($awstats_conf_dir."/awstats.conf")) { - $include_file = $awstats_conf_dir."/awstats.conf"; - } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { - $include_file = $awstats_conf_dir."/awstats.model.conf"; - } - $content .= "Include \"".$include_file."\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - if (isset($include_file)) { - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); - } else { - $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); - } - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } - } - - //* Delete the awstats configuration file - private function awstats_delete ($data, $web_config) { - global $app; - - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); - } - } - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { - global $app, $conf; - $pool_dir = trim($pool_dir); - //$reload = false; - - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] != 'php-fpm'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] == 'php-fpm'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - //if($reload == true) $app->services->restartService('php-fpm','reload'); - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - $tpl->setVar('apache_version', $app->system->getapacheversion()); - $tpl->setVar('apache_full_version', $app->system->getapacheversion(true)); - - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_listen_mode', '0660'); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_user', $data['new']['system_user']); - $tpl->setVar('fpm_listen_group', $web_config['group']); - $tpl->setVar('fpm_domain', $data['new']['domain']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level', $web_config['security_level']); - $tpl->setVar('domain', $data['new']['domain']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'apache' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $custom_session_save_path = false; - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting, 0, 1) == ';') continue; - if(substr($ini_setting, 0, 1) == '#') continue; - if(substr($ini_setting, 0, 2) == '//') continue; - list($key, $value) = explode('=', $ini_setting, 2); - $value = trim($value); - if($value != ''){ - $key = trim($key); - if($key == 'session.save_path') $custom_session_save_path = true; - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - - //$reload = true; - - //if($reload == true) $app->services->restartService('php-fpm','reload'); - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data, $web_config) { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - - //$app->services->restartService('php-fpm','reload'); - } - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - function client_delete($event_name, $data) { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir, '..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $app->system->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); - } - } - - } - - private function _checkTcp ($host, $port) { - - $fp = @fsockopen($host, $port, $errno, $errstr, 2); - - if ($fp) { - fclose($fp); - return true; - } else { - return false; - } - } - - private function _rewrite_quote($string) { - return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); - } + global $app; - private function _is_url($string) { - return preg_match('/^(f|ht)tp(s)?:\/\//i', $string); + $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'apache'); } - private function get_seo_redirects($web, $prefix = ''){ - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){ - $domain = str_replace('.', '\.', $web['domain']); - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = ''; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $domain.'|.*\.'.$domain.'(? diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 5024a3bff..3a7f569c2 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -30,14 +30,19 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class nginx_plugin { - var $plugin_name = 'nginx_plugin'; - var $class_name = 'nginx_plugin'; + var $plugin_name; + var $class_name; // private variables var $action = ''; var $ssl_certificate_changed = false; var $update_letsencrypt = false; + public function __construct() { + $this->plugin_name = get_class($this); + $this->class_name = get_class($this); + } + //* This function is called during ispconfig installation to determine // if a symlink shall be created for this plugin. function onInstall() { @@ -62,3096 +67,93 @@ class nginx_plugin { /* Register for the events */ - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl'); - - $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert'); - $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update'); - $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete'); - - $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip'); - $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip'); - - /* - $app->plugins->registerEvent('webdav_user_insert',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_update',$this->plugin_name,'webdav'); - $app->plugins->registerEvent('webdav_user_delete',$this->plugin_name,'webdav'); - */ + $app->plugin_webserver_base->registerEvents('nginx'); + } - $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete'); + // Handle php.ini changes + function php_ini_changed($event_name, $data) { + global $app; - $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user'); - $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user'); + $app->plugin_webserver_base->eventPhpIniChanged($event_name, $data, 'nginx'); - $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update'); - $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete'); } // Handle the creation of SSL certificates function ssl($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf')) - $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR); - - //* Only vhosts can have a ssl cert - if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return; - - // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl'); - if(!is_dir($data['new']['document_root'].'/ssl') && !is_dir($data['old']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl'); - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = ($data['new']['ssl_domain'] != '') ? $data['new']['ssl_domain'] : $data['new']['domain']; - $key_file = $ssl_dir.'/'.$domain.'.key'; - $key_file2 = $ssl_dir.'/'.$domain.'.key.org'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - - //* Create a SSL Certificate, but only if this is not a mirror server. - if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) { - - $this->ssl_certificate_changed = true; - - //* Rename files if they exist - if(file_exists($key_file)){ - $app->system->rename($key_file, $key_file.'.bak'); - $app->system->chmod($key_file.'.bak', 0400); - } - if(file_exists($key_file2)){ - $app->system->rename($key_file2, $key_file2.'.bak'); - $app->system->chmod($key_file2.'.bak', 0400); - } - if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak'); - if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak'); - - $rand_file = $ssl_dir.'/random_file'; - $rand_data = md5(uniqid(microtime(), 1)); - for($i=0; $i<1000; $i++) { - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - $rand_data .= md5(uniqid(microtime(), 1)); - } - $app->system->file_put_contents($rand_file, $rand_data); - - $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15); - - $ssl_cnf = " RANDFILE = $rand_file - - [ req ] - default_bits = 2048 - default_md = sha256 - default_keyfile = keyfile.pem - distinguished_name = req_distinguished_name - attributes = req_attributes - prompt = no - output_password = $ssl_password - - [ req_distinguished_name ] - C = ".trim($data['new']['ssl_country'])." - " . (trim($data['new']['ssl_state']) == '' ? '' : "ST = ".trim($data['new']['ssl_state'])) . " - " . (trim($data['new']['ssl_locality']) == '' ? '' : "L = ".trim($data['new']['ssl_locality']))." - " . (trim($data['new']['ssl_organisation']) == '' ? '' : "O = ".trim($data['new']['ssl_organisation']))." - " . (trim($data['new']['ssl_organisation_unit']) == '' ? '' : "OU = ".trim($data['new']['ssl_organisation_unit']))." - CN = $domain - emailAddress = webmaster@".$data['new']['domain']." - - [ req_attributes ] - ";//challengePassword = A challenge password"; - - $ssl_cnf_file = $ssl_dir.'/openssl.conf'; - $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf); - - $rand_file = escapeshellcmd($rand_file); - $key_file2 = escapeshellcmd($key_file2); - $openssl_cmd_key_file2 = $key_file2; - if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate - $key_file = escapeshellcmd($key_file); - $openssl_cmd_key_file = $key_file; - if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate - $ssl_days = 3650; - $csr_file = escapeshellcmd($csr_file); - $openssl_cmd_csr_file = $csr_file; - if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate - $config_file = escapeshellcmd($ssl_cnf_file); - $crt_file = escapeshellcmd($crt_file); - $openssl_cmd_crt_file = $crt_file; - if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate - - if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) { - - exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file2 2048"); - exec("openssl req -new -sha256 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -out $openssl_cmd_csr_file -days $ssl_days -config $config_file"); - exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file2 -out $openssl_cmd_key_file"); - - if(file_exists($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file"); - $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed. openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR); - }; - if (@filesize($crt_file)==0 || !file_exists($crt_file)){ - exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file2 -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file "); - $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - - } - - $app->system->chmod($key_file2, 0400); - $app->system->chmod($key_file, 0400); - @$app->system->unlink($config_file); - @$app->system->unlink($rand_file); - $ssl_request = $app->system->file_get_contents($csr_file); - $ssl_cert = $app->system->file_get_contents($crt_file); - $ssl_key = $app->system->file_get_contents($key_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key, $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - - //* Check that the SSL key is not password protected - if($data["new"]["ssl_action"] == 'save') { - if(stristr($data["new"]["ssl_key"],'Proc-Type: 4,ENCRYPTED')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL key is encrypted.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL key is encrypted.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* and check that SSL cert does not contain subdomain of domain acme.invalid - if($data["new"]["ssl_action"] == 'save') { - $tmp = array(); - $crt_data = ''; - exec('openssl x509 -noout -text -in '.escapeshellarg($crt_file),$tmp); - $crt_data = implode("\n",$tmp); - if(stristr($crt_data,'.acme.invalid')) { - $data["new"]["ssl_action"] = ''; - - $app->log('SSL Certificate not saved. The SSL cert contains domain acme.invalid.', LOGLEVEL_WARN); - $app->dbmaster->datalogError('SSL Certificate not saved. The SSL cert contains domain acme.invalid.'); - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } - } - - //* Save a SSL certificate to disk - if($data["new"]["ssl_action"] == 'save') { - $this->ssl_certificate_changed = true; - - //* Backup files - if(file_exists($key_file)){ - $app->system->copy($key_file, $key_file.'~'); - $app->system->chmod($key_file.'~', 0400); - } - if(file_exists($key_file2)){ - $app->system->copy($key_file2, $key_file2.'~'); - $app->system->chmod($key_file2.'~', 0400); - } - if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~'); - if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~'); - - //* Write new ssl files - if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]); - if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]); - if(trim($data["new"]["ssl_key"]) != '') $app->system->file_put_contents($key_file, $data["new"]["ssl_key"]); - $app->system->chmod($key_file, 0400); - - // for nginx, bundle files have to be appended to the certificate file - if(trim($data["new"]["ssl_bundle"]) != ''){ - if(file_exists($crt_file)){ - $crt_file_contents = trim($app->system->file_get_contents($crt_file)); - } else { - $crt_file_contents = ''; - } - if($crt_file_contents != '') $crt_file_contents .= "\n"; - $crt_file_contents .= $data["new"]["ssl_bundle"]; - $app->system->file_put_contents($crt_file, $app->file->unix_nl($crt_file_contents)); - unset($crt_file_contents); - } - - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } - - //* Delete a SSL certificate - if($data['new']['ssl_action'] == 'del') { - if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf')) - { - exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file)); - $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG); - }; - $app->system->unlink($csr_file); - $app->system->unlink($crt_file); - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ? AND server_id = ?", $data['new']['domain'], $data['new']['server_id']); - $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG); - } + global $app; + $app->plugin_webserver_base->eventSsl($event_name, $data, 'nginx'); } function insert($event_name, $data) { - global $app, $conf; - $this->action = 'insert'; // just run the update function $this->update($event_name, $data); - - } function update($event_name, $data) { - global $app, $conf; - - //* Check if the apache plugin is enabled - if(@is_link('/usr/local/ispconfig/server/plugins-enabled/apache2_plugin.inc.php')) { - $app->log('The nginx plugin cannot be used together with the apache2 plugin.', LOGLEVEL_WARN); - return 0; - } + global $app; if($this->action != 'insert') $this->action = 'update'; - if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) { - - $old_parent_domain_id = intval($data['old']['parent_domain_id']); - $new_parent_domain_id = intval($data['new']['parent_domain_id']); - - // If the parent_domain_id has been changed, we will have to update the old site as well. - if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) { - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update($event_name, $data); - } - - // This is not a vhost, so we need to update the parent record instead. - $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $new_parent_domain_id, 'y'); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - } - - // load the server configuration options - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - $app->log('Info: nginx is chrooted.', LOGLEVEL_DEBUG); - } else { - $nginx_chrooted = false; - } - - if($data['new']['document_root'] == '') { - if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN); - return 0; - } - if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false - || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) { - $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN); - return 0; - } - if(trim($data['new']['domain']) == '') { - $app->log('domain is empty', LOGLEVEL_WARN); - return 0; - } - - $web_folder = 'web'; - $log_folder = 'log'; - $old_web_folder = 'web'; - $old_log_folder = 'log'; - if($data['new']['type'] == 'vhost'){ - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'],0,1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'],-1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $web_folder .= '/'.$data['new']['web_folder']; - - if($data['old']['web_folder'] != ''){ - if(substr($data['old']['web_folder'],0,1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],1); - if(substr($data['old']['web_folder'],-1) == '/') $data['old']['web_folder'] = substr($data['old']['web_folder'],0,-1); - } - $old_web_folder .= '/'.$data['old']['web_folder']; - } - if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - // new one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id']; - $web_folder = $data['new']['web_folder']; - $log_folder .= '/' . $subdomain_host; - unset($tmp); - - if(isset($data['old']['parent_domain_id'])) { - // old one - $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $old_web_folder = $data['old']['web_folder']; - $old_log_folder .= '/' . $subdomain_host; - unset($tmp); - } - } - - // Create group and user, if not exist - $app->uses('system'); - - if($web_config['connect_userid_to_webid'] == 'y') { - //* Calculate the uid and gid - $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']); - $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']); - $fixed_uid_param = '--uid '.$fixed_uid_gid; - $fixed_gid_param = '--gid '.$fixed_uid_gid; - - //* Check if a ispconfigend user and group exists and create them - if(!$app->system->is_group('ispconfigend')) { - exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - if(!$app->system->is_user('ispconfigend')) { - exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend'); - } - } else { - $fixed_uid_param = ''; - $fixed_gid_param = ''; - } - - $groupname = escapeshellcmd($data['new']['system_group']); - if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) { - exec('groupadd '.$fixed_gid_param.' '.$groupname); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname); - $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG); - } - - $username = escapeshellcmd($data['new']['system_user']); - if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) { - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false"); - } else { - exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false"); - } - $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG); - } - - //* If the client of the site has been changed, we have a change of the document root - if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) { - - //* Get the old client ID - $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $old_client_id = intval($old_client['client_id']); - unset($old_client); - - //* Remove the old symlinks - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // create the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") { - //* Move the site data - $tmp_docroot = explode('/', $data['new']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $new_dir = implode('/', $tmp_docroot); - - $tmp_docroot = explode('/', $data['old']['document_root']); - unset($tmp_docroot[count($tmp_docroot)-1]); - $old_dir = implode('/', $tmp_docroot); - - //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path - if(@is_dir($data['new']['document_root'])) { - $app->system->web_folder_protection($data['new']['document_root'], false); - $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s')); - $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG); - } - - //* Unmount the old log directory bfore we move the log dir - exec('umount '.escapeshellcmd($old_dir.'/log')); - - //* Create new base directory, if it does not exist yet - if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir); - $app->system->web_folder_protection($data['old']['document_root'], false); - exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir)); - //$app->system->rename($data['old']['document_root'],$new_dir); - $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG); - - // Handle the change in php_open_basedir - $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']); - - //* Change the owner of the website files to the new website owner - exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir); - - //* Change the home directory and group of the website user - $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod'; - $command .= ' --home '.escapeshellcmd($data['new']['document_root']); - $command .= ' --gid '.escapeshellcmd($data['new']['system_group']); - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - exec($command); - } - - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* Change the log mount - /* - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind,nobootwait'; - $app->system->removeLine('/etc/fstab', $fstab_line); - */ - - $fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - - if($web_config['network_filesystem'] == 'y') { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail,_netdev 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nofail 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1); - } - - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - - } - - //print_r($data); - - // Check if the directories are there and create them if necessary. - $app->system->web_folder_protection($data['new']['document_root'], false); - - if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder); - if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error'); - 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'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder); - 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'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav'); - - if(!is_dir($data['new']['document_root'].'/.ssh')) { - $app->system->mkdirpath($data['new']['document_root'].'/.ssh'); - $app->system->chmod($data['new']['document_root'].'/.ssh', 0700); - $app->system->chown($data['new']['document_root'].'/.ssh', $username); - $app->system->chgrp($data['new']['document_root'].'/.ssh', $groupname); - } - - //* Create the new private directory - if(!is_dir($data['new']['document_root'].'/private')) { - $app->system->mkdirpath($data['new']['document_root'].'/private'); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - } - - - // 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'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']); - if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder); - - //* remove old log mount - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - - //* Unmount log directory - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder)); - } - - //* Create the log dir if nescessary and mount it - if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) { - if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder); - if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']); - $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder); - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root'); - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder)); - //* add mountpoint to fstab - $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.' none bind,nobootwait'; - $fstab_line .= @($web_config['network_filesystem'] == 'y')?',_netdev 0 0':' 0 0'; - $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1); - } - - $app->system->web_folder_protection($data['new']['document_root'], true); - - // Get the client ID - $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - - // Remove old symlinks, if site is renamed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // remove the symlinks, if not exist - if(is_link($tmp_symlink)) { - exec('rm -f '.escapeshellcmd($tmp_symlink)); - $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - } - - // Create the symlinks for the sites - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - //* Remove symlink if target folder has been changed. - if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - } - // create the symlinks, if not exist - if(!is_link($tmp_symlink)) { - // exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - if ($web_config["website_symlinks_rel"] == 'y') { - $app->system->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink)); - } else { - exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink)); - } - - $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - - - - // Install the Standard or Custom Error, Index and other related files - // /usr/local/ispconfig/server/conf is for the standard files - // /usr/local/ispconfig/server/conf-custom is for the custom files - // setting a local var here - - // normally $conf['templates'] = "/usr/local/ispconfig/server/conf"; - if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - - // Copy the error pages - if($data['new']['errordocs']) { - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - } - - //* Copy the web skeleton files only when there is no index.ph or index.html file yet - if(!file_exists($data['new']['document_root'].'/'.$web_folder.'/index.html') && !file_exists($data['new']['document_root'].'/'.$web_folder.'/index.php')) { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - - if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) { - // exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - //} - } else { - if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - } else { - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html')) exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html'); - if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - if(is_file($conf['rootpath'] . '/conf/index/robots.txt')){ - if(!file_exists(escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - //if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - } - } - } - exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/'); - - //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before - } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) { - - $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/'; - if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - else { - if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) { - exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path); - } - else { - exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path); - } - } - exec('chmod -R a+r '.$error_page_path); - exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path); - } // end copy error docs - - // Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias - if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') { - if($data['new']['hd_quota'] > 0) { - $blocks_soft = $data['new']['hd_quota'] * 1024; - $blocks_hard = $blocks_soft + 1024; - $mb_soft = $data['new']['hd_quota']; - $mb_hard = $mb_soft + 1; - } else { - $mb_soft = $mb_hard = $blocks_soft = $blocks_hard = 0; - } - - // get the primitive folder for document_root and the filesystem, will need it later. - $df_output=explode(" ", exec("df -T " . escapeshellarg($data['new']['document_root']) . "|awk 'END{print \$2,\$NF}'")); - $file_system = $df_output[0]; - $primitive_root = $df_output[1]; - - if($file_system == 'xfs') { - exec("xfs_quota -x -c " . escapeshellarg("limit -u bsoft=$mb_soft" . 'm'. " bhard=$mb_hard" . 'm'. " " . $username) . " " . escapeshellarg($primitive_root)); - - // xfs only supports timers globally, not per user. - exec("xfs_quota -x -c 'timer -bir -i 604800' " . escapeshellarg($primitive_root)); - - unset($project_uid, $username_position, $xfs_projects); - unset($primitive_root, $df_output, $mb_hard, $mb_soft); - } else { - if($app->system->is_installed('setquota')) { - exec('setquota -u '. $username . ' ' . $blocks_soft . ' ' . $blocks_hard . ' 0 0 -a &> /dev/null'); - exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null'); - } - } - } - - if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) { - // Chown and chmod the directories below the document root - $app->system->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - // The document root itself has to be owned by root in normal level and by the web owner in security level 20 - if($web_config['security_level'] == 20) { - $app->system->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } else { - $app->system->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder); - } - } - - //* add the nginx user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update - if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - - //* If the security level is set to high - if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost') or ($web_folder != $old_web_folder && $data['new']['type'] == 'vhost')) { - - $app->system->web_folder_protection($data['new']['document_root'], false); - - //* Check if we have the new private folder and create it if nescessary - if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private'); - - if($web_config['security_level'] == 20) { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0751); - //$app->system->chmod($data['new']['document_root'].'/webdav',0710); - $app->system->chmod($data['new']['document_root'].'/private', 0710); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0751); - - // make tmp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - if($web_config['add_web_users_to_sshusers_group'] == 'y') { - $command = 'usermod'; - $command .= ' --groups sshusers'; - $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null'; - $app->system->_exec($command); - } - - //* if we have a chrooted nginx environment - if($nginx_chrooted) { - $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - //* add the nginx user to the client group in the chroot environment - $tmp_groupfile = $app->system->server_conf['group_datei']; - $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group'; - $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['nginx_user'])); - $app->system->server_conf['group_datei'] = $tmp_groupfile; - unset($tmp_groupfile); - } - - //* Chown all default directories - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - $app->system->chown($data['new']['document_root'].'/private', $username); - $app->system->chgrp($data['new']['document_root'].'/private', $groupname); - - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - - // If the security Level is set to medium - } else { - - $app->system->chmod($data['new']['document_root'], 0755); - $app->system->chmod($data['new']['document_root'].'/web', 0755); - //$app->system->chmod($data['new']['document_root'].'/webdav',0755); - $app->system->chmod($data['new']['document_root'].'/ssl', 0755); - $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755); - if($web_folder != 'web') $app->system->chmod($data['new']['document_root'].'/'.$web_folder, 0755); - - // make temp directory writable for nginx and the website users - $app->system->chmod($data['new']['document_root'].'/tmp', 0770); - - // Set Log directory to 755 to make the logs accessible by the FTP user - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755); - } - - $app->system->chown($data['new']['document_root'], 'root'); - $app->system->chgrp($data['new']['document_root'], 'root'); - $app->system->chown($data['new']['document_root'].'/cgi-bin', $username); - $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname); - if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') { - $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false); - $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false); - } - - $app->system->chown($data['new']['document_root'].'/ssl', 'root'); - $app->system->chgrp($data['new']['document_root'].'/ssl', 'root'); - $app->system->chown($data['new']['document_root'].'/tmp', $username); - $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname); - $app->system->chown($data['new']['document_root'].'/web', $username); - $app->system->chgrp($data['new']['document_root'].'/web', $groupname); - $app->system->chown($data['new']['document_root'].'/web/error', $username); - $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/web/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname); - } - //$app->system->chown($data['new']['document_root'].'/webdav',$username); - //$app->system->chgrp($data['new']['document_root'].'/webdav',$groupname); - - if($web_folder != 'web'){ - $app->system->chown($data['new']['document_root'].'/'.$web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/'.$web_folder, $groupname); - } - } - } elseif((($data['new']['type'] == 'vhostsubdomain') || ($data['new']['type'] == 'vhostalias')) && - (($this->action == 'insert') || ($web_config['set_folder_permissions_on_update'] == 'y'))) { - - if($web_config['security_level'] == 20) { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } else { - $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755); - $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname); - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname); - if($data['new']['stats_type'] != '') { - $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname); - } - } - } - - //* Protect web folders - $app->system->web_folder_protection($data['new']['document_root'], true); - - if($data['new']['type'] == 'vhost') { - // Change the ownership of the error log to the root user - if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')); - $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root'); - } - - - //* Create the vhost config file - $app->load('tpl'); - - $tpl = new tpl(); - $tpl->newTemplate('nginx_vhost.conf.master'); - - // IPv4 - if($data['new']['ip_address'] == '') $data['new']['ip_address'] = '*'; - - //* use ip-mapping for web-mirror - if($data['new']['ip_address'] != '*' && $conf['mirror_server_id'] > 0) { - $sql = "SELECT destination_ip FROM server_ip_map WHERE server_id = ? AND source_ip = ?"; - $newip = $app->db->queryOneRecord($sql, $conf['server_id'], $data['new']['ip_address']); - $data['new']['ip_address'] = $newip['destination_ip']; - unset($newip); - } - - $vhost_data = $data['new']; - - //unset($vhost_data['ip_address']); - $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder; - $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder; - $vhost_data['web_basedir'] = $web_config['website_basedir']; - - // IPv6 - if($data['new']['ipv6_address'] != ''){ - $tpl->setVar('ipv6_enabled', 1); - if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') { - if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') { - $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']); - $explode_v6=explode(':', $data['new']['ipv6_address']); - - for ( $i = 0; $i <= count($explode_v6prefix)-1; $i++ ) { - $explode_v6[$i] = $explode_v6prefix[$i]; - } - $data['new']['ipv6_address'] = implode(':', $explode_v6); - $vhost_data['ipv6_address'] = $data['new']['ipv6_address']; - } - } - } - - // PHP-FPM - // Support for multiple PHP versions - /* - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - */ - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['new']['domain_id']; - $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']); - if(substr($socket_dir, -1) != '/') $socket_dir .= '/'; - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - $php_fpm_nochroot = 0; - } else { - $php_fpm_chroot = 0; - $php_fpm_nochroot = 1; - } - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - $tpl->setVar('php_fpm_nochroot', $php_fpm_nochroot); - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('rnd_php_dummy_file', '/'.md5(uniqid(microtime(), 1)).'.htm'); - $vhost_data['fpm_port'] = $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1; - - // backwards compatibility; since ISPConfig 3.0.5, the PHP mode for nginx is called 'php-fpm' instead of 'fast-cgi'. The following line makes sure that old web sites that have 'fast-cgi' in the database still get PHP-FPM support. - if($vhost_data['php'] == 'fast-cgi') $vhost_data['php'] = 'php-fpm'; - - // Custom rewrite rules - /* - $final_rewrite_rules = array(); - $custom_rewrite_rules = $data['new']['rewrite_rules']; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - */ - - // Custom rewrite rules - $final_rewrite_rules = array(); - - if(isset($data['new']['rewrite_rules']) && trim($data['new']['rewrite_rules']) != '') { - $custom_rewrite_rules = trim($data['new']['rewrite_rules']); - $custom_rewrites_are_valid = true; - // use this counter to make sure all curly brackets are properly closed - $if_level = 0; - // Make sure we only have Unix linebreaks - $custom_rewrite_rules = str_replace("\r\n", "\n", $custom_rewrite_rules); - $custom_rewrite_rules = str_replace("\r", "\n", $custom_rewrite_rules); - $custom_rewrite_rule_lines = explode("\n", $custom_rewrite_rules); - if(is_array($custom_rewrite_rule_lines) && !empty($custom_rewrite_rule_lines)){ - foreach($custom_rewrite_rule_lines as $custom_rewrite_rule_line){ - // ignore comments - if(substr(ltrim($custom_rewrite_rule_line), 0, 1) == '#'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // empty lines - if(trim($custom_rewrite_rule_line) == ''){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // rewrite - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?(\'[^\']+\'|"[^"]+")+(\$)?\s+\S+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - if(preg_match('@^\s*rewrite\s+(^/)?\S+(\$)?\s+(\'[^\']+\'|"[^"]+")+(\s+(last|break|redirect|permanent|))?\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // if - if(preg_match('@^\s*if\s+\(\s*\$\S+(\s+(\!?(=|~|~\*))\s+(\S+|\".+\"))?\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // if - check for files, directories, etc. - if(preg_match('@^\s*if\s+\(\s*\!?-(f|d|e|x)\s+\S+\s*\)\s*\{\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level += 1; - continue; - } - // break - if(preg_match('@^\s*break\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code [ text ] - if(preg_match('@^\s*return\s+\d\d\d.*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // return code URL - // return URL - if(preg_match('@^\s*return(\s+\d\d\d)?\s+(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*\@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // set - if(preg_match('@^\s*set\s+\$\S+\s+\S+\s*;\s*$@', $custom_rewrite_rule_line)){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - continue; - } - // closing curly bracket - if(trim($custom_rewrite_rule_line) == '}'){ - $final_rewrite_rules[] = array('rewrite_rule' => $custom_rewrite_rule_line); - $if_level -= 1; - continue; - } - $custom_rewrites_are_valid = false; - break; - } - } - if(!$custom_rewrites_are_valid || $if_level != 0){ - $final_rewrite_rules = array(); - } - } - $tpl->setLoop('rewrite_rules', $final_rewrite_rules); - - // Custom nginx directives - $final_nginx_directives = array(); - if($data['new']['enable_pagespeed'] == 'y'){ - // if PageSpeed is already enabled, don't add configuration again - if(stripos($nginx_directives, 'pagespeed') !== false){ - $vhost_data['enable_pagespeed'] = false; - } else { - $vhost_data['enable_pagespeed'] = true; - } - } else { - $vhost_data['enable_pagespeed'] = false; - } - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", $data['new']['directive_snippets_id']); - if(isset($snippet['snippet'])){ - $nginx_directives = $snippet['snippet']; - } else { - $nginx_directives = $data['new']['nginx_directives']; - } -/* - if($data['new']['enable_pagespeed'] == 'y'){ - // if PageSpeed is already enabled, don't add configuration again - if(stripos($nginx_directives, 'pagespeed') !== false){ - $vhost_data['enable_pagespeed'] = false; - } else { - $vhost_data['enable_pagespeed'] = true; - } - } else { - $vhost_data['enable_pagespeed'] = false; - } -*/ - } else { - $nginx_directives = $data['new']['nginx_directives']; -// $vhost_data['enable_pagespeed'] = false; - } - - // folder_directive_snippets - if(trim($data['new']['folder_directive_snippets']) != ''){ - $data['new']['folder_directive_snippets'] = trim($data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r\n", "\n", $data['new']['folder_directive_snippets']); - $data['new']['folder_directive_snippets'] = str_replace("\r", "\n", $data['new']['folder_directive_snippets']); - $folder_directive_snippets_lines = explode("\n", $data['new']['folder_directive_snippets']); - - if(is_array($folder_directive_snippets_lines) && !empty($folder_directive_snippets_lines)){ - foreach($folder_directive_snippets_lines as $folder_directive_snippets_line){ - list($folder_directive_snippets_folder, $folder_directive_snippets_snippets_id) = explode(':', $folder_directive_snippets_line); - - $folder_directive_snippets_folder = trim($folder_directive_snippets_folder); - $folder_directive_snippets_snippets_id = trim($folder_directive_snippets_snippets_id); - - if($folder_directive_snippets_folder != '' && intval($folder_directive_snippets_snippets_id) > 0 && preg_match('@^((?!(.*\.\.)|(.*\./)|(.*//))[^/][\w/_\.\-]{1,100})?$@', $folder_directive_snippets_folder)){ - if(substr($folder_directive_snippets_folder, -1) != '/') $folder_directive_snippets_folder .= '/'; - if(substr($folder_directive_snippets_folder, 0, 1) == '/') $folder_directive_snippets_folder = substr($folder_directive_snippets_folder, 1); - - $master_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($folder_directive_snippets_snippets_id)); - if(isset($master_snippet['snippet'])){ - $folder_directive_snippets_trans = array('{FOLDER}' => $folder_directive_snippets_folder, '{FOLDERMD5}' => md5($folder_directive_snippets_folder)); - $master_snippet['snippet'] = strtr($master_snippet['snippet'], $folder_directive_snippets_trans); - $nginx_directives .= "\n\n".$master_snippet['snippet']; - - // create folder it it does not exist - if(!is_dir($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder)){ - $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder); - $app->system->chown($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $username); - $app->system->chgrp($data['new']['document_root'].'/' . $web_folder.$folder_directive_snippets_folder, $groupname); - } - } - } - } - } - } - - // use vLib for template logic - if(trim($nginx_directives) != '') { - $nginx_directives_new = ''; - $ngx_conf_tpl = new tpl(); - $ngx_conf_tpl_tmp_file = tempnam($conf['temppath'], "ngx"); - file_put_contents($ngx_conf_tpl_tmp_file, $nginx_directives); - $ngx_conf_tpl->newTemplate($ngx_conf_tpl_tmp_file); - $ngx_conf_tpl->setVar('use_tcp', $use_tcp); - $ngx_conf_tpl->setVar('use_socket', $use_socket); - $ngx_conf_tpl->setVar('fpm_socket', $fpm_socket); - $ngx_conf_tpl->setVar($vhost_data); - $nginx_directives_new = $ngx_conf_tpl->grab(); - if(is_file($ngx_conf_tpl_tmp_file)) unlink($ngx_conf_tpl_tmp_file); - if($nginx_directives_new != '') $nginx_directives = $nginx_directives_new; - unset($nginx_directives_new); - } - - // Make sure we only have Unix linebreaks - $nginx_directives = str_replace("\r\n", "\n", $nginx_directives); - $nginx_directives = str_replace("\r", "\n", $nginx_directives); - $nginx_directive_lines = explode("\n", $nginx_directives); - if(is_array($nginx_directive_lines) && !empty($nginx_directive_lines)){ - $trans = array( - '{DOCROOT}' => $vhost_data['web_document_root_www'], - '{DOCROOT_CLIENT}' => $vhost_data['web_document_root'], - '{FASTCGIPASS}' => 'fastcgi_pass '.($data['new']['php_fpm_use_socket'] == 'y'? 'unix:'.$fpm_socket : '127.0.0.1:'.$vhost_data['fpm_port']).';' - ); - foreach($nginx_directive_lines as $nginx_directive_line){ - $final_nginx_directives[] = array('nginx_directive' => strtr($nginx_directive_line, $trans)); - } - } - $tpl->setLoop('nginx_directives', $final_nginx_directives); - - $app->uses('letsencrypt'); - // Check if a SSL cert exists - $tmp = $app->letsencrypt->get_website_certificate_paths($data); - $domain = $tmp['domain']; - $key_file = $tmp['key']; - $key_file2 = $tmp['key2']; - $csr_file = $tmp['csr']; - $crt_file = $tmp['crt']; - $bundle_file = $tmp['bundle']; - unset($tmp); - - $data['new']['ssl_domain'] = $domain; - $vhost_data['ssl_domain'] = $domain; - $vhost_data['ssl_crt_file'] = $crt_file; - $vhost_data['ssl_key_file'] = $key_file; - $vhost_data['ssl_bundle_file'] = $bundle_file; - - //* Generate Let's Encrypt SSL certificat - if($data['new']['ssl'] == 'y' && $data['new']['ssl_letsencrypt'] == 'y' && $conf['mirror_server_id'] == 0 && ( // ssl and let's encrypt is active and no mirror server - ($data['old']['ssl'] == 'n' || $data['old']['ssl_letsencrypt'] == 'n') // we have new let's encrypt configuration - || ($data['old']['domain'] != $data['new']['domain']) // we have domain update - || ($data['old']['subdomain'] != $data['new']['subdomain']) // we have new or update on "auto" subdomain - || $this->update_letsencrypt == true - )) { - - $success = $app->letsencrypt->request_certificates($data, 'nginx'); - if($success) { - /* we don't need to store it. - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain_id = ?", $data['new']['domain']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '', ssl_key = '' WHERE domain = ?", $data['new']['domain']); - $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']); - } else { - $data['new']['ssl_letsencrypt'] = 'n'; - if($data['old']['ssl'] == 'n') $data['new']['ssl'] = 'n'; - /* Update the DB of the (local) Server */ - $app->db->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ? AND `server_id` = ?", $data['new']['ssl'], 'n', $data['new']['domain'], $conf['server_id']); - /* Update also the master-DB of the Server-Farm */ - $app->dbmaster->query("UPDATE web_domain SET `ssl` = ?, `ssl_letsencrypt` = ? WHERE `domain` = ?", $data['new']['ssl'], 'n', $data['new']['domain']); - } - } - - if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0) && (@filesize($key_file)>0)) { - $vhost_data['ssl_enabled'] = 1; - $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG); - } else { - $vhost_data['ssl_enabled'] = 0; - $app->log('SSL Disabled. '.$domain, LOGLEVEL_DEBUG); - } - - // Set SEO Redirect - if($data['new']['seo_redirect'] != ''){ - $vhost_data['seo_redirect_enabled'] = 1; - $tmp_seo_redirects = $this->get_seo_redirects($data['new']); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - foreach($tmp_seo_redirects as $key => $val){ - $vhost_data[$key] = $val; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - } else { - $vhost_data['seo_redirect_enabled'] = 0; - } - - // Rewrite rules - $own_rewrite_rules = array(); - $rewrite_rules = array(); - $local_rewrite_rules = array(); - if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') { - if(substr($data['new']['redirect_path'], -1) != '/') $data['new']['redirect_path'] .= '/'; - if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){ - if($data['new']['redirect_type'] != 'proxy'){ - $data['new']['redirect_path'] = '$scheme'.substr($data['new']['redirect_path'], 8); - } else { - $data['new']['redirect_path'] = 'http'.substr($data['new']['redirect_path'], 8); - } - } - - // Custom proxy directives - if($data['new']['redirect_type'] == 'proxy' && trim($data['new']['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $data['new']['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - switch($data['new']['subdomain']) { - case 'www': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if(($tmp_redirect_path_parts['host'] == $data['new']['domain'] || $tmp_redirect_path_parts['host'] == 'www.'.$data['new']['domain']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - case '*': - $exclude_own_hostname = ''; - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - - //if($is_serveralias && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - if($this->url_is_local($tmp_redirect_path_parts['host'], $data['new']['domain_id']) && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - break; - default: - if(substr($data['new']['redirect_path'], 0, 1) == '/'){ // relative path - $exclude_own_hostname = ''; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= substr($data['new']['redirect_path'], 0, -1); - break; - } - $rewrite_exclude = '(?!/('.substr($data['new']['redirect_path'], 1, -1).(substr($data['new']['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - } else { // URL - check if URL is local - $tmp_redirect_path = $data['new']['redirect_path']; - if(substr($tmp_redirect_path, 0, 7) == '$scheme') $tmp_redirect_path = 'http'.substr($tmp_redirect_path, 7); - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - if($tmp_redirect_path_parts['host'] == $data['new']['domain'] && ($tmp_redirect_path_parts['port'] == '80' || $tmp_redirect_path_parts['port'] == '443' || !isset($tmp_redirect_path_parts['port']))){ - // URL is local - if(substr($tmp_redirect_path_parts['path'], -1) == '/') $tmp_redirect_path_parts['path'] = substr($tmp_redirect_path_parts['path'], 0, -1); - if(substr($tmp_redirect_path_parts['path'], 0, 1) != '/') $tmp_redirect_path_parts['path'] = '/'.$tmp_redirect_path_parts['path']; - //$rewrite_exclude = '((?!'.$tmp_redirect_path_parts['path'].'))'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['web_document_root_www_proxy'] = 'root '.$vhost_data['web_document_root_www'].';'; - $vhost_data['web_document_root_www'] .= $tmp_redirect_path_parts['path']; - break; - } else { - $rewrite_exclude = '(?!/('.substr($tmp_redirect_path_parts['path'], 1).(substr($tmp_redirect_path_parts['path'], 1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - $exclude_own_hostname = $tmp_redirect_path_parts['host']; - } - } else { - // external URL - $rewrite_exclude = '(.?)/'; - if($data['new']['redirect_type'] == 'proxy'){ - $vhost_data['use_proxy'] = 'y'; - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - } - unset($tmp_redirect_path); - unset($tmp_redirect_path_parts); - } - $own_rewrite_rules[] = array( 'rewrite_domain' => '^'.$this->_rewrite_quote($data['new']['domain']), - 'rewrite_type' => ($data['new']['redirect_type'] == 'no')?'':$data['new']['redirect_type'], - 'rewrite_target' => $data['new']['redirect_path'], - 'rewrite_exclude' => $rewrite_exclude, - 'rewrite_subdir' => $rewrite_subdir, - 'exclude_own_hostname' => $exclude_own_hostname, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($data['new']['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($data['new']['redirect_type'] == 'proxy' ? true:false)); - } - } - - // http2 or spdy? - $vhost_data['enable_http2'] = 'n'; - if($vhost_data['enable_spdy'] == 'y'){ - // check if nginx support http_v2; if so, use that instead of spdy - exec("2>&1 nginx -V | tr -- - '\n' | grep http_v2_module", $tmp_output, $tmp_retval); - if($tmp_retval == 0){ - $vhost_data['enable_http2'] = 'y'; - $vhost_data['enable_spdy'] = 'n'; - } - unset($tmp_output, $tmp_retval); - } - - // set logging variable - $vhost_data['logging'] = $web_config['logging']; - - $tpl->setVar($vhost_data); - - $server_alias = array(); - - // get autoalias - $auto_alias = $web_config['website_autoalias']; - if($auto_alias != '') { - // get the client username - $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = ?", $client_id); - $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]'); - $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']); - $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias); - unset($client); - unset($aa_search); - unset($aa_replace); - $server_alias[] .= $auto_alias.' '; - } - - // get alias domains (co-domains and subdomains) - $aliases = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE parent_domain_id = ? AND active = 'y' AND (type != 'vhostsubdomain' AND type != 'vhostalias')", $data['new']['domain_id']); - $alias_seo_redirects = array(); - switch($data['new']['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$data['new']['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$data['new']['domain'].' '; - break; - } - if(is_array($aliases)) { - foreach($aliases as $alias) { - - // Custom proxy directives - if($alias['redirect_type'] == 'proxy' && trim($alias['proxy_directives'] != '')){ - $final_proxy_directives = array(); - $proxy_directives = $alias['proxy_directives']; - // Make sure we only have Unix linebreaks - $proxy_directives = str_replace("\r\n", "\n", $proxy_directives); - $proxy_directives = str_replace("\r", "\n", $proxy_directives); - $proxy_directive_lines = explode("\n", $proxy_directives); - if(is_array($proxy_directive_lines) && !empty($proxy_directive_lines)){ - foreach($proxy_directive_lines as $proxy_directive_line){ - $final_proxy_directives[] = array('proxy_directive' => $proxy_directive_line); - } - } - } else { - $final_proxy_directives = false; - } - - if($alias['redirect_type'] == '' || $alias['redirect_path'] == '' || substr($alias['redirect_path'], 0, 1) == '/') { - switch($alias['subdomain']) { - case 'www': - $server_alias[] = 'www.'.$alias['domain'].' '.$alias['domain'].' '; - break; - case '*': - $server_alias[] = '*.'.$alias['domain'].' '.$alias['domain'].' '; - break; - default: - $server_alias[] = $alias['domain'].' '; - break; - } - $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG); - - // Add SEO redirects for alias domains - if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects[] = $tmp_seo_redirects; - } - } - } - - // Local Rewriting (inside vhost server {} container) - if($alias['redirect_type'] != '' && substr($alias['redirect_path'], 0, 1) == '/' && $alias['redirect_type'] != 'proxy') { // proxy makes no sense with local path - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - $rewrite_exclude = '(?!/('.substr($alias['redirect_path'], 1, -1).(substr($alias['redirect_path'], 1, -1) != ''? '|': '').'stats'.($vhost_data['errordocs'] == 1 ? '|error' : '').'|\.well-known/acme-challenge))/'; - switch($alias['subdomain']) { - case 'www': - // example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - - // www.example.com - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => 'www.'.$alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - case '*': - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => '^('.str_replace('.', '\.', $alias['domain']).'|.+\.'.str_replace('.', '\.', $alias['domain']).')$', - 'local_redirect_operator' => '~*', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - break; - default: - $local_rewrite_rules[] = array( 'local_redirect_origin_domain' => $alias['domain'], - 'local_redirect_operator' => '=', - 'local_redirect_exclude' => $rewrite_exclude, - 'local_redirect_target' => $alias['redirect_path'], - 'local_redirect_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type']); - } - } - - // External Rewriting (extra server {} containers) - if($alias['redirect_type'] != '' && $alias['redirect_path'] != '' && substr($alias['redirect_path'], 0, 1) != '/') { - if(substr($alias['redirect_path'], -1) != '/') $alias['redirect_path'] .= '/'; - if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){ - if($alias['redirect_type'] != 'proxy'){ - $alias['redirect_path'] = '$scheme'.substr($alias['redirect_path'], 8); - } else { - $alias['redirect_path'] = 'http'.substr($alias['redirect_path'], 8); - } - } - - switch($alias['subdomain']) { - case 'www': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'www'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => 'www.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - case '*': - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $alias['domain'].' *.'.$alias['domain'], - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - break; - default: - if($alias['redirect_type'] == 'proxy'){ - $tmp_redirect_path = $alias['redirect_path']; - $tmp_redirect_path_parts = parse_url($tmp_redirect_path); - $rewrite_subdir = $tmp_redirect_path_parts['path']; - if(substr($rewrite_subdir, 0, 1) == '/') $rewrite_subdir = substr($rewrite_subdir, 1); - if(substr($rewrite_subdir, -1) != '/') $rewrite_subdir .= '/'; - if($rewrite_subdir == '/') $rewrite_subdir = ''; - } - - if($alias['redirect_type'] != 'proxy'){ - if(substr($alias['redirect_path'], -1) == '/') $alias['redirect_path'] = substr($alias['redirect_path'], 0, -1); - } - if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '*.'.substr($alias['domain'], 2); - else $domain_rule = $alias['domain']; - // Add SEO redirects for alias domains - $alias_seo_redirects2 = array(); - if($alias['seo_redirect'] != ''){ - if(substr($alias['domain'], 0, 2) === '*.'){ - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_'); - } else { - $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_', 'none'); - } - if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){ - $alias_seo_redirects2[] = $tmp_seo_redirects; - } - } - $rewrite_rules[] = array( 'rewrite_domain' => $domain_rule, - 'rewrite_type' => ($alias['redirect_type'] == 'no')?'':$alias['redirect_type'], - 'rewrite_target' => $alias['redirect_path'], - 'rewrite_subdir' => $rewrite_subdir, - 'proxy_directives' => $final_proxy_directives, - 'use_rewrite' => ($alias['redirect_type'] == 'proxy' ? false:true), - 'use_proxy' => ($alias['redirect_type'] == 'proxy' ? true:false), - 'alias_seo_redirects2' => (count($alias_seo_redirects2) > 0 ? $alias_seo_redirects2 : false)); - } - } - } - } - - //* If we have some alias records - if(count($server_alias) > 0) { - $server_alias_str = ''; - $n = 0; - - foreach($server_alias as $tmp_alias) { - $server_alias_str .= $tmp_alias; - } - unset($tmp_alias); - - $tpl->setVar('alias', trim($server_alias_str)); - } else { - $tpl->setVar('alias', ''); - } - - if(count($rewrite_rules) > 0) { - $tpl->setLoop('redirects', $rewrite_rules); - } - if(count($own_rewrite_rules) > 0) { - $tpl->setLoop('own_redirects', $own_rewrite_rules); - } - if(count($local_rewrite_rules) > 0) { - $tpl->setLoop('local_redirects', $local_rewrite_rules); - } - if(count($alias_seo_redirects) > 0) { - $tpl->setLoop('alias_seo_redirects', $alias_seo_redirects); - } - - $stats_web_folder = 'web'; - if($data['new']['type'] == 'vhost'){ - if($data['new']['web_folder'] != ''){ - if(substr($data['new']['web_folder'], 0, 1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],1); - if(substr($data['new']['web_folder'], -1) == '/') $data['new']['web_folder'] = substr($data['new']['web_folder'],0,-1); - } - $stats_web_folder .= '/'.$data['new']['web_folder']; - } elseif($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') { - $stats_web_folder = $data['new']['web_folder']; - } - - //* Create basic http auth for website statistics - $tpl->setVar('stats_auth_passwd_file', $data['new']['document_root']."/" . $stats_web_folder . "/stats/.htpasswd_stats"); - - // Create basic http auth for other directories - $basic_auth_locations = $this->_create_web_folder_auth_configuration($data['new']); - if(is_array($basic_auth_locations) && !empty($basic_auth_locations)) $tpl->setLoop('basic_auth_locations', $basic_auth_locations); - - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost'); - //* Make a backup copy of vhost file - if(file_exists($vhost_file)) copy($vhost_file, $vhost_file.'~'); - - //* Write vhost file - $app->system->file_put_contents($vhost_file, $this->nginx_merge_locations($tpl->grab())); - $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - unset($tpl); - - //* Set the symlink to enable the vhost - //* First we check if there is a old type of symlink and remove it - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink); - - //* Remove old or changed symlinks - if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - } - - //* New symlink - if($data['new']['subdomain'] == '*') { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost'); - } else { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost'); - } - if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) { - symlink($vhost_file, $vhost_symlink); - $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - // remove old symlink and vhost file, if domain name of the site has changed - if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) { - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)) { - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - $app->system->unlink($vhost_file); - $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG); - } - - // create password file for stats directory - if(!is_file($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) { - if(trim($data['new']['stats_password']) != '') { - $htp_file = 'admin:'.trim($data['new']['stats_password']); - $app->system->file_put_contents($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', $htp_file); - $app->system->chmod($data['new']['document_root'].'/' . $stats_web_folder . '/stats/.htpasswd_stats', 0755); - unset($htp_file); - } - } - - //* Create awstats configuration - if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) { - $this->awstats_update($data, $web_config); - } - - $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir); - - if($web_config['check_apache_config'] == 'y') { - //* Test if nginx starts with the new configuration file - $nginx_online_status_before_restart = $this->_checkTcp('localhost', 80); - $app->log('nginx status is: '.($nginx_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - - $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure - $app->log('nginx restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG); - - // wait a few seconds, before we test the apache status again - sleep(2); - - //* Check if nginx restarted successfully if it was online before - $nginx_online_status_after_restart = $this->_checkTcp('localhost', 80); - $app->log('nginx online status after restart is: '.($nginx_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG); - if($nginx_online_status_before_restart && !$nginx_online_status_after_restart || $retval['retval'] > 0) { - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN); - if(is_array($retval['output']) && !empty($retval['output'])){ - $app->log('Reason for nginx restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $retval['output'])); - } else { - // if no output is given, check again - exec('nginx -t 2>&1', $tmp_output, $tmp_retval); - if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){ - $app->log('Reason for nginx restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN); - $app->dbmaster->datalogError(implode("\n", $tmp_output)); - } - unset($tmp_output, $tmp_retval); - } - $app->system->copy($vhost_file, $vhost_file.'.err'); - - if(is_file($vhost_file.'~')) { - //* Copy back the last backup file - $app->system->copy($vhost_file.'~', $vhost_file); - } else { - //* There is no backup file, so we create a empty vhost file with a warning message inside - $app->system->file_put_contents($vhost_file, "# nginx did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors."); - } - - if($this->ssl_certificate_changed === true) { - - $ssl_dir = $data['new']['document_root'].'/ssl'; - $domain = $data['new']['ssl_domain']; - $key_file = $ssl_dir.'/'.$domain.'.key.org'; - $key_file2 = $ssl_dir.'/'.$domain.'.key'; - $csr_file = $ssl_dir.'/'.$domain.'.csr'; - $crt_file = $ssl_dir.'/'.$domain.'.crt'; - //$bundle_file = $ssl_dir.'/'.$domain.'.bundle'; - - //* Backup the files that might have caused the error - if(is_file($key_file)){ - $app->system->copy($key_file, $key_file.'.err'); - $app->system->chmod($key_file.'.err', 0400); - } - if(is_file($key_file2)){ - $app->system->copy($key_file2, $key_file2.'.err'); - $app->system->chmod($key_file2.'.err', 0400); - } - if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err'); - if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err'); - //if(is_file($bundle_file)) $app->system->copy($bundle_file,$bundle_file.'.err'); - - //* Restore the ~ backup files - if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file); - if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2); - if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file); - if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file); - //if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~',$bundle_file); - - $app->log('nginx did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN); - } - - $app->services->restartService('httpd', 'restart'); - } - } else { - //* We do not check the nginx config after changes (is faster) - $app->services->restartServiceDelayed('httpd', 'reload'); - } - - //* The vhost is written and apache has been restarted, so we - // can reset the ssl changed var to false and cleanup some files - $this->ssl_certificate_changed = false; - - if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~'); - if(@is_file($key_file2.'~')) $app->system->unlink($key_file2.'~'); - if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~'); - if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~'); - //if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~'); - - // Remove the backup copy of the config file. - if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~'); + $app->plugins_webserver_base->eventUpdate($event_name, $data, 'nginx'); //* Unset action to clean it for next processed vhost. $this->action = ''; } function delete($event_name, $data) { - global $app, $conf; - - // load the server configuration options - $app->uses('getconf'); - $app->uses('system'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') $app->system->web_folder_protection($data['old']['document_root'], false); - - //* Check if this is a chrooted setup - if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) { - $nginx_chrooted = true; - } else { - $nginx_chrooted = false; - } - - //* Remove the mounts - $log_folder = 'log'; - $web_folder = ''; - if($data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']); - if($tmp['domain'] != ''){ - $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']); - } else { - // get log folder from /etc/fstab - /* - $bind_mounts = $app->system->file_get_contents('/etc/fstab'); - $bind_mount_lines = explode("\n", $bind_mounts); - if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){ - foreach($bind_mount_lines as $bind_mount_line){ - $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line); - $bind_mount_parts = explode(' ', $bind_mount_line); - if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){ - if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){ - $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]); - } - } - } - } - */ - // we are deleting the parent domain, so we can delete everything in the log directory - $subdomain_hosts = array(); - $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){ - $subdomain_hosts[] = $file; - } - } - } - } - if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){ - $log_folders = array(); - foreach($subdomain_hosts as $subdomain_host){ - $log_folders[] = $log_folder.'/'.$subdomain_host; - } - } else { - if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id']; - $log_folder .= '/' . $subdomain_host; - } - $web_folder = $data['old']['web_folder']; - unset($tmp); - unset($subdomain_hosts); - } - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias'){ - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - } else { - //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder)); - //exec('fuser -km '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null'); - } - - //try umount mysql - if(file_exists($data['old']['document_root'].'/var/run/mysqld')) { - $fstab_line = '/var/run/mysqld ' . $data['old']['document_root'] . '/var/run/mysqld none bind,nobootwait 0 0'; - $app->system->removeLine('/etc/fstab', $fstab_line); - $command = 'umount ' . escapeshellarg($data['old']['document_root']) . '/var/run/mysqld/'; - exec($command); - } - // remove letsencrypt if it exists (renew will always fail otherwise) - - $old_domain = $data['old']['domain']; - if(substr($old_domain, 0, 2) === '*.') { - // wildcard domain not yet supported by letsencrypt! - $old_domain = substr($old_domain, 2); - } - $le_conf_file = '/etc/letsencrypt/renewal/' . $old_domain . '.conf'; - @rename('/etc/letsencrypt/renewal/' . $old_domain . '.conf', '/etc/letsencrypt/renewal/' . $old_domain . '.conf~backup'); - } - - //* remove mountpoint from fstab - if(is_array($log_folders) && !empty($log_folders)){ - foreach($log_folders as $log_folder){ - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - } else { - $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.' none bind'; - $app->system->removeLine('/etc/fstab', $fstab_line); - } - unset($log_folders); - - if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['type'] != 'vhostalias' && $data['old']['parent_domain_id'] > 0) { - //* This is a alias domain or subdomain, so we have to update the website instead - $parent_domain_id = intval($data['old']['parent_domain_id']); - $tmp = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ? AND active = 'y'", $parent_domain_id); - $data['new'] = $tmp; - $data['old'] = $tmp; - $this->action = 'update'; - $this->update_letsencrypt = true; - // just run the update function - $this->update($event_name, $data); - - } else { - //* This is a website - // Deleting the vhost file, symlink and the data directory - $vhost_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost'); - - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - $vhost_symlink = escapeshellcmd($web_config['nginx_vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost'); - if(is_link($vhost_symlink)){ - $app->system->unlink($vhost_symlink); - $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG); - } - - $app->system->unlink($vhost_file); - $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain' || $data['old']['type'] == 'vhostalias') { - $docroot = escapeshellcmd($data['old']['document_root']); - if($docroot != '' && !stristr($docroot, '..')) { - if($data['old']['type'] == 'vhost') { - // this is a vhost - we delete everything in here. - exec('rm -rf '.$docroot); - } elseif(!stristr($data['old']['web_folder'], '..')) { - // this is a vhost subdomain - // IMPORTANT: do some folder checks before we delete this! - $do_delete = true; - $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times - if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1); - if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1); - - $path_elements = explode('/', $delete_folder); - - if($path_elements[0] == 'web' || $path_elements[0] === '') { - // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here! - // we use strict check as otherwise directories named '0' may not be deleted - $do_delete = false; - } else { - // read all vhost subdomains and alias with same parent domain - $used_paths = array(); - $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE (type = 'vhostsubdomain' OR type = 'vhostalias') AND parent_domain_id = ? AND domain_id != ?", $data['old']['parent_domain_id'], $data['old']['domain_id']); - foreach($tmp as $tmprec) { - // we normalize the folder entries because we need to compare them - $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times - if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1); - if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1); - - // add this path and it's parent paths to used_paths array - while(strpos($tmp_folder, '/') !== false) { - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/')); - } - if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder; - } - unset($tmp); - - // loop and check if the path is still used and stop at first used one - // set do_delete to false so nothing gets deleted if the web_folder itself is still used - $do_delete = false; - while(count($path_elements) > 0) { - $tmp_folder = implode('/', $path_elements); - if(in_array($tmp_folder, $used_paths) == true) break; - - // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true - $delete_folder = $tmp_folder; - $do_delete = true; - array_pop($path_elements); - } - unset($tmp_folder); - unset($used_paths); - } - - if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder); - - unset($delete_folder); - unset($path_elements); - } - } - - //remove the php fastgi starter script if available - if ($data['old']['php'] == 'fast-cgi') { - $this->php_fpm_pool_delete($data, $web_config); - $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['fastcgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($fastcgi_starter_path)) { - exec('rm -rf '.$fastcgi_starter_path); - } - } else { - $fcgi_starter_script = $fastcgi_starter_path.$web_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id']; - if (file_exists($fcgi_starter_script)) { - exec('rm -f '.$fcgi_starter_script); - } - } - } - - // remove PHP-FPM pool - if ($data['old']['php'] == 'php-fpm') { - $this->php_fpm_pool_delete($data, $web_config); - } - - //remove the php cgi starter script if available - if ($data['old']['php'] == 'cgi') { - // TODO: fetch the date from the server-settings - $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/'; - - $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']); - if($data['old']['type'] == 'vhost') { - if (is_dir($cgi_starter_path)) { - exec('rm -rf '.$cgi_starter_path); - } - } else { - $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id']; - if (file_exists($cgi_starter_script)) { - exec('rm -f '.$cgi_starter_script); - } - } - } - - $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG); - - // Delete the symlinks for the sites - $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']); - $client_id = intval($client['client_id']); - unset($client); - $tmp_symlinks_array = explode(':', $web_config['website_symlinks']); - if(is_array($tmp_symlinks_array)) { - foreach($tmp_symlinks_array as $tmp_symlink) { - $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink); - $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink); - // Remove trailing slash - if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1); - // delete the symlink - if(is_link($tmp_symlink)) { - $app->system->unlink($tmp_symlink); - $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG); - } - } - } - // end removing symlinks - } - - // Delete the log file directory - $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']); - if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir); - $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG); - - if($data['old']['type'] == 'vhost') { - //delete the web user - $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel'; - $command .= ' '.escapeshellcmd($data['old']['system_user']); - exec($command); - if($nginx_chrooted) $app->system->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command); - - } - - //* Remove the awstats configuration file - if($data['old']['stats_type'] == 'awstats') { - $this->awstats_delete($data, $web_config); - } - - //* Delete the web-backups - if($data['old']['type'] == 'vhost') { - $server_config = $app->getconf->get_server_config($conf['server_id'], 'server'); - $backup_dir = $server_config['backup_dir']; - $mount_backup = true; - if($server_config['backup_dir'] != '' && $server_config['backup_delete'] == 'y') { - //* mount backup directory, if necessary - if( $server_config['backup_dir_is_mount'] == 'y' && !$app->system->mount_backup_dir($backup_dir) ) $mount_backup = false; - - if($mount_backup){ - $web_backup_dir = $backup_dir.'/web'.$data_old['domain_id']; - //** do not use rm -rf $web_backup_dir because database(s) may exits - exec(escapeshellcmd('rm -f '.$web_backup_dir.'/web'.$data_old['domain_id'].'_').'*'); - //* cleanup database - $sql = "DELETE FROM web_backup WHERE server_id = ? AND parent_domain_id = ? AND filename LIKE ?"; - $app->db->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - if($app->db->dbHost != $app->dbmaster->dbHost) $app->dbmaster->query($sql, $conf['server_id'], $data_old['domain_id'], "web".$data_old['domain_id']."_%"); - - $app->log('Deleted the web backup files', LOGLEVEL_DEBUG); - } - } - } - - $app->services->restartServiceDelayed('httpd', 'reload'); - - } - + global $app; - if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true); + $app->plugin_webserver_base->eventDelete($event_name, $data, 'nginx'); } - //* This function is called when a IP on the server is inserted, updated or deleted + //* This function is called when a IP on the server is inserted, updated or deleted or when anon_ip setting is altered function server_ip($event_name, $data) { - return; + global $app; + + $app->plugin_webserver_base->eventServerIp($event_name, $data, 'nginx'); + } //* Create or update the .htaccess folder protection function web_folder_user($event_name, $data) { - global $app, $conf; - - $app->uses('system'); - - if($event_name == 'web_folder_user_delete') { - $folder_id = $data['old']['web_folder_id']; - } else { - $folder_id = $data['new']['web_folder_id']; - } - - $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ?", $folder_id); - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) { - $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($folder_path)) { - $app->system->mkdirpath($folder_path, 0755, $website['system_user'], $website['system_group']); - } - - //* Create empty .htpasswd file, if it does not exist - if(!is_file($folder_path.'.htpasswd')) { - $app->system->touch($folder_path.'.htpasswd'); - $app->system->chmod($folder_path.'.htpasswd', 0755); - $app->system->chown($folder_path.'.htpasswd', $website['system_user']); - $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']); - $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } + global $app; - //* Add or remove the user from .htpasswd file - if($event_name == 'web_folder_user_delete') { - $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':'); - $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG); - } else { - if($data['new']['active'] == 'y') { - $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1); - $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG); - } - } + $app->plugin_webserver_base->eventWebFolderUser($event_name, $data, 'nginx'); - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); } //* Remove .htpasswd file, when folder protection is removed function web_folder_delete($event_name, $data) { - global $app, $conf; - - $folder_id = $data['old']['web_folder_id']; - - $folder = $data['old']; - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $folder['parent_domain_id']); - - if(!is_array($folder) or !is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1); - if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1); - $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']); - if(substr($folder_path, -1) != '/') $folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Remove .htpasswd file - if(is_file($folder_path.'.htpasswd')) { - $app->system->unlink($folder_path.'.htpasswd'); - $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } + global $app; - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); + $app->plugin_webserver_base->eventWebFolderDelete($event_name, $data, 'nginx'); } //* Update folder protection, when path has been changed function web_folder_update($event_name, $data) { - global $app, $conf; - - $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); - - if(!is_array($website)) { - $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG); - return false; - } - - $web_folder = 'web'; - if($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') $web_folder = $website['web_folder']; - - //* Get the folder path. - if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1); - if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1); - $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']); - if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/'; - - if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1); - if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1); - $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']); - if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/'; - - //* Check if the resulting path is inside the docroot - if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) { - $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) { - $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG); - return false; - } - - //* Check if the resulting path is inside the docroot - if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) { - $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG); - return false; - } - - //* Create the folder path, if it does not exist - if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path); - - if($data['old']['path'] != $data['new']['path']) { - - - //* move .htpasswd file - if(is_file($old_folder_path.'.htpasswd')) { - $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd'); - $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG); - } - - } - - // write basic auth configuration to vhost file because nginx does not support .htaccess - $webdata['new'] = $webdata['old'] = $website; - $this->update('web_domain_update', $webdata); - } - - function _create_web_folder_auth_configuration($website){ - global $app, $conf; - //* Create the domain.auth file which is included in the vhost configuration file - $app->uses('getconf'); - $web_config = $app->getconf->get_server_config($conf['server_id'], 'web'); - $basic_auth_file = escapeshellcmd($web_config['nginx_vhost_conf_dir'].'/'.$website['domain'].'.auth'); - //$app->load('tpl'); - //$tpl = new tpl(); - //$tpl->newTemplate('nginx_http_authentication.auth.master'); - $website_auth_locations = $app->db->queryAllRecords("SELECT * FROM web_folder WHERE active = 'y' AND parent_domain_id = ?", $website['domain_id']); - $basic_auth_locations = array(); - if(is_array($website_auth_locations) && !empty($website_auth_locations)){ - foreach($website_auth_locations as $website_auth_location){ - if(substr($website_auth_location['path'], 0, 1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 1); - if(substr($website_auth_location['path'], -1) == '/') $website_auth_location['path'] = substr($website_auth_location['path'], 0, -1); - if($website_auth_location['path'] != ''){ - $website_auth_location['path'] .= '/'; - } - $basic_auth_locations[] = array('htpasswd_location' => '/'.$website_auth_location['path'], - 'htpasswd_path' => $website['document_root'].'/' . (($website['type'] == 'vhostsubdomain' || $website['type'] == 'vhostalias') ? $website['web_folder'] : 'web') . '/'.$website_auth_location['path']); - } - } - return $basic_auth_locations; - //$tpl->setLoop('basic_auth_locations', $basic_auth_locations); - //file_put_contents($basic_auth_file,$tpl->grab()); - //$app->log('Writing the http basic authentication file: '.$basic_auth_file,LOGLEVEL_DEBUG); - //unset($tpl); - //$app->services->restartServiceDelayed('httpd','reload'); - } - - //* Update the awstats configuration file - private function awstats_update ($data, $web_config) { global $app; - $web_folder = $data['new']['web_folder']; - if($data['new']['type'] == 'vhost') $web_folder = 'web'; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats"); - if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) { - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - } - - $content = ''; - if (is_file($awstats_conf_dir."/awstats.conf")) { - $include_file = $awstats_conf_dir."/awstats.conf"; - } elseif (is_file($awstats_conf_dir."/awstats.model.conf")) { - $include_file = $awstats_conf_dir."/awstats.model.conf"; - } - $content .= "Include \"".$include_file."\"\n"; - $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n"; - $content .= "SiteDomain=\"".$data['new']['domain']."\"\n"; - $content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n"; - - if (isset($include_file)) { - $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content); - $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG); - } else { - $app->log("No awstats base config found. Either awstats.conf or awstats.model.conf must exist in ".$awstats_conf_dir.".", LOGLEVEL_WARN); - } - } - - if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html"); - if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) { - $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } else { - $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php"); - } + $app->plugin_webserver_base->eventWebFolderUpdate($event_name, $data, 'nginx'); } - //* Delete the awstats configuration file - private function awstats_delete ($data, $web_config) { + public function ftp_user_delete($event_name, $data) { global $app; - $awstats_conf_dir = $web_config['awstats_conf_dir']; - - if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) { - $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf'); - $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG); - } - } - - //* Update the PHP-FPM pool configuration file - private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) { - global $app, $conf; - $pool_dir = trim($pool_dir); - $rh_releasefiles = array('/etc/centos-release', '/etc/redhat-release'); - - if($data['new']['php'] == 'php-fpm'){ - if(trim($data['new']['fastcgi_php_version']) != ''){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } else { - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - } - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - if($data['new']['php'] != 'php-fpm'){ - if(@is_file($pool_dir.$pool_name.'.conf')){ - $app->system->unlink($pool_dir.$pool_name.'.conf'); - //$reload = true; - } - if($data['old']['php'] != 'no'){ - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - return; - } - - $app->load('tpl'); - $tpl = new tpl(); - $tpl->newTemplate('php_fpm_pool.conf.master'); - - if($data['new']['php_fpm_chroot'] == 'y'){ - $php_fpm_chroot = 1; - } else { - $php_fpm_chroot = 0; - } - if($data['new']['php_fpm_use_socket'] == 'y'){ - $use_tcp = 0; - $use_socket = 1; - if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir); - } else { - $use_tcp = 1; - $use_socket = 0; - } - $tpl->setVar('use_tcp', $use_tcp); - $tpl->setVar('use_socket', $use_socket); - $tpl->setVar('php_fpm_chroot', $php_fpm_chroot); - - $fpm_socket = $socket_dir.$pool_name.'.sock'; - $tpl->setVar('fpm_socket', $fpm_socket); - $tpl->setVar('fpm_listen_mode', '0660'); - - $tpl->setVar('fpm_pool', $pool_name); - $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1); - $tpl->setVar('fpm_user', $data['new']['system_user']); - - //Red Hat workaround for group ownership of socket files - foreach($rh_releasefiles as $rh_file) { - if(file_exists($rh_file) && (filesize($rh_file) > 0)) { - $tmp = file_get_contents($rh_file); - if(preg_match('/[67]+\.[0-9]+/m', $tmp)) { - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $data['new']['system_group']); - } - unset($tmp); - } elseif(!file_exists($rh_file)) { - //OS seems to be not Red Hat'ish - $tpl->setVar('fpm_group', $data['new']['system_group']); - $tpl->setVar('fpm_listen_group', $web_config['group']); - } - break; - } - - $tpl->setVar('fpm_listen_user', $data['new']['system_user']); - $tpl->setVar('fpm_domain', $data['new']['domain']); - $tpl->setVar('pm', $data['new']['pm']); - $tpl->setVar('pm_max_children', $data['new']['pm_max_children']); - $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']); - $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']); - $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']); - $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']); - $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']); - $tpl->setVar('document_root', $data['new']['document_root']); - $tpl->setVar('security_level', $web_config['security_level']); - $tpl->setVar('domain', $data['new']['domain']); - $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']); - if($php_fpm_chroot){ - $document_root = $data['new']['document_root']; - $domain = $data['new']['domain']; - $php_open_basedir = str_replace(":/srv/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace(":/var/www/$domain/web",'',$php_open_basedir); - $php_open_basedir = str_replace("$document_root",'',$php_open_basedir); - } - $tpl->setVar('php_open_basedir', $php_open_basedir); - if($php_open_basedir != ''){ - $tpl->setVar('enable_php_open_basedir', ''); - } else { - $tpl->setVar('enable_php_open_basedir', ';'); - } - - // Custom php.ini settings - $final_php_ini_settings = array(); - $custom_php_ini_settings = trim($data['new']['custom_php_ini']); - - if(intval($data['new']['directive_snippets_id']) > 0){ - $snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($data['new']['directive_snippets_id'])); - if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){ - $required_php_snippets = explode(',', trim($snippet['required_php_snippets'])); - if(is_array($required_php_snippets) && !empty($required_php_snippets)){ - foreach($required_php_snippets as $required_php_snippet){ - $required_php_snippet = intval($required_php_snippet); - if($required_php_snippet > 0){ - $php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE ".($snippet['master_directive_snippets_id'] > 0 ? 'master_' : '')."directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet); - $php_snippet['snippet'] = trim($php_snippet['snippet']); - if($php_snippet['snippet'] != ''){ - $custom_php_ini_settings .= "\n".$php_snippet['snippet']; - } - } - } - } - } - } - - $custom_session_save_path = false; - if($custom_php_ini_settings != ''){ - // Make sure we only have Unix linebreaks - $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings); - $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings); - $ini_settings = explode("\n", $custom_php_ini_settings); - if(is_array($ini_settings) && !empty($ini_settings)){ - foreach($ini_settings as $ini_setting){ - $ini_setting = trim($ini_setting); - if(substr($ini_setting, 0, 1) == ';') continue; - if(substr($ini_setting, 0, 1) == '#') continue; - if(substr($ini_setting, 0, 2) == '//') continue; - list($key, $value) = explode('=', $ini_setting, 2); - $value = trim($value); - if($value != ''){ - $key = trim($key); - if($key == 'session.save_path') $custom_session_save_path = true; - switch (strtolower($value)) { - case '0': - // PHP-FPM might complain about invalid boolean value if you use 0 - $value = 'off'; - case '1': - case 'on': - case 'off': - case 'true': - case 'false': - case 'yes': - case 'no': - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value); - break; - default: - $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value); - } - } - } - } - } - - $tpl->setVar('custom_session_save_path', ($custom_session_save_path ? 'y' : 'n')); - - $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings); - - $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab()); - $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - unset($tpl); - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $conf["server_id"]); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - //* Delete the PHP-FPM pool configuration file - private function php_fpm_pool_delete ($data, $web_config) { - global $app, $conf; - - if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] != 'no'){ - $default_php_fpm = false; - list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version'])); - if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/'; - } else { - $default_php_fpm = true; - } - - if($default_php_fpm){ - $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']); - } else { - $pool_dir = $custom_php_fpm_pool_dir; - } - $pool_dir = trim($pool_dir); - - if(substr($pool_dir, -1) != '/') $pool_dir .= '/'; - $pool_name = 'web'.$data['old']['domain_id']; - - if ( @is_file($pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - } - - // delete pool in all other PHP versions - $default_pool_dir = trim(escapeshellcmd($web_config['php_fpm_pool_dir'])); - if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/'; - if($default_pool_dir != $pool_dir){ - if ( @is_file($default_pool_dir.$pool_name.'.conf') ) { - $app->system->unlink($default_pool_dir.$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - $php_versions = $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 = ?", $data['old']['server_id']); - if(is_array($php_versions) && !empty($php_versions)){ - foreach($php_versions as $php_version){ - $php_version['php_fpm_pool_dir'] = trim($php_version['php_fpm_pool_dir']); - if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/'; - if($php_version['php_fpm_pool_dir'] != $pool_dir){ - if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) { - $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf'); - $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG); - $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']); - } - } - } - } - - // Reload current PHP-FPM after all others - sleep(1); - if(!$default_php_fpm){ - $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script); - } else { - $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']); - } - } - - private function nginx_replace($matches){ - $location = 'location'.($matches[1] != '' ? ' '.$matches[1] : '').' '.$matches[2].' '.$matches[3]; - if($matches[4] == '##merge##' || $matches[7] == '##merge##') $location .= ' ##merge##'; - if($matches[4] == '##delete##' || $matches[7] == '##delete##') $location .= ' ##delete##'; - $location .= "\n"; - $location .= $matches[5]."\n"; - $location .= $matches[6]; - return $location; - } - - private function nginx_merge_locations($vhost_conf) { - global $app, $conf; - - if(preg_match('/##subroot (.+?)\s*##/', $vhost_conf, $subroot)) { - if(!preg_match('/^(?:[a-z0-9\/_-]|\.(?!\.))+$/iD', $subroot[1])) { - $app->log('Token ##subroot is unsecure (server ID: '.$conf['server_id'].').', LOGLEVEL_WARN); - } else { - $insert_pos = strpos($vhost_conf, ';', strpos($vhost_conf, 'root ')); - $vhost_conf = substr_replace($vhost_conf, ltrim($subroot[1], '/'), $insert_pos, 0); - } - } - - $lines = explode("\n", $vhost_conf); - - // if whole location block is in one line, split it up into multiple lines - if(is_array($lines) && !empty($lines)){ - $linecount = sizeof($lines); - for($h=0;$h<$linecount;$h++){ - // remove comments - if(substr(trim($lines[$h]), 0, 1) == '#'){ - unset($lines[$h]); - continue; - } - - $lines[$h] = rtrim($lines[$h]); - /* - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], ';') !== false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - $lines[$h] = str_replace(";", ";\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - if(substr(ltrim($lines[$h]), 0, 8) == 'location' && strpos($lines[$h], '{') !== false && strpos($lines[$h], '}') !== false && strpos($lines[$h], ';') === false){ - $lines[$h] = str_replace("{", "{\n", $lines[$h]); - if(strpos($lines[$h], '##merge##') !== false){ - $lines[$h] = str_replace('##merge##', '', $lines[$h]); - $lines[$h] = substr($lines[$h],0,strpos($lines[$h], '{')).' ##merge##'.substr($lines[$h],strpos($lines[$h], '{')+1); - } - } - */ - $pattern = '/^[^\S\n]*location[^\S\n]+(?:(.+)[^\S\n]+)?(.+)[^\S\n]*(\{)[^\S\n]*(##merge##|##delete##)?[^\S\n]*(.+)[^\S\n]*(\})[^\S\n]*(##merge##|##delete##)?[^\S\n]*$/'; - $lines[$h] = preg_replace_callback($pattern, array($this, 'nginx_replace') , $lines[$h]); - } - } - $vhost_conf = implode("\n", $lines); - unset($lines); - unset($linecount); - - $lines = explode("\n", $vhost_conf); - - if(is_array($lines) && !empty($lines)){ - $locations = array(); - $locations_to_delete = array(); - $islocation = false; - $linecount = sizeof($lines); - $server_count = 0; - - for($i=0;$i<$linecount;$i++){ - $l = trim($lines[$i]); - if(substr($l, 0, 8) == 'server {') $server_count += 1; - if($server_count > 1) break; - if(substr($l, 0, 8) == 'location' && !$islocation){ - - $islocation = true; - $level = 0; - - // Remove unnecessary whitespace - $l = preg_replace('/\s\s+/', ' ', $l); - - $loc_parts = explode(' ', $l); - // see http://wiki.nginx.org/HttpCoreModule#location - if($loc_parts[1] == '=' || $loc_parts[1] == '~' || $loc_parts[1] == '~*' || $loc_parts[1] == '^~'){ - $location = $loc_parts[1].' '.$loc_parts[2]; - } else { - $location = $loc_parts[1]; - } - unset($loc_parts); - - if(!isset($locations[$location]['action'])) $locations[$location]['action'] = 'replace'; - if(substr($l, -9) == '##merge##') $locations[$location]['action'] = 'merge'; - if(substr($l, -10) == '##delete##') $locations[$location]['action'] = 'delete'; - - if(!isset($locations[$location]['open_tag'])) $locations[$location]['open_tag'] = ' location '.$location.' {'; - if(!isset($locations[$location]['location']) || $locations[$location]['action'] == 'replace') $locations[$location]['location'] = ''; - if($locations[$location]['action'] == 'delete') $locations_to_delete[] = $location; - if(!isset($locations[$location]['end_tag'])) $locations[$location]['end_tag'] = ' }'; - if(!isset($locations[$location]['start_line'])) $locations[$location]['start_line'] = $i; - - unset($lines[$i]); - - } else { - - if($islocation){ - $openingbracketpos = strrpos($l, '{'); - if($openingbracketpos !== false){ - $level += 1; - } - $closingbracketpos = strrpos($l, '}'); - if($closingbracketpos !== false && $level > 0 && $closingbracketpos >= intval($openingbracketpos)){ - $level -= 1; - $locations[$location]['location'] .= $lines[$i]."\n"; - } elseif($closingbracketpos !== false && $level == 0 && $closingbracketpos >= intval($openingbracketpos)){ - $islocation = false; - } else { - $locations[$location]['location'] .= $lines[$i]."\n"; - } - unset($lines[$i]); - } - - } - } + $ftpquota_file = $data['old']['dir'].'/.ftpquota'; + if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file); - if(is_array($locations) && !empty($locations)){ - if(is_array($locations_to_delete) && !empty($locations_to_delete)){ - foreach($locations_to_delete as $location_to_delete){ - if(isset($locations[$location_to_delete])) unset($locations[$location_to_delete]); - } - } - - foreach($locations as $key => $val){ - $new_location = $val['open_tag']."\n".$val['location'].$val['end_tag']; - $lines[$val['start_line']] = $new_location; - } - } - ksort($lines); - $vhost_conf = implode("\n", $lines); - } - - return trim($vhost_conf); } function client_delete($event_name, $data) { - global $app, $conf; - - $app->uses("getconf"); - $web_config = $app->getconf->get_server_config($conf["server_id"], 'web'); - - $client_id = intval($data['old']['client_id']); - if($client_id > 0) { - - $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id; - if(is_dir($client_dir) && !stristr($client_dir, '..')) { - // remove symlinks from $client_dir - $files = array_diff(scandir($client_dir), array('.', '..')); - if(is_array($files) && !empty($files)){ - foreach($files as $file){ - if(is_link($client_dir.'/'.$file)){ - unlink($client_dir.'/'.$file); - $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG); - } - } - } - - @rmdir($client_dir); - $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG); - } - - if($app->system->is_group('client'.$client_id)){ - $app->system->_exec('groupdel client'.$client_id); - $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG); - } - } - - } - - private function _checkTcp ($host, $port) { - - $fp = @fsockopen($host, $port, $errno, $errstr, 2); - - if ($fp) { - fclose($fp); - return true; - } else { - return false; - } - } - - private function _rewrite_quote($string) { - return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string); - } - - private function url_is_local($hostname, $domain_id){ global $app; - // ORDER BY clause makes sure wildcard subdomains (*) are listed last in the result array so that we can find direct matches first - $webs = $app->db->queryAllRecords("SELECT * FROM web_domain WHERE active = 'y' ORDER BY subdomain ASC"); - if(is_array($webs) && !empty($webs)){ - foreach($webs as $web){ - // web domain doesn't match hostname - if(substr($hostname, -strlen($web['domain'])) != $web['domain']) continue; - // own vhost and therefore server {} container of its own - //if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') continue; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - //if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') continue; - - if($web['subdomain'] == '*'){ - $pattern = '/\.?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'none'){ - if($web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if($web['subdomain'] == 'www'){ - if($web['domain'] == $hostname || $web['subdomain'].'.'.$web['domain'] == $hostname){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - $pattern = '/^(www\.)?'.str_replace('.', '\.', $web['domain']).'$/i'; - } - if(preg_match($pattern, $hostname)){ - if($web['domain_id'] == $domain_id || $web['parent_domain_id'] == $domain_id){ - // own vhost and therefore server {} container of its own - if($web['type'] == 'vhostsubdomain' || $web['type'] == 'vhostalias') return false; - // alias domains/subdomains using rewrites and therefore a server {} container of their own - if(($web['type'] == 'alias' || $web['type'] == 'subdomain') && $web['redirect_type'] != '' && $web['redirect_path'] != '') return false; - return true; - } else { - return false; - } - } - } - } - - return false; + $app->plugin_webserver_base->eventClientDelete($event_name, $data, 'nginx'); } - private function get_seo_redirects($web, $prefix = '', $force_subdomain = false){ - // $force_subdomain = 'none|www' - $seo_redirects = array(); - - if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*'; - - if(($web['subdomain'] == 'www' || $web['subdomain'] == '*') && $force_subdomain != 'www'){ - if($web['seo_redirect'] == 'non_www_to_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){ - // ^(example\.com|(?!\bwww\b)\.example\.com)$ - // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_www_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - if($force_subdomain != 'none'){ - if($web['seo_redirect'] == 'www_to_non_www'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www.'.$web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '='; - } - if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){ - // ^(.+)\.example\.com$ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '^(.+)\.'.str_replace('.', '\.', $web['domain']).'$'; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '~*'; - } - if($web['seo_redirect'] == '*_to_domain_tld'){ - $seo_redirects[$prefix.'seo_redirect_origin_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain']; - $seo_redirects[$prefix.'seo_redirect_operator'] = '!='; - } - } - return $seo_redirects; - } } // end class -?> -- GitLab From d27980e2b42e595c829d744e502f805b08d1ec7e Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Thu, 13 Dec 2018 21:22:42 +0100 Subject: [PATCH 282/310] Add filename in the error to see what is being opened --- interface/lib/app.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php index ab7d90334..7af764f92 100755 --- a/interface/lib/app.inc.php +++ b/interface/lib/app.inc.php @@ -195,14 +195,14 @@ class app { /* if (is_writable($this->_conf['log_file'])) { if (!$fp = fopen ($this->_conf['log_file'], 'a')) { - $this->error('Unable to open logfile.'); + $this->error('Unable to open logfile: ' . $this->_conf['log_file']); } if (!fwrite($fp, date('d.m.Y-H:i').' - '. $msg."\r\n")) { - $this->error('Unable to write to logfile.'); + $this->error('Unable to write to logfile: ' . $this->_conf['log_file']); } fclose($fp); } else { - $this->error('Unable to write to logfile.'); + $this->error('Unable to write to logfile: ' . $this->_conf['log_file']); } */ } -- GitLab From c76e0cc2afb7777f85e4b572c9325b8d369c34c8 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Wed, 2 Jan 2019 13:43:51 +0100 Subject: [PATCH 283/310] - fixed typos from merge in previous commit --- install/install.php | 5 +++-- install/update.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/install/install.php b/install/install.php index ae0da7e65..f99a99d9e 100644 --- a/install/install.php +++ b/install/install.php @@ -553,9 +553,10 @@ if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPCon } // Create SSL certs for non-webserver(s)? -if(!file_exists(/usr/local/ispconfig/interface/ssl/ispserver.crt)) { - if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') +if(!file_exists('/usr/local/ispconfig/interface/ssl/ispserver.crt')) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { $inst->make_ispconfig_ssl_cert(); + } } $inst->raiseEvent('install_ispconfig::before'); diff --git a/install/update.php b/install/update.php index 8e5a1ff93..03c203d2b 100644 --- a/install/update.php +++ b/install/update.php @@ -504,9 +504,10 @@ if ($inst->install_ispconfig_interface) { } // Create SSL certs for non-webserver(s)? -if(!file_exists(/usr/local/ispconfig/interface/ssl/ispserver.crt)) { - if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') +if(!file_exists('/usr/local/ispconfig/interface/ssl/ispserver.crt')) { + if(strtolower($inst->simple_query('Do you want to create SSL certs for your server?', array('y', 'n'), 'y')) == 'y') { $inst->make_ispconfig_ssl_cert(); + } } $inst->raiseEvent('install_ispconfig::before'); -- GitLab From 38751c07808d945ecba7c53084b2ce99bfafb00b Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 8 Jan 2019 10:22:40 +0100 Subject: [PATCH 284/310] Fixed #5214 relayhost without authentication --- server/plugins-available/postfix_server_plugin.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/plugins-available/postfix_server_plugin.inc.php b/server/plugins-available/postfix_server_plugin.inc.php index 64c557139..2b0b1ba67 100644 --- a/server/plugins-available/postfix_server_plugin.inc.php +++ b/server/plugins-available/postfix_server_plugin.inc.php @@ -89,7 +89,7 @@ class postfix_server_plugin { $content = file_exists('/etc/postfix/sasl_passwd') ? file_get_contents('/etc/postfix/sasl_passwd') : ''; $content = preg_replace('/^'.preg_quote($old_ini_data['email']['relayhost']).'\s+[^\n]*(:?\n|)/m','',$content); - if (!empty($mail_config['relayhost']) || !empty($mail_config['relayhost_user']) || !empty($mail_config['relayhost_password'])) { + if (!empty($mail_config['relayhost_user']) || !empty($mail_config['relayhost_password'])) { $content .= "\n".$mail_config['relayhost'].' '.$mail_config['relayhost_user'].':'.$mail_config['relayhost_password']; } -- GitLab From 64be2d7465177f007b6584edce8c0c9999fcef5e Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 8 Jan 2019 11:21:20 +0100 Subject: [PATCH 285/310] Implemented #5209 Add support for renaming empty databases --- server/plugins-available/mysql_clientdb_plugin.inc.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/plugins-available/mysql_clientdb_plugin.inc.php b/server/plugins-available/mysql_clientdb_plugin.inc.php index 14052e5b7..efe7142c8 100644 --- a/server/plugins-available/mysql_clientdb_plugin.inc.php +++ b/server/plugins-available/mysql_clientdb_plugin.inc.php @@ -331,6 +331,7 @@ class mysql_clientdb_plugin { $timestamp = time(); $tables = $link->query("SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema='".$old_name."' AND TABLE_TYPE='BASE TABLE'"); + $tables_all = $link->query("SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema='".$old_name."'"); if ($tables->num_rows > 0) { while ($row = $tables->fetch_assoc()) { $tables_array[] = $row['TABLE_NAME']; @@ -436,6 +437,11 @@ class mysql_clientdb_plugin { } } + } elseif ($tables->num_rows == 0 && $tables_all->num_rows == 0) { + //* Rename empty database by creating a new one and dropping the old database + $this->db_insert($event_name, $data); + $this->db_delete($event_name, $data); + } else { //* SELECT TABLE_NAME error $app->log('Unable to rename database '.$old_name.' to '.$new_name, LOGLEVEL_ERROR); } -- GitLab From 9d417c0df251bee77b02d7275421f16434c0f1f2 Mon Sep 17 00:00:00 2001 From: Till Brehm Date: Tue, 8 Jan 2019 12:07:43 +0100 Subject: [PATCH 286/310] Implements new API functions #5215 and #5202 --- interface/lib/classes/remote.d/admin.inc.php | 43 +++++++++++++++++++ interface/lib/classes/remote.d/client.inc.php | 21 +++++++++ interface/lib/classes/remote.d/dns.inc.php | 15 +++++++ .../API-docs/client_get_by_groupid.html | 29 +++++++++++++ .../API-docs/dns_slave_delete.html | 29 +++++++++++++ remoting_client/API-docs/dns_slave_get.html | 29 +++++++++++++ remoting_client/API-docs/sys_datalog_get.html | 29 +++++++++++++ .../API-docs/sys_datalog_get_by_tstamp.html | 29 +++++++++++++ 8 files changed, 224 insertions(+) create mode 100644 remoting_client/API-docs/client_get_by_groupid.html create mode 100644 remoting_client/API-docs/dns_slave_delete.html create mode 100644 remoting_client/API-docs/dns_slave_get.html create mode 100644 remoting_client/API-docs/sys_datalog_get.html create mode 100644 remoting_client/API-docs/sys_datalog_get_by_tstamp.html diff --git a/interface/lib/classes/remote.d/admin.inc.php b/interface/lib/classes/remote.d/admin.inc.php index 8b0c4730e..793f9ed33 100644 --- a/interface/lib/classes/remote.d/admin.inc.php +++ b/interface/lib/classes/remote.d/admin.inc.php @@ -272,6 +272,49 @@ class remoting_admin extends remoting { return $app->db->query('DELETE FROM sys_config WHERE `group` = ? AND `name` = ?',$group,$name); } + + // Get datalog information with tstamp >= + public function sys_datalog_get_by_tstamp($session_id, $tstamp) + { + global $app; + + if(!$this->checkPerm($session_id, 'server_get')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + $tstamp = $app->functions->intval($tstamp); + + if($tstamp > 0) { + $rec = $app->db->queryAllRecords("SELECT datalog_id, server_id, dbtable, dbidx, action, tstamp, user, data, status, error FROM sys_datalog WHERE tstamp >= ? ORDER BY datalog_id DESC", $tstamp); + return $rec; + } + } + + // Get datalog information by datalog_id + public function sys_datalog_get($session_id, $datalog_id, $newer = false) + { + global $app; + + if(!$this->checkPerm($session_id, 'server_get')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + $tstamp = $app->functions->intval($tstamp); + + if($datalog_id > 0 && $newer === true) { + $rec = $app->db->queryAllRecords("SELECT datalog_id, server_id, dbtable, dbidx, action, tstamp, user, data, status, error FROM sys_datalog WHERE datalog_id >= ? ORDER BY datalog_id DESC", $datalog_id); + return $rec; + } elseif ($datalog_id > 0) { + $rec = $app->db->queryAllRecords("SELECT datalog_id, server_id, dbtable, dbidx, action, tstamp, user, data, status, error FROM sys_datalog WHERE datalog_id = ? ORDER BY datalog_id DESC", $datalog_id); + return $rec; + } else { + throw new SoapFault('invalid_datalog_id', 'The ID passed to the function must be > 0'); + return false; + } + } + } diff --git a/interface/lib/classes/remote.d/client.inc.php b/interface/lib/classes/remote.d/client.inc.php index 5c47c26c7..b91909c9d 100644 --- a/interface/lib/classes/remote.d/client.inc.php +++ b/interface/lib/classes/remote.d/client.inc.php @@ -678,6 +678,27 @@ class remoting_client extends remoting { return $returnval; } + + public function client_get_by_groupid($session_id, $group_id) + { + global $app; + if(!$this->checkPerm($session_id, 'client_get_id')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + + $group_id = $app->functions->intval($group_id); + + $rec = $app->db->queryOneRecord("SELECT client_id FROM sys_group WHERE groupid = ?", $group_id); + if(isset($rec['client_id'])) { + $client_id = $app->functions->intval($rec['client_id']); + return $this->client_get($session_id, $client_id); + } else { + throw new SoapFault('no_group_found', 'There is no client for this group ID.'); + return false; + } + } + } ?> diff --git a/interface/lib/classes/remote.d/dns.inc.php b/interface/lib/classes/remote.d/dns.inc.php index 363af8f48..faae06dc2 100644 --- a/interface/lib/classes/remote.d/dns.inc.php +++ b/interface/lib/classes/remote.d/dns.inc.php @@ -197,6 +197,21 @@ class remoting_dns extends remoting { return $app->remoting_lib->getDataRecord($primary_id); } + //* Get slave zone details + public function dns_slave_get($session_id, $primary_id) + { + global $app; + + if(!$this->checkPerm($session_id, 'dns_zone_get')) { + throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); + return false; + } + $app->uses('remoting_lib'); + $app->remoting_lib->loadFormDef('../dns/form/dns_slave.tform.php'); + return $app->remoting_lib->getDataRecord($primary_id); + } + + //* Add a slave zone public function dns_slave_add($session_id, $client_id, $params) { diff --git a/remoting_client/API-docs/client_get_by_groupid.html b/remoting_client/API-docs/client_get_by_groupid.html new file mode 100644 index 000000000..60fb58e47 --- /dev/null +++ b/remoting_client/API-docs/client_get_by_groupid.html @@ -0,0 +1,29 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

client_get_by_groupid($session_id, $groupid);

+
+

Description:

+

Shows client information of user.


+

Input Variables:

+

$session_id, $groupid

+

Parameters (in $params):

+

None

+

Output:

+

Returns client information from client tyble by groupid of that client.

+ +
+ + diff --git a/remoting_client/API-docs/dns_slave_delete.html b/remoting_client/API-docs/dns_slave_delete.html new file mode 100644 index 000000000..baaca8408 --- /dev/null +++ b/remoting_client/API-docs/dns_slave_delete.html @@ -0,0 +1,29 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

dns_slave_delete($session_id, $primary_id);

+
+

Description:

+

Deletes a dns slave zone.


+

Input Variables:

+

$session_id, $primary_id

+

Parameters (in $params):

+

None

+

Output:

+

Returns the number of deleted records.

+ +
+ + diff --git a/remoting_client/API-docs/dns_slave_get.html b/remoting_client/API-docs/dns_slave_get.html new file mode 100644 index 000000000..8b66dd300 --- /dev/null +++ b/remoting_client/API-docs/dns_slave_get.html @@ -0,0 +1,29 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

dns_slave_get($session_id, $primary_id);

+
+

Description:

+

Retrieves information about a dns slave zone.


+

Input Variables:

+

$session_id, $primary_id

+

Parameters (in $params):

+

None

+

Output:

+

Returns all fields and values of the chosen dns slave zone.

+ +
+ + diff --git a/remoting_client/API-docs/sys_datalog_get.html b/remoting_client/API-docs/sys_datalog_get.html new file mode 100644 index 000000000..9f1714609 --- /dev/null +++ b/remoting_client/API-docs/sys_datalog_get.html @@ -0,0 +1,29 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

sys_datalog_get($session_id, $datalog_id, $newer);

+
+

Description:

+

Retrieves information from sys_datalog.


+

Input Variables:

+

$session_id, $datalog_id, $newer (true/false)

+

Parameters (in $params):

+

None

+

Output:

+

Returns all fields and values of the chosen dns slave zone.

+ +
+ + diff --git a/remoting_client/API-docs/sys_datalog_get_by_tstamp.html b/remoting_client/API-docs/sys_datalog_get_by_tstamp.html new file mode 100644 index 000000000..fdc1008c2 --- /dev/null +++ b/remoting_client/API-docs/sys_datalog_get_by_tstamp.html @@ -0,0 +1,29 @@ + +ISPCOnfig 3 remote API documentation + + + + + + + + + + +
+

sys_datalog_get_by_tstamp($session_id, $tstamp);

+
+

Description:

+

Retrieves information from sys_datalog by timestamp. All records that are newer or same than given timestamp are returned.


+

Input Variables:

+

$session_id, $tstamp

+

Parameters (in $params):

+

None

+

Output:

+

Returns all fields and values of the chosen dns slave zone.

+ +
+ + -- GitLab From 41b988f3c630aa0f26ec1982a80654f0cc3a61ef Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 11 Jan 2019 18:12:32 +0100 Subject: [PATCH 287/310] - improved mailer class (content type encoding and subject encoding) --- interface/lib/classes/ispcmail.inc.php | 23 ++++++++++++---------- server/lib/classes/ispcmail.inc.php | 27 ++++++++++++++++---------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php index 209cb5bd4..dfe27edca 100644 --- a/interface/lib/classes/ispcmail.inc.php +++ b/interface/lib/classes/ispcmail.inc.php @@ -430,6 +430,9 @@ class ispcmail { if($text == true && $html == false && $attach == false) { // only text $content_type = 'text/plain; charset="' . strtolower($this->mail_charset) . '"'; + if($this->mail_charset == 'UTF-8') { + $this->headers['Content-Transfer-Encoding'] = '8bit'; + } $textonly = true; } elseif($text == true && $html == false && $attach == true) { // text and attachment @@ -440,6 +443,9 @@ class ispcmail { } elseif($html == true && $text == false && $attach == false) { // html only (or text too) $content_type = 'text/html; charset="' . strtolower($this->mail_charset) . '"'; + if($this->mail_charset == 'UTF-8') { + $this->headers['Content-Transfer-Encoding'] = '8bit'; + } $htmlonly = true; } elseif($html == true && $attach == true) { // html and attachments @@ -564,17 +570,14 @@ class ispcmail { * @access private */ private function _encodeSubject($input, $charset = 'ISO-8859-1') { - /* - if($charset == 'UTF-8' && function_exists('imap_8bit')) { - $input = "=?utf-8?Q?" . imap_8bit($input) . "?="; - } else { - preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches); - foreach ($matches[1] as $value) { - $replacement = preg_replace('/([\x20\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value); - $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input); + if(preg_match('/(?:[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/s', $input)) { + // needs encoding + if(function_exists('imap_8bit')) { + $input = "=?utf-8?Q?" . str_replace("?","=3F", imap_8bit($input)) . "?="; + } else { + $input = '=?utf-8?B?' . base64_encode($input) . '?='; } - }*/ - $input='=?UTF-8?B?'.base64_encode($input).'?='; + } return $input; } diff --git a/server/lib/classes/ispcmail.inc.php b/server/lib/classes/ispcmail.inc.php index 3ffabe8c4..dfe27edca 100644 --- a/server/lib/classes/ispcmail.inc.php +++ b/server/lib/classes/ispcmail.inc.php @@ -430,6 +430,9 @@ class ispcmail { if($text == true && $html == false && $attach == false) { // only text $content_type = 'text/plain; charset="' . strtolower($this->mail_charset) . '"'; + if($this->mail_charset == 'UTF-8') { + $this->headers['Content-Transfer-Encoding'] = '8bit'; + } $textonly = true; } elseif($text == true && $html == false && $attach == true) { // text and attachment @@ -440,6 +443,9 @@ class ispcmail { } elseif($html == true && $text == false && $attach == false) { // html only (or text too) $content_type = 'text/html; charset="' . strtolower($this->mail_charset) . '"'; + if($this->mail_charset == 'UTF-8') { + $this->headers['Content-Transfer-Encoding'] = '8bit'; + } $htmlonly = true; } elseif($html == true && $attach == true) { // html and attachments @@ -564,17 +570,14 @@ class ispcmail { * @access private */ private function _encodeSubject($input, $charset = 'ISO-8859-1') { - /* - if($charset == 'UTF-8' && function_exists('imap_8bit')) { - $input = "=?utf-8?Q?" . imap_8bit($input) . "?="; - } else { - preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches); - foreach ($matches[1] as $value) { - $replacement = preg_replace('/([\x20\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value); - $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input); + if(preg_match('/(?:[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/s', $input)) { + // needs encoding + if(function_exists('imap_8bit')) { + $input = "=?utf-8?Q?" . str_replace("?","=3F", imap_8bit($input)) . "?="; + } else { + $input = '=?utf-8?B?' . base64_encode($input) . '?='; } - }*/ - $input='=?UTF-8?B?'.base64_encode($input).'?='; + } return $input; } @@ -598,6 +601,10 @@ class ispcmail { if($this->smtp_crypt == 'tls') { fputs($this->_smtp_conn, 'STARTTLS' . $this->_crlf); fgets($this->_smtp_conn, 515); + + stream_context_set_option($this->_smtp_conn, 'ssl', 'verify_host', false); + stream_context_set_option($this->_smtp_conn, 'ssl', 'verify_peer', false); + stream_context_set_option($this->_smtp_conn, 'ssl', 'allow_self_signed', true); stream_socket_enable_crypto($this->_smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); } -- GitLab From 3f9c6a3a929694715d756e023de4447de554e4c4 Mon Sep 17 00:00:00 2001 From: Webslice Date: Thu, 17 Jan 2019 20:16:53 +0100 Subject: [PATCH 288/310] Add support for powerdns 4.x, fixes #5223 --- .../plugins-available/powerdns_plugin.inc.php | 108 +++++++++++------- 1 file changed, 67 insertions(+), 41 deletions(-) diff --git a/server/plugins-available/powerdns_plugin.inc.php b/server/plugins-available/powerdns_plugin.inc.php index f5f5158c4..1ecdfaf50 100644 --- a/server/plugins-available/powerdns_plugin.inc.php +++ b/server/plugins-available/powerdns_plugin.inc.php @@ -7,14 +7,14 @@ 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. + * 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 @@ -97,7 +97,7 @@ class powerdns_plugin { /* - This function is called when the plugin is loaded + This function is called when the plugin is loaded */ function onLoad() { @@ -421,15 +421,23 @@ class powerdns_plugin { } } - function find_pdns_pdnssec() { + function find_pdns_pdnssec_or_pdnsutil() { $output = array(); $retval = ''; + + // The command is named pdnssec in PowerDNS 3 exec("type -p pdnssec", $output, $retval); if ($retval == 0 && is_file($output[0])){ return $output[0]; - } else { - return false; } + + // But in PowerNDS 4 they renamed it to pdnsutil + exec("type -p pdnsutil", $output, $retval); + if ($retval == 0 && is_file($output[0])){ + return $output[0]; + } + + return false; } function zoneRediscover() { @@ -466,6 +474,14 @@ class powerdns_plugin { } } + function is_pdns_version_supported() { + if (preg_match('/^[34]/',$this->get_pdns_version())) { + return true; + } + + return false; + } + function handle_dnssec($data) { // If origin changed, delete keys first if ($data['old']['origin'] != $data['new']['origin']) { @@ -475,14 +491,14 @@ class powerdns_plugin { } // If DNSSEC is disabled, but was enabled before, just disable DNSSEC but leave the keys in dns_info - if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_initialized'] === 'Y') { + if ($data['new']['dnssec_wanted'] === 'N' && $data['old']['dnssec_wanted'] === 'Y') { $this->soa_dnssec_disable($data); return; } // If DNSSEC is wanted, enable it - if ($data['new']['dnssec_wanted'] === 'Y') { + if ($data['new']['dnssec_wanted'] === 'Y' && $data['old']['dnssec_wanted'] === 'N') { $this->soa_dnssec_create($data); } } @@ -490,11 +506,11 @@ class powerdns_plugin { function soa_dnssec_create($data) { global $app; - if (!preg_match('/^3/',$this->get_pdns_version()) ) { + if (false === $this->is_pdns_version_supported()) { return; } - $pdns_pdnssec = $this->find_pdns_pdnssec(); + $pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil(); if ($pdns_pdnssec === false) { return; } @@ -504,9 +520,13 @@ class powerdns_plugin { // We don't log the actual commands here, because having commands in the dnssec_info field will trigger // the IDS if you try to save the record using the interface afterwards. - $cmd_secure_zone = sprintf('%s secure-zone %s 2>&1', $pdns_pdnssec, $zone); - $log[] = sprintf("\r\n%s %s", date('c'), 'Running secure-zone command...'); - exec($cmd_secure_zone, $log); + $cmd_add_zone_key_ksk = sprintf('%s add-zone-key %s ksk active 2048 rsasha256', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running add-zone-key ksk command...'); + exec($cmd_add_zone_key_ksk, $log); + + $cmd_add_zone_key_zsk = sprintf('%s add-zone-key %s zsk active 1024 rsasha256', $pdns_pdnssec, $zone); + $log[] = sprintf("\r\n%s %s", date('c'), 'Running add-zone-key zsk command...'); + exec($cmd_add_zone_key_zsk, $log); $cmd_set_nsec3 = sprintf('%s set-nsec3 %s "1 0 10 deadbeef" 2>&1', $pdns_pdnssec, $zone); $log[] = sprintf("\r\n%s %s", date('c'), 'Running set-nsec3 command...'); @@ -539,17 +559,19 @@ class powerdns_plugin { switch ($part = substr($line, 0, 3)) { case 'ID ': // Only process active keys - if (!strpos($line, 'Active: 1')) { - continue; + // 'Active: 1' is pdnssec (PowerDNS 3.x) output + // 'Active (' is pdnsutil (PowerDNS 4.x) output + if (!strpos($line, 'Active: 1') && !strpos($line, 'Active ( ')) { + break; } - // Determine key type (KSK or ZSK) - preg_match('/(KSK|ZSK)/', $line, $matches_key_type); + // Determine key type (KSK, ZSK or CSK) + preg_match('/(KSK|ZSK|CSK)/', $line, $matches_key_type); $key_type = $matches_key_type[1]; - // We only care about the KSK - if ('ZSK' === $key_type) { - continue; + // We only care about the KSK or CSK + if (!in_array($key_type, ['KSK', 'CSK'], true)) { + break; } // Determine key tag @@ -568,6 +590,7 @@ class powerdns_plugin { break; case 'KSK': + case 'CSK': // Determine DNSKEY preg_match('/ IN DNSKEY \d+ \d+ \d+ (.*) ;/', $line, $matches_dnskey); $formatted[] = sprintf('DNSKEY: %s', $matches_dnskey[1]); @@ -604,11 +627,11 @@ class powerdns_plugin { function soa_dnssec_disable($data) { global $app; - if (!preg_match('/^3/',$this->get_pdns_version()) ) { + if (false === $this->is_pdns_version_supported()) { return; } - $pdns_pdnssec = $this->find_pdns_pdnssec(); + $pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil(); if ($pdns_pdnssec === false) { return; } @@ -631,11 +654,11 @@ class powerdns_plugin { function soa_dnssec_delete($data) { global $app; - if (!preg_match('/^3/',$this->get_pdns_version()) ) { + if (false === $this->is_pdns_version_supported()) { return; } - $pdns_pdnssec = $this->find_pdns_pdnssec(); + $pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil(); if ($pdns_pdnssec === false) { return; } @@ -661,17 +684,20 @@ class powerdns_plugin { function rectifyZone($data) { global $app, $conf; - if ( preg_match('/^3/',$this->get_pdns_version()) ) { - $pdns_pdnssec = $this->find_pdns_pdnssec(); - if ( $pdns_pdnssec != false ) { - if (isset($data["new"]["origin"])) { - //* data has origin field only for SOA recordtypes - exec($pdns_pdnssec . ' rectify-zone ' . rtrim($data["new"]["origin"],".")); - } else { - // get origin from DB for all other recordtypes - $zn = $app->db->queryOneRecord("SELECT d.name AS name FROM powerdns.domains d, powerdns.records r WHERE r.ispconfig_id=? AND r.domain_id = d.id", $data["new"]["id"]); - exec($pdns_pdnssec . ' rectify-zone ' . trim($zn["name"])); - } + + if (false === $this->is_pdns_version_supported()) { + return; + } + + $pdns_pdnssec = $this->find_pdns_pdnssec_or_pdnsutil(); + if ( $pdns_pdnssec != false ) { + if (isset($data["new"]["origin"])) { + //* data has origin field only for SOA recordtypes + exec($pdns_pdnssec . ' rectify-zone ' . rtrim($data["new"]["origin"],".")); + } else { + // get origin from DB for all other recordtypes + $zn = $app->db->queryOneRecord("SELECT d.name AS name FROM powerdns.domains d, powerdns.records r WHERE r.ispconfig_id=? AND r.domain_id = d.id", $data["new"]["id"]); + exec($pdns_pdnssec . ' rectify-zone ' . trim($zn["name"])); } } } -- GitLab From cda177a2484843a20ff013728b856ee1f4e5008c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Sat, 19 Jan 2019 21:47:04 +0100 Subject: [PATCH 289/310] - fixed vhost settings for nginx - fixed rspamd settings - fixed errors in webserver plugin - fixed error in dkim domain handling --- install/tpl/nginx_ispconfig.vhost.master | 2 +- install/tpl/rspamd_users.conf.master | 6 +-- interface/web/mail/mail_domain_edit.php | 4 +- server/conf/nginx_vhost.conf.master | 2 +- .../lib/classes/plugin_webserver_base.inc.php | 2 +- .../classes/plugin_webserver_nginx.inc.php | 2 +- .../mail_plugin_dkim.inc.php | 2 + server/plugins-available/nginx_plugin.inc.php | 2 +- .../plugins-available/rspamd_plugin.inc.php | 41 ++++++++++++------- 9 files changed, 39 insertions(+), 24 deletions(-) diff --git a/install/tpl/nginx_ispconfig.vhost.master b/install/tpl/nginx_ispconfig.vhost.master index edd9471d3..cd9bb1852 100644 --- a/install/tpl/nginx_ispconfig.vhost.master +++ b/install/tpl/nginx_ispconfig.vhost.master @@ -2,7 +2,7 @@ server { listen {vhost_port}{ssl_on}; listen [::]:{vhost_port} ipv6only=on{ssl_on}; - {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + {ssl_comment}ssl_protocols TLSv1 TLSv1.1 TLSv1.2; {ssl_comment}ssl_certificate /usr/local/ispconfig/interface/ssl/ispserver.crt; {ssl_comment}ssl_certificate_key /usr/local/ispconfig/interface/ssl/ispserver.key; {ssl_comment}ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; diff --git a/install/tpl/rspamd_users.conf.master b/install/tpl/rspamd_users.conf.master index bf7ad2830..73d437d6c 100644 --- a/install/tpl/rspamd_users.conf.master +++ b/install/tpl/rspamd_users.conf.master @@ -4,10 +4,10 @@ settings { authenticated = yes; #apply "default" { groups_disabled = ["rbl", "spf"]; } apply "default" { - symbols_enabled = []; + #symbols_enabled = []; symbols_disabled = []; - groups_enabled = []; - groups_disabled = []; + #groups_enabled = []; + groups_disabled = ["rbl"]; } } whitelist { diff --git a/interface/web/mail/mail_domain_edit.php b/interface/web/mail/mail_domain_edit.php index 3b1a5794d..5839d0b5d 100644 --- a/interface/web/mail/mail_domain_edit.php +++ b/interface/web/mail/mail_domain_edit.php @@ -318,7 +318,7 @@ class page_action extends tform_actions { $soaDomain = $this->dataRecord['domain'].'.'; while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); - $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + $soaDomain = preg_replace("/^[^\.]+\./","",$soaDomain); } if ( isset($soa) && !empty($soa) ) $this->update_dns($this->dataRecord, $soa); } @@ -444,7 +444,7 @@ class page_action extends tform_actions { $soaDomain = $this->dataRecord['domain'].'.'; while ((!isset($soa) && (substr_count($soaDomain,'.') > 1))) { $soa = $app->db->queryOneRecord("SELECT id AS zone, sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, server_id, ttl, serial FROM dns_soa WHERE active = 'Y' AND origin = ?", $soaDomain); - $soaDomain = preg_replace("/^\w+\./","",$soaDomain); + $soaDomain = preg_replace("/^[^\.]+\./","",$soaDomain); } if ( ($selector || $dkim_private || $dkim_active) && $dkim_active ) diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master index c072d0ae3..bc09c4293 100644 --- a/server/conf/nginx_vhost.conf.master +++ b/server/conf/nginx_vhost.conf.master @@ -28,7 +28,7 @@ server {
listen : ssl{tmpl_if name='enable_http2' op='==' value='y'} http2{/tmpl_if}{tmpl_if name='enable_spdy' op='==' value='y'} spdy{/tmpl_if}; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # ssl_ciphers 'TLS-CHACHA20-POLY1305-SHA256:TLS-AES-256-GCM-SHA384:TLS-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; # ssl_prefer_server_ciphers on; diff --git a/server/lib/classes/plugin_webserver_base.inc.php b/server/lib/classes/plugin_webserver_base.inc.php index ea9ab8aa5..0ce6cc5d9 100644 --- a/server/lib/classes/plugin_webserver_base.inc.php +++ b/server/lib/classes/plugin_webserver_base.inc.php @@ -1719,7 +1719,7 @@ class plugin_webserver_base { $this->action = 'update'; $this->update_letsencrypt = true; // just run the update function - $this->update($event_name, $data); + $this->eventUpdate($event_name, $data, 'update', $server_type); } else { $conf_prefix = ''; diff --git a/server/lib/classes/plugin_webserver_nginx.inc.php b/server/lib/classes/plugin_webserver_nginx.inc.php index 3002f4b0f..377c05fd4 100644 --- a/server/lib/classes/plugin_webserver_nginx.inc.php +++ b/server/lib/classes/plugin_webserver_nginx.inc.php @@ -632,7 +632,7 @@ class plugin_webserver_nginx { if(count($server_alias) > 0) { $server_alias_str = ''; foreach($server_alias as $tmp_alias) { - $server_alias_str .= $tmp_alias; + $server_alias_str .= ' ' . $tmp_alias; } unset($tmp_alias); diff --git a/server/plugins-available/mail_plugin_dkim.inc.php b/server/plugins-available/mail_plugin_dkim.inc.php index 26de6ca4a..cf9d713b9 100755 --- a/server/plugins-available/mail_plugin_dkim.inc.php +++ b/server/plugins-available/mail_plugin_dkim.inc.php @@ -104,6 +104,8 @@ class mail_plugin_dkim { function check_system($data) { global $app, $mail_config; + /** TODO: FIX IF ONLY RSPAMD IS INSTALLED AND NO AMAVIS! **/ + $app->uses('getconf'); $check=true; diff --git a/server/plugins-available/nginx_plugin.inc.php b/server/plugins-available/nginx_plugin.inc.php index 3a7f569c2..614437852 100644 --- a/server/plugins-available/nginx_plugin.inc.php +++ b/server/plugins-available/nginx_plugin.inc.php @@ -98,7 +98,7 @@ class nginx_plugin { if($this->action != 'insert') $this->action = 'update'; - $app->plugins_webserver_base->eventUpdate($event_name, $data, 'nginx'); + $app->plugin_webserver_base->eventUpdate($event_name, $data, $this->action, 'nginx'); //* Unset action to clean it for next processed vhost. $this->action = ''; diff --git a/server/plugins-available/rspamd_plugin.inc.php b/server/plugins-available/rspamd_plugin.inc.php index 4b60b11ea..c9af1be00 100644 --- a/server/plugins-available/rspamd_plugin.inc.php +++ b/server/plugins-available/rspamd_plugin.inc.php @@ -88,7 +88,7 @@ class rspamd_plugin { $app->uses('getconf,system,functions'); $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - if($mail_config['content_filter'] == 'rspamd'){ + if(is_dir('/etc/rspamd')) { $policy = $app->db->queryOneRecord("SELECT * FROM spamfilter_policy WHERE id = ?", intval($data['new']['policy_id'])); //* Create the config file @@ -129,10 +129,14 @@ class rspamd_plugin { $app->system->file_put_contents($user_file, $tpl->grab()); } else { - if(is_file($user_file)) unlink($user_file); + if(is_file($user_file)) { + unlink($user_file); + } + } + + if($mail_config['content_filter'] == 'rspamd'){ + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); } - //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); - if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); } } @@ -143,11 +147,14 @@ class rspamd_plugin { $app->uses('getconf'); $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - if($mail_config['content_filter'] == 'rspamd'){ + if(is_dir('/etc/rspamd')) { //* delete the config file $user_file = $this->users_config_dir.'spamfilter_user_'.intval($data['old']['id']).'.conf'; if(is_file($user_file)) unlink($user_file); - //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); + + } + + if($mail_config['content_filter'] == 'rspamd') { if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); } } @@ -166,7 +173,7 @@ class rspamd_plugin { $app->uses('getconf,system,functions'); $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - if($mail_config['content_filter'] == 'rspamd'){ + if(is_dir('/etc/rspamd')) { $recipient = $app->db->queryOneRecord("SELECT email FROM spamfilter_users WHERE id = ?", intval($data['new']['rid'])); //* Create the config file $wblist_file = $this->users_config_dir.'spamfilter_wblist_'.intval($data['new']['wblist_id']).'.conf'; @@ -191,8 +198,10 @@ class rspamd_plugin { } else { if(is_file($wblist_file)) unlink($wblist_file); } - //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); - if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + + if($mail_config['content_filter'] == 'rspamd'){ + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } } } @@ -202,12 +211,14 @@ class rspamd_plugin { $app->uses('getconf'); $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - if($mail_config['content_filter'] == 'rspamd'){ + if(is_dir('/etc/rspamd')) { //* delete the config file $wblist_file = $this->users_config_dir.'spamfilter_wblist_'.intval($data['old']['wblist_id']).'.conf'; if(is_file($wblist_file)) unlink($wblist_file); - //if(is_file('/etc/init.d/rspamd')) exec('/etc/init.d/rspamd reload &> /dev/null'); - if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + + if($mail_config['content_filter'] == 'rspamd'){ + if(is_file('/etc/init.d/rspamd')) $app->services->restartServiceDelayed('rspamd', 'reload'); + } } } @@ -220,7 +231,7 @@ class rspamd_plugin { $mail_config = $app->getconf->get_server_config($conf['server_id'], 'mail'); - if($mail_config['content_filter'] == 'rspamd'){ + if(is_dir('/etc/rspamd')) { $tpl = new tpl(); $tpl->newTemplate('rspamd_users.conf.master'); @@ -234,7 +245,9 @@ class rspamd_plugin { $tpl->setLoop('whitelist_ips', $whitelist_ips); $app->system->file_put_contents('/etc/rspamd/local.d/users.conf', $tpl->grab()); - $app->services->restartServiceDelayed('rspamd', 'reload'); + if($mail_config['content_filter'] == 'rspamd'){ + $app->services->restartServiceDelayed('rspamd', 'reload'); + } } } -- GitLab From 178b34ebb15f33c7327623d249ee0368e3daa391 Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 25 Jan 2019 09:44:15 +0100 Subject: [PATCH 290/310] - fixed some rspamd values, removed commented code --- install/install.php | 14 -- install/lib/classes/tpl.inc.php | 141 ------------------ install/tpl/rspamd_neural.conf.master | 4 +- install/tpl/rspamd_neural_group.conf.master | 6 +- .../web/admin/form/system_config.tform.php | 24 --- .../mail_plugin_dkim.inc.php | 1 + 6 files changed, 6 insertions(+), 184 deletions(-) diff --git a/install/install.php b/install/install.php index f99a99d9e..5c821cadf 100644 --- a/install/install.php +++ b/install/install.php @@ -509,20 +509,6 @@ $install_ispconfig_interface_default = ($conf['mysql']['master_slave_setup'] == if($install_mode == 'standard' || strtolower($inst->simple_query('Install ISPConfig Web Interface', array('y', 'n'), $install_ispconfig_interface_default,'install_ispconfig_web_interface')) == 'y') { swriteln('Installing ISPConfig'); - //** We want to check if the server is a module or cgi based php enabled server - //** TODO: Don't always ask for this somehow ? - /* - $fast_cgi = $inst->simple_query('CGI PHP Enabled Server?', array('yes','no'),'no'); - - if($fast_cgi == 'yes') { - $alias = $inst->free_query('Script Alias', '/php/'); - $path = $inst->free_query('Script Alias Path', '/path/to/cgi/bin'); - $conf['apache']['vhost_cgi_alias'] = sprintf('ScriptAlias %s %s', $alias, $path); - } else { - $conf['apache']['vhost_cgi_alias'] = ""; - } - */ - //** Customise the port ISPConfig runs on $ispconfig_vhost_port = $inst->free_query('ISPConfig Port', '8080','ispconfig_port'); $temp_admin_password = str_shuffle(bin2hex(openssl_random_pseudo_bytes(4))); diff --git a/install/lib/classes/tpl.inc.php b/install/lib/classes/tpl.inc.php index 73ff19230..5bd8ded1f 100644 --- a/install/lib/classes/tpl.inc.php +++ b/install/lib/classes/tpl.inc.php @@ -357,147 +357,6 @@ if (!defined('vlibTemplateClassLoaded')) { return true; } - /** - * [** EXPERIMENTAL **] - * Function to create a loop from a Db result resource link. - * @param string $loopname to commit loop. If not set, will use last loopname set using newLoop() - * @param string $result link to a Db result resource - * @param string $db_type, type of db that the result resource belongs to. - * @return boolean true/false - * @access public - */ - public function setDbLoop($loopname, $result, $db_type = 'MYSQL') - { - /* - $db_type = strtoupper($db_type); - if (!in_array($db_type, $this->allowed_loop_dbs)) { - vlibTemplateError::raiseError('VT_WARNING_INVALID_LOOP_DB', WARNING, $db_type); - return false; - } - - $loop_arr = array(); - // TODO: Are all these necessary as were onyl using mysql and possible postgres ? - pedro - switch ($db_type) { - - case 'MYSQL': - if (get_resource_type($result) != 'mysql result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = mysql_fetch_assoc($result)) { - $loop_arr[] = $r; - } - break; - - case 'POSTGRESQL': - if (get_resource_type($result) != 'pgsql result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - - $nr = (function_exists('pg_num_rows')) ? pg_num_rows($result) : pg_numrows($result); - - for ($i=0; $i < $nr; $i++) { - $loop_arr[] = pg_fetch_array($result, $i, PGSQL_ASSOC); - } - break; - - case 'INFORMIX': - if (!$result) { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = ifx_fetch_row($result, 'NEXT')) { - $loop_arr[] = $r; - } - break; - - case 'INTERBASE': - if (get_resource_type($result) != 'interbase result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = ibase_fetch_row($result)) { - $loop_arr[] = $r; - } - break; - - case 'INGRES': - if (!$result) { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = ingres_fetch_array(INGRES_ASSOC, $result)) { - $loop_arr[] = $r; - } - break; - - case 'MSSQL': - if (get_resource_type($result) != 'mssql result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = mssql_fetch_array($result)) { - $loop_arr[] = $r; - } - break; - - case 'MSQL': - if (get_resource_type($result) != 'msql result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while($r = msql_fetch_array($result, MSQL_ASSOC)) { - $loop_arr[] = $r; - } - break; - - case 'OCI8': - if (get_resource_type($result) != 'oci8 statement') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while(OCIFetchInto($result, &$r, OCI_ASSOC+OCI_RETURN_LOBS)) { - $loop_arr[] = $r; - } - break; - - case 'ORACLE': - if (get_resource_type($result) != 'oracle Cursor') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while(ora_fetch_into($result, &$r, ORA_FETCHINTO_ASSOC)) { - $loop_arr[] = $r; - } - break; - - case 'OVRIMOS': - if (!$result) { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - while(ovrimos_fetch_into($result, &$r, 'NEXT')) { - $loop_arr[] = $r; - } - break; - - case 'SYBASE': - if (get_resource_type($result) != 'sybase-db result') { - vlibTemplateError::raiseError('VT_WARNING_INVALID_RESOURCE', WARNING, $db_type); - return false; - } - - while($r = sybase_fetch_array($result)) { - $loop_arr[] = $r; - } - break; - } - $this->setLoop($loopname, $loop_arr); - return true; - */ - } - /** * Sets the name for the curent loop in the 3 step loop process. * @param string $name string to define loop name diff --git a/install/tpl/rspamd_neural.conf.master b/install/tpl/rspamd_neural.conf.master index 64b0fa871..76f8a6d34 100644 --- a/install/tpl/rspamd_neural.conf.master +++ b/install/tpl/rspamd_neural.conf.master @@ -8,7 +8,7 @@ rules { max_usages = 200; max_iterations = 25; learning_rate = 0.01, - spam_score = 8; + spam_score = 10; ham_score = -2; } symbol_spam = "NEURAL_SPAM_LONG"; @@ -21,7 +21,7 @@ rules { max_usages = 2; max_iterations = 25; learning_rate = 0.01, - spam_score = 8; + spam_score = 10; ham_score = -2; } symbol_spam = "NEURAL_SPAM_SHORT"; diff --git a/install/tpl/rspamd_neural_group.conf.master b/install/tpl/rspamd_neural_group.conf.master index c4f59c52e..5aabdefaf 100644 --- a/install/tpl/rspamd_neural_group.conf.master +++ b/install/tpl/rspamd_neural_group.conf.master @@ -1,14 +1,14 @@ symbols = { "NEURAL_SPAM_LONG" { - weight = 3.0; # sample weight + weight = 1.0; # sample weight description = "Neural network spam (long)"; } "NEURAL_HAM_LONG" { - weight = -3.0; # sample weight + weight = -2.0; # sample weight description = "Neural network ham (long)"; } "NEURAL_SPAM_SHORT" { - weight = 2.0; # sample weight + weight = 0.5; # sample weight description = "Neural network spam (short)"; } "NEURAL_HAM_SHORT" { diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php index 31a9b6bcc..4762e0028 100644 --- a/interface/web/admin/form/system_config.tform.php +++ b/interface/web/admin/form/system_config.tform.php @@ -452,30 +452,6 @@ $form["tabs"]['domains'] = array ( ) ); -/* TODO_ BEGIN: Branding - -$form["tabs"]['domains'] = array ( - 'title' => "Branding", - 'width' => 70, - 'template' => "templates/system_config_branding_edit.htm", - 'fields' => array ( - ################################## - # Begin Datatable fields - ################################## - 'allow_themechange' => array ( - 'datatype' => 'VARCHAR', - 'formtype' => 'CHECKBOX', - 'default' => 'N', - 'value' => array(0 => 'n',1 => 'y') - ), - ################################## - # ENDE Datatable fields - ################################## - ) -); - - - END: Branding */ $form["tabs"]['misc'] = array ( 'title' => "Misc", 'width' => 70, diff --git a/server/plugins-available/mail_plugin_dkim.inc.php b/server/plugins-available/mail_plugin_dkim.inc.php index cf9d713b9..699fac3ea 100755 --- a/server/plugins-available/mail_plugin_dkim.inc.php +++ b/server/plugins-available/mail_plugin_dkim.inc.php @@ -105,6 +105,7 @@ class mail_plugin_dkim { global $app, $mail_config; /** TODO: FIX IF ONLY RSPAMD IS INSTALLED AND NO AMAVIS! **/ + /** TODO: FIX DKIM FOR RSPAMD, RSPAMD CANNOT READ FILES OF amavis:root **/ $app->uses('getconf'); $check=true; -- GitLab From 04d8e6f6e9290755522d915213bd9d6e52b90b6d Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Fri, 25 Jan 2019 10:11:49 +0100 Subject: [PATCH 291/310] - fixed update serial on delete RR via remoting - reduced duplicate code in dns remoting function --- interface/lib/classes/remote.d/dns.inc.php | 573 ++++++--------------- 1 file changed, 155 insertions(+), 418 deletions(-) diff --git a/interface/lib/classes/remote.d/dns.inc.php b/interface/lib/classes/remote.d/dns.inc.php index faae06dc2..e640145c6 100644 --- a/interface/lib/classes/remote.d/dns.inc.php +++ b/interface/lib/classes/remote.d/dns.inc.php @@ -42,8 +42,7 @@ class remoting_dns extends remoting { // DNS Function -------------------------------------------------------------------------------------------------- //* Create Zone with Template - public function dns_templatezone_add($session_id, $client_id, $template_id, $domain, $ip, $ns1, $ns2, $email) - { + public function dns_templatezone_add($session_id, $client_id, $template_id, $domain, $ip, $ns1, $ns2, $email) { global $app, $conf; if(!$this->checkPerm($session_id, 'dns_templatezone_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); @@ -184,8 +183,7 @@ class remoting_dns extends remoting { //* Get record details - public function dns_zone_get($session_id, $primary_id) - { + public function dns_zone_get($session_id, $primary_id) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get')) { @@ -198,8 +196,7 @@ class remoting_dns extends remoting { } //* Get slave zone details - public function dns_slave_get($session_id, $primary_id) - { + public function dns_slave_get($session_id, $primary_id) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get')) { @@ -213,8 +210,7 @@ class remoting_dns extends remoting { //* Add a slave zone - public function dns_slave_add($session_id, $client_id, $params) - { + public function dns_slave_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -223,8 +219,7 @@ class remoting_dns extends remoting { } //* Update a slave zone - public function dns_slave_update($session_id, $client_id, $primary_id, $params) - { + public function dns_slave_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_update')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -234,8 +229,7 @@ class remoting_dns extends remoting { } //* Delete a slave zone - public function dns_slave_delete($session_id, $primary_id) - { + public function dns_slave_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'dns_zone_delete')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -244,8 +238,7 @@ class remoting_dns extends remoting { } //* Get record id by origin - public function dns_zone_get_id($session_id, $origin) - { + public function dns_zone_get_id($session_id, $origin) { global $app; if(!$this->checkPerm($session_id, 'dns_zone_get_id')) { @@ -268,8 +261,7 @@ class remoting_dns extends remoting { } //* Add a record - public function dns_zone_add($session_id, $client_id, $params) - { + public function dns_zone_add($session_id, $client_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -278,8 +270,7 @@ class remoting_dns extends remoting { } //* Update a record - public function dns_zone_update($session_id, $client_id, $primary_id, $params) - { + public function dns_zone_update($session_id, $client_id, $primary_id, $params) { if(!$this->checkPerm($session_id, 'dns_zone_update')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -289,8 +280,7 @@ class remoting_dns extends remoting { } //* Delete a record - public function dns_zone_delete($session_id, $primary_id) - { + public function dns_zone_delete($session_id, $primary_id) { if(!$this->checkPerm($session_id, 'dns_zone_delete')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; @@ -301,563 +291,312 @@ class remoting_dns extends remoting { // ---------------------------------------------------------------------------------------------------------------- - //* Get record details - public function dns_aaaa_get($session_id, $primary_id) - { + private function dns_rr_get($session_id, $primary_id, $rr_type = 'A') { global $app; - - if(!$this->checkPerm($session_id, 'dns_aaaa_get')) { + + $rr_type = strtolower($rr_type); + if(!preg_match('/^[a-z]+$/', $rr_type)) { + throw new SoapFault('permission denied', 'Invalid rr type'); + } + + if(!$this->checkPerm($session_id, 'dns_' . $rr_type . '_get')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_aaaa.tform.php'); + $app->remoting_lib->loadFormDef('../dns/form/dns_' . $rr_type . '.tform.php'); return $app->remoting_lib->getDataRecord($primary_id); } - + //* Add a record - public function dns_aaaa_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_aaaa_add')) { + private function dns_rr_add($session_id, $client_id, $params, $update_serial=false, $rr_type = 'A') { + $rr_type = strtolower($rr_type); + if(!preg_match('/^[a-z]+$/', $rr_type)) { + throw new SoapFault('permission denied', 'Invalid rr type'); + } + + if(!$this->checkPerm($session_id, 'dns_' . $rr_type . '_add')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_aaaa.tform.php', $client_id, $params); + if($update_serial) { + $this->increase_serial($session_id, $client_id, $params); + } + return $this->insertQuery('../dns/form/dns_' . $rr_type . '.tform.php', $client_id, $params); } //* Update a record - public function dns_aaaa_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_aaaa_update')) { + private function dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial=false, $rr_type = 'A') { + $rr_type = strtolower($rr_type); + if(!preg_match('/^[a-z]+$/', $rr_type)) { + throw new SoapFault('permission denied', 'Invalid rr type'); + } + + if(!$this->checkPerm($session_id, 'dns_' . $rr_type . '_update')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); return false; } - $affected_rows = $this->updateQuery('../dns/form/dns_aaaa.tform.php', $client_id, $primary_id, $params); - if($update_serial) $this->increase_serial($session_id, $client_id, $params); + $affected_rows = $this->updateQuery('../dns/form/dns_' . $rr_type . '.tform.php', $client_id, $primary_id, $params); + if($update_serial) { + $this->increase_serial($session_id, $client_id, $params); + } return $affected_rows; } - + //* Delete a record - public function dns_aaaa_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_aaaa_delete')) { + private function dns_rr_delete($session_id, $primary_id, $update_serial=false, $rr_type = 'A') { + $rr_type = strtolower($rr_type); + if(!preg_match('/^[a-z]+$/', $rr_type)) { + throw new SoapFault('permission denied', 'Invalid rr type'); + } + if(!$this->checkPerm($session_id, 'dns_' . $rr_type . '_delete')) { throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; } - $affected_rows = $this->deleteQuery('../dns/form/dns_aaaa.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); + if($update_serial) { + $this->increase_serial($session_id, 0, array('dns_rr_id' => $primary_id)); + } + $affected_rows = $this->deleteQuery('../dns/form/dns_' . $rr_type . '.tform.php', $primary_id); return $affected_rows; } + + // ---------------------------------------------------------------------------------------------------------------- + + //* Get record details + public function dns_aaaa_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'AAAA'); + } + + //* Add a record + public function dns_aaaa_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'AAAA'); + } + + //* Update a record + public function dns_aaaa_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'AAAA'); + } + + //* Delete a record + public function dns_aaaa_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'AAAA'); + } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_a_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_a_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_a.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_a_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'A'); } //* Add a record - public function dns_a_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_a_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_a.tform.php', $client_id, $params); + public function dns_a_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'A'); } //* Update a record - public function dns_a_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_a_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_a.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_a_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'A'); } //* Delete a record - public function dns_a_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_a_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_a.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_a_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'A'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_alias_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_alias_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_alias.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_alias_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'ALIAS'); } //* Add a record - public function dns_alias_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_alias_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_alias.tform.php', $client_id, $params); + public function dns_alias_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'ALIAS'); } //* Update a record - public function dns_alias_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_alias_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_alias.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_alias_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'ALIAS'); } //* Delete a record - public function dns_alias_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_alias_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_alias.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_alias_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'ALIAS'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_cname_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_cname_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_cname.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_cname_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'CNAME'); } //* Add a record - public function dns_cname_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_cname_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_cname.tform.php', $client_id, $params); + public function dns_cname_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'CNAME'); } //* Update a record - public function dns_cname_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_cname_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_cname.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_cname_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'CNAME'); } //* Delete a record - public function dns_cname_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_cname_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_cname.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_cname_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'CNAME'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_hinfo_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_hinfo_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_hinfo.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_hinfo_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'HINFO'); } //* Add a record - public function dns_hinfo_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_hinfo_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_hinfo.tform.php', $client_id, $params); + public function dns_hinfo_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'HINFO'); } //* Update a record - public function dns_hinfo_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_hinfo_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_hinfo.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_hinfo_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'HINFO'); } //* Delete a record - public function dns_hinfo_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_hinfo_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_hinfo.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_hinfo_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'HINFO'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_mx_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_mx_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_mx.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_mx_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'MX'); } //* Add a record - public function dns_mx_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_mx_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_mx.tform.php', $client_id, $params); + public function dns_mx_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'MX'); } //* Update a record - public function dns_mx_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_mx_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_mx.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_mx_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'MX'); } //* Delete a record - public function dns_mx_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_mx_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_mx.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_mx_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'MX'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_ns_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_ns_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_ns.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_ns_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'NS'); } //* Add a record - public function dns_ns_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ns_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_ns.tform.php', $client_id, $params); + public function dns_ns_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'NS'); } //* Update a record - public function dns_ns_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ns_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_ns.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_ns_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'NS'); } //* Delete a record - public function dns_ns_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ns_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_ns.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_ns_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'NS'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_ptr_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_ptr_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_ptr.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_ptr_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'PTR'); } //* Add a record - public function dns_ptr_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ptr_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_ptr.tform.php', $client_id, $params); + public function dns_ptr_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'PTR'); } //* Update a record - public function dns_ptr_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ptr_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_ptr.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_ptr_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'PTR'); } //* Delete a record - public function dns_ptr_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_ptr_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_ptr.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_ptr_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'PTR'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_rp_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_rp_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_rp.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_rp_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'RP'); } //* Add a record - public function dns_rp_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_rp_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_rp.tform.php', $client_id, $params); + public function dns_rp_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'RP'); } //* Update a record - public function dns_rp_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_rp_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_rp.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_rp_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'RP'); } //* Delete a record - public function dns_rp_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_rp_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_rp.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_rp_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'RP'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_srv_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_srv_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_srv.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_srv_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'SRV'); } //* Add a record - public function dns_srv_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_srv_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_srv.tform.php', $client_id, $params); + public function dns_srv_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'SRV'); } //* Update a record - public function dns_srv_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_srv_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_srv.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_srv_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'SRV'); } //* Delete a record - public function dns_srv_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_srv_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_srv.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_srv_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'SRV'); } // ---------------------------------------------------------------------------------------------------------------- //* Get record details - public function dns_txt_get($session_id, $primary_id) - { - global $app; - - if(!$this->checkPerm($session_id, 'dns_txt_get')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $app->uses('remoting_lib'); - $app->remoting_lib->loadFormDef('../dns/form/dns_txt.tform.php'); - return $app->remoting_lib->getDataRecord($primary_id); + public function dns_txt_get($session_id, $primary_id) { + return $this->dns_rr_get($session_id, $primary_id, 'TXT'); } //* Add a record - public function dns_txt_add($session_id, $client_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_txt_add')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - return $this->insertQuery('../dns/form/dns_txt.tform.php', $client_id, $params); + public function dns_txt_add($session_id, $client_id, $params, $update_serial=false) { + return $this->dns_rr_add($session_id, $client_id, $params, $update_serial, 'TXT'); } //* Update a record - public function dns_txt_update($session_id, $client_id, $primary_id, $params, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_txt_update')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - if($update_serial) $this->increase_serial($session_id, $client_id, $params); - $affected_rows = $this->updateQuery('../dns/form/dns_txt.tform.php', $client_id, $primary_id, $params); - return $affected_rows; + public function dns_txt_update($session_id, $client_id, $primary_id, $params, $update_serial=false) { + return $this->dns_rr_update($session_id, $client_id, $primary_id, $params, $update_serial, 'TXT'); } //* Delete a record - public function dns_txt_delete($session_id, $primary_id, $update_serial=false) - { - if(!$this->checkPerm($session_id, 'dns_txt_delete')) { - throw new SoapFault('permission_denied', 'You do not have the permissions to access this function.'); - return false; - } - $affected_rows = $this->deleteQuery('../dns/form/dns_txt.tform.php', $primary_id); - if($update_serial) $this->increase_serial($session_id, $client_id, array('dns_rr_id' => $primary_id)); - return $affected_rows; + public function dns_txt_delete($session_id, $primary_id, $update_serial=false) { + return $this->dns_rr_delete($session_id, $primary_id, $update_serial, 'TXT'); } /** @@ -957,5 +696,3 @@ class remoting_dns extends remoting { $this->dns_zone_update($session_id, $client_id, $soa['id'], $soa); } } - -?> -- GitLab From 6d8d61688418cb13b4438c6198594f5c80f0be04 Mon Sep 17 00:00:00 2001 From: Herman van Rink Date: Sat, 26 Jan 2019 21:52:36 +0100 Subject: [PATCH 292/310] Create a util function to remove duplication --- interface/lib/classes/auth.inc.php | 30 +++++++++++++++++++ .../lib/classes/validate_password.inc.php | 6 ++-- interface/web/login/password_reset.php | 3 +- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/interface/lib/classes/auth.inc.php b/interface/lib/classes/auth.inc.php index 6658c4c11..0c891fc31 100644 --- a/interface/lib/classes/auth.inc.php +++ b/interface/lib/classes/auth.inc.php @@ -188,6 +188,36 @@ class auth { } + /** + * Get the minimum password length. + */ + public function get_min_password_length() { + global $app; + $server_config_array = $app->getconf->get_global_config(); + $min_password_length = 8; + if(isset($server_config_array['misc']['min_password_length'])) $min_password_length = $server_config_array['misc']['min_password_length']; + return $min_password_length; + } + + /** + * Get the minimum password strength. + */ + public function get_min_password_strength() { + global $app; + $server_config_array = $app->getconf->get_global_config(); + $min_password_strength = 0; + if(isset($server_config_array['misc']['min_password_strength'])) $min_password_strength = $server_config_array['misc']['min_password_strength'];; + return $min_password_strength; + } + + /** + * Generate a ranmdom password. + * + * @param int $minLength + * Minimum number of characters. + * @param boolean $special + * Include special characters, like # and ! + */ public function get_random_password($minLength = 8, $special = false) { if($minLength < 8) $minLength = 8; $maxLength = $minLength + 5; diff --git a/interface/lib/classes/validate_password.inc.php b/interface/lib/classes/validate_password.inc.php index a0f6de2e9..fc7b96984 100644 --- a/interface/lib/classes/validate_password.inc.php +++ b/interface/lib/classes/validate_password.inc.php @@ -111,10 +111,8 @@ class validate_password { $app->uses('ini_parser,getconf'); $server_config_array = $app->getconf->get_global_config(); - $min_password_strength = 0; - $min_password_length = 5; - if(isset($server_config_array['misc']['min_password_length'])) $min_password_length = $server_config_array['misc']['min_password_length']; - if(isset($server_config_array['misc']['min_password_strength'])) $min_password_strength = $server_config_array['misc']['min_password_strength']; + $min_password_length = $app->auth->get_min_password_length(); + $min_password_strength = $app->auth->get_min_password_strength(); if($min_password_strength > 0) { $lng_text = $app->lng('weak_password_txt'); diff --git a/interface/web/login/password_reset.php b/interface/web/login/password_reset.php index 02c71f294..d0bf9a7c3 100644 --- a/interface/web/login/password_reset.php +++ b/interface/web/login/password_reset.php @@ -123,8 +123,7 @@ if(isset($_POST['username']) && $_POST['username'] != '' && $_POST['email'] != ' } elseif ($continue) { if($client['client_id'] > 0) { $server_config_array = $app->getconf->get_global_config(); - $min_password_length = 8; - if(isset($server_config_array['misc']['min_password_length'])) $min_password_length = $server_config_array['misc']['min_password_length']; + $min_password_length = $app->auth->get_min_password_length(); $new_password = $app->auth->get_random_password($min_password_length, true); $new_password_encrypted = $app->auth->crypt_password($new_password); -- GitLab From 396f20a14ced6212337a396d5621576788e2862c Mon Sep 17 00:00:00 2001 From: Pete Date: Tue, 29 Jan 2019 23:57:52 +0100 Subject: [PATCH 293/310] Update wp-auth.conf to include some commonly attacked WordPress URLs --- docs/hardening/anti-bruteforce/wp-auth.conf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/hardening/anti-bruteforce/wp-auth.conf b/docs/hardening/anti-bruteforce/wp-auth.conf index 2acad450c..1fc420c87 100644 --- a/docs/hardening/anti-bruteforce/wp-auth.conf +++ b/docs/hardening/anti-bruteforce/wp-auth.conf @@ -2,4 +2,9 @@ # This goes into /etc/fail2ban/filter.d/wp-auth.conf # [Definition] - failregex = ^ .* "POST /wp-login.php \ No newline at end of file +failregex = ^ .* "POST /wp-login.php + ^ .* "POST /wordpress/wp-login.php + ^ .* "POST /wp/wp-login.php + ^ .* "GET /login_page.php +#ignoreregex = + \ No newline at end of file -- GitLab From ba5071311032960e3312179cab1be89b2f1d6455 Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Tue, 26 Feb 2019 07:53:56 +0100 Subject: [PATCH 294/310] update caa --- .../plugin_system_config_dns_ca.inc.php | 27 +++++++++---------- .../plugin_system_config_dns_ca_list.inc.php | 2 +- .../system_config_dns_ca_plugin.inc.php | 2 +- interface/web/dns/ajax_get_json.php | 2 +- server/conf/bind_pri.domain.master | 1 + 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/interface/lib/classes/plugin_system_config_dns_ca.inc.php b/interface/lib/classes/plugin_system_config_dns_ca.inc.php index 6144a7349..d9a994965 100644 --- a/interface/lib/classes/plugin_system_config_dns_ca.inc.php +++ b/interface/lib/classes/plugin_system_config_dns_ca.inc.php @@ -43,11 +43,11 @@ class plugin_system_config_dns_ca extends plugin_base { $pluginTpl = new tpl; $pluginTpl->newTemplate('templates/system_config_dns_ca_edit.htm'); - include 'lib/lang/'.$_SESSION['s']['language'].'_system_config.lng'; + include 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_system_config.lng'; $pluginTpl->setVar($wb); - if(isset($_GET['action']) && ($_GET['action'] == 'edit') && $_GET['id'] > 0) { + $ca_id = $app->functions->intval($_GET['id']); + if(isset($_GET['action']) && ($_GET['action'] == 'edit') && $ca_id > 0) { $pluginTpl->setVar('edit_record', 1); - $ca_id = intval($_GET['id']); $rec = $app->db->queryOneRecord("SELECT * FROM dns_ssl_ca WHERE id = ?", $ca_id); $pluginTpl->setVar('id', $rec['id']); $pluginTpl->setVar('ca_name', $rec['ca_name']); @@ -56,16 +56,15 @@ class plugin_system_config_dns_ca extends plugin_base { $pluginTpl->setVar('ca_critical', $rec['ca_critical']); $pluginTpl->setVar('ca_iodef', $rec['ca_iodef']); $pluginTpl->setVar('active', $rec['active']); - } elseif(isset($_GET['action']) && ($_GET['action'] == 'save') && $_GET['id'] > 0) { + } elseif(isset($_GET['action']) && ($_GET['action'] == 'save') && $ca_id > 0) { $pluginTpl->setVar('edit_record', 0); - $ca_id = intval($_GET['id']); $pluginTpl->setVar('id', $ca_id); - $pluginTpl->setVar('ca_name', $_POST['ca_name']); - $pluginTpl->setVar('ca_issue', $_POST['ca_issue']); - $pluginTpl->setVar('ca_wildcard', $_POST['ca_wildcard']); - $pluginTpl->setVar('ca_critical', $_POST['ca_critical']); - $pluginTpl->setVar('ca_iodef', $_POST['ca_iodef']); - $pluginTpl->setVar('active', $_POST['active']); + $pluginTpl->setVar('ca_name', $app->functions->htmlentities($_POST['ca_name'])); + $pluginTpl->setVar('ca_issue', $app->functions->htmlentities($_POST['ca_issue'])); + $pluginTpl->setVar('ca_wildcard', $app->functions->htmlentities($_POST['ca_wildcard'])); + $pluginTpl->setVar('ca_critical', $app->functions->htmlentities($_POST['ca_critical'])); + $pluginTpl->setVar('ca_iodef', $app->functions->htmlentities($_POST['ca_iodef'])); + $pluginTpl->setVar('active', $app->functions->htmlentities($_POST['active'])); } else { $pluginTpl->setVar('edit_record', 0); } @@ -77,10 +76,10 @@ class plugin_system_config_dns_ca extends plugin_base { function onUpdate() { global $app; - $id = intval($_GET['id']); + $ca_id = $app->functions->intval($_GET['id']); if(isset($_GET['action']) && $_GET['action'] == 'save') { - if($id > 0) { - $app->db->query("UPDATE dns_ssl_ca SET ca_name = ?, ca_issue = ?, ca_wildcard = ?, ca_iodef = ?, active = ? WHERE id = ?", $_POST['ca_name'], $_POST['ca_issue'], $_POST['ca_wildcard'], $_POST['ca_iodef'], $_POST['active'], $_GET['id']); + if($ca_id > 0) { + $app->db->query("UPDATE dns_ssl_ca SET ca_name = ?, ca_issue = ?, ca_wildcard = ?, ca_iodef = ?, active = ? WHERE id = ?", $_POST['ca_name'], $_POST['ca_issue'], $_POST['ca_wildcard'], $_POST['ca_iodef'], $_POST['active'], $ca_id); } else { $app->db->query("INSERT INTO (sys_userid, sys_groupid, sys_perm_user, sys_perm_group, sys_perm_other, ca_name, ca_issue, ca_wildcard, ca_iodef, active) VALUES(1, 1, 'riud', 'riud', '', ?, ?, ?, ?, ?", $_POST['ca_name'], $_POST['ca_issue'], $_POST['ca_wildcard'], $_POST['ca_iodef'], $_POST['active']); } diff --git a/interface/lib/classes/plugin_system_config_dns_ca_list.inc.php b/interface/lib/classes/plugin_system_config_dns_ca_list.inc.php index eb5882bd3..6b82c0604 100644 --- a/interface/lib/classes/plugin_system_config_dns_ca_list.inc.php +++ b/interface/lib/classes/plugin_system_config_dns_ca_list.inc.php @@ -44,7 +44,7 @@ class plugin_system_config_dns_ca_list extends plugin_base { $listTpl->newTemplate('templates/system_config_dns_ca_list.htm'); //* Loading language file - $lng_file = 'lib/lang/'.$_SESSION['s']['language'].'_system_config.lng'; + $lng_file = 'lib/lang/'.$app->functions->check_language($_SESSION['s']['language']).'_system_config.lng'; include $lng_file; $listTpl->setVar($wb); if($_SESSION['s']['user']['typ'] == 'admin') { diff --git a/interface/lib/plugins/system_config_dns_ca_plugin.inc.php b/interface/lib/plugins/system_config_dns_ca_plugin.inc.php index 5ab338640..c35934e5b 100644 --- a/interface/lib/plugins/system_config_dns_ca_plugin.inc.php +++ b/interface/lib/plugins/system_config_dns_ca_plugin.inc.php @@ -62,7 +62,7 @@ class system_config_dns_ca_plugin { } } } - } //* End function + } function web_vhost_domain_edit($event_name, $page_form) { global $app; diff --git a/interface/web/dns/ajax_get_json.php b/interface/web/dns/ajax_get_json.php index b2c381f3e..1dd9c518f 100644 --- a/interface/web/dns/ajax_get_json.php +++ b/interface/web/dns/ajax_get_json.php @@ -35,7 +35,7 @@ require_once '../../lib/app.inc.php'; $app->auth->check_module_permissions('dns'); $type = $_GET["type"]; -$ca_id = $_GET['ca_id']; +$ca_id = $app->functions->intval($_GET['ca_id']); if($type == 'get_ipv4'){ $result = array(); diff --git a/server/conf/bind_pri.domain.master b/server/conf/bind_pri.domain.master index 897ece496..fb867901d 100644 --- a/server/conf/bind_pri.domain.master +++ b/server/conf/bind_pri.domain.master @@ -61,3 +61,4 @@ $TTL {tmpl_var name='ttl'} + -- GitLab From 42e7c3876d7da2ad6efca0e4f7da79be9806a226 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Tue, 26 Feb 2019 11:40:35 +0100 Subject: [PATCH 295/310] fixes #5254 --- server/lib/classes/cronjob.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/classes/cronjob.inc.php b/server/lib/classes/cronjob.inc.php index 23b3c766e..9fba5af3c 100644 --- a/server/lib/classes/cronjob.inc.php +++ b/server/lib/classes/cronjob.inc.php @@ -86,8 +86,8 @@ class cronjob { if($run_it == true) { $this->onRunJob(); $this->onAfterRun(); + $this->onCompleted(); } - $this->onCompleted(); return; } -- GitLab From 607d3643858d70b1a78e91d09e4ac27ccbe428bb Mon Sep 17 00:00:00 2001 From: root Date: Tue, 5 Mar 2019 12:45:13 +0100 Subject: [PATCH 296/310] soap api server bugfix fix invalid return of mirror id --- interface/lib/classes/remote.d/server.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/lib/classes/remote.d/server.inc.php b/interface/lib/classes/remote.d/server.inc.php index 261acd848..b14b10d0d 100644 --- a/interface/lib/classes/remote.d/server.inc.php +++ b/interface/lib/classes/remote.d/server.inc.php @@ -233,7 +233,7 @@ class remoting_server extends remoting { $func = array(); foreach($all as $key => $value) { if($key === 'mirror_server_id' || substr($key, -7) === '_server') { - if($value == 0 || $value == 1) { + if(is_numeric($value)) { $func[$key] = $value; } } -- GitLab From 03d4e1a9e0da5789bace17f40656ca0e7aaca034 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 11 Mar 2019 23:52:09 -0600 Subject: [PATCH 297/310] this avoids a warning in bounce mails and logs --- install/tpl/debian6_dovecot2.conf.master | 2 +- install/tpl/debian_dovecot2.conf.master | 2 +- install/tpl/fedora_dovecot2.conf.master | 2 +- install/tpl/opensuse_dovecot2.conf.master | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/install/tpl/debian6_dovecot2.conf.master b/install/tpl/debian6_dovecot2.conf.master index 155453bd3..fd6a87ee0 100644 --- a/install/tpl/debian6_dovecot2.conf.master +++ b/install/tpl/debian6_dovecot2.conf.master @@ -8,6 +8,7 @@ ssl_cert = Date: Wed, 13 Mar 2019 14:10:26 +0100 Subject: [PATCH 298/310] Use env in bash scripting shebangs --- helper_scripts/gentoo_setup.sh | 2 +- helper_scripts/pdns-slave-zone-cleanup.sh | 2 +- helper_scripts/utils.sh | 2 +- remoting_client/cli/ispconfig-cli | 2 +- remoting_client/examples/rest_example.sh | 2 +- server/cron.sh | 2 +- server/scripts/create_daily_nginx_access_logs.sh | 2 +- server/scripts/create_jailkit_chroot.sh | 2 +- server/scripts/create_jailkit_programs.sh | 2 +- server/scripts/create_jailkit_user.sh | 2 +- server/scripts/ispconfig_update.sh | 2 +- server/scripts/run-getmail.sh | 2 +- server/scripts/update_from_dev.sh | 2 +- server/scripts/update_from_dev_stable.sh | 2 +- server/scripts/update_from_svn.sh | 2 +- server/scripts/update_stable.sh | 2 +- server/server.sh | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/helper_scripts/gentoo_setup.sh b/helper_scripts/gentoo_setup.sh index 3c736a378..526d2ac11 100644 --- a/helper_scripts/gentoo_setup.sh +++ b/helper_scripts/gentoo_setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Copyright (c) 2009, Scott Barr # All rights reserved. # diff --git a/helper_scripts/pdns-slave-zone-cleanup.sh b/helper_scripts/pdns-slave-zone-cleanup.sh index 0e64a5043..65348da87 100755 --- a/helper_scripts/pdns-slave-zone-cleanup.sh +++ b/helper_scripts/pdns-slave-zone-cleanup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #### Config ################################ DBHOST="localhost" diff --git a/helper_scripts/utils.sh b/helper_scripts/utils.sh index b42fd32dc..2a473b7fb 100644 --- a/helper_scripts/utils.sh +++ b/helper_scripts/utils.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # this is a bash script library to be called by other scripts, # but not to be run directly diff --git a/remoting_client/cli/ispconfig-cli b/remoting_client/cli/ispconfig-cli index e03aa29f3..83c95216e 100755 --- a/remoting_client/cli/ispconfig-cli +++ b/remoting_client/cli/ispconfig-cli @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Command line for ISPConfig remote user REST API using either smart functions or raw methods. # Author: Johan Ehnberg, johan@molnix.com diff --git a/remoting_client/examples/rest_example.sh b/remoting_client/examples/rest_example.sh index 5173f0fa3..61919927f 100644 --- a/remoting_client/examples/rest_example.sh +++ b/remoting_client/examples/rest_example.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/server/cron.sh b/server/cron.sh index 58ddc67ff..9af736977 100644 --- a/server/cron.sh +++ b/server/cron.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin diff --git a/server/scripts/create_daily_nginx_access_logs.sh b/server/scripts/create_daily_nginx_access_logs.sh index ce4945f85..8b4d4db6b 100644 --- a/server/scripts/create_daily_nginx_access_logs.sh +++ b/server/scripts/create_daily_nginx_access_logs.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin FILES=/var/log/ispconfig/httpd/* for f in $FILES diff --git a/server/scripts/create_jailkit_chroot.sh b/server/scripts/create_jailkit_chroot.sh index 9ddfb3834..57a749c9b 100755 --- a/server/scripts/create_jailkit_chroot.sh +++ b/server/scripts/create_jailkit_chroot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Create the jailkit chroot diff --git a/server/scripts/create_jailkit_programs.sh b/server/scripts/create_jailkit_programs.sh index 11641f2c1..06c2fde84 100755 --- a/server/scripts/create_jailkit_programs.sh +++ b/server/scripts/create_jailkit_programs.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Add specified programs and their libraries to the jailkit chroot diff --git a/server/scripts/create_jailkit_user.sh b/server/scripts/create_jailkit_user.sh index 5e1060be2..2ecd24b9f 100755 --- a/server/scripts/create_jailkit_user.sh +++ b/server/scripts/create_jailkit_user.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Add user to the jailkit chroot diff --git a/server/scripts/ispconfig_update.sh b/server/scripts/ispconfig_update.sh index fc3450663..be7af8b5f 100644 --- a/server/scripts/ispconfig_update.sh +++ b/server/scripts/ispconfig_update.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash _UPD=1 diff --git a/server/scripts/run-getmail.sh b/server/scripts/run-getmail.sh index 3eac5ec19..e78fc5823 100644 --- a/server/scripts/run-getmail.sh +++ b/server/scripts/run-getmail.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin set -e cd /etc/getmail diff --git a/server/scripts/update_from_dev.sh b/server/scripts/update_from_dev.sh index 0be65986d..8413f0c59 100755 --- a/server/scripts/update_from_dev.sh +++ b/server/scripts/update_from_dev.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash { umask 0077 \ diff --git a/server/scripts/update_from_dev_stable.sh b/server/scripts/update_from_dev_stable.sh index a5dc10605..2a99494be 100644 --- a/server/scripts/update_from_dev_stable.sh +++ b/server/scripts/update_from_dev_stable.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash { umask 0077 \ diff --git a/server/scripts/update_from_svn.sh b/server/scripts/update_from_svn.sh index 8c8ee2ae1..128182639 100644 --- a/server/scripts/update_from_svn.sh +++ b/server/scripts/update_from_svn.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash CUR=`dirname $0` bash ${CUR}/update_from_dev.sh diff --git a/server/scripts/update_stable.sh b/server/scripts/update_stable.sh index 854731077..fbe8480ca 100644 --- a/server/scripts/update_stable.sh +++ b/server/scripts/update_stable.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash _UPD=1 diff --git a/server/server.sh b/server/server.sh index 9c92a868b..ebd1d56c6 100755 --- a/server/server.sh +++ b/server/server.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin -- GitLab From d10c482eef6eced3cf2cc8b13821099ec9ab6f7c Mon Sep 17 00:00:00 2001 From: Marius Burkard Date: Thu, 21 Mar 2019 17:44:14 +0100 Subject: [PATCH 299/310] - rspamd fixes --- interface/web/admin/form/server_config.tform.php | 6 ++++++ interface/web/admin/server_config_edit.php | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/interface/web/admin/form/server_config.tform.php b/interface/web/admin/form/server_config.tform.php index 6bbfd7985..2ff4b5350 100644 --- a/interface/web/admin/form/server_config.tform.php +++ b/interface/web/admin/form/server_config.tform.php @@ -556,6 +556,12 @@ $form["tabs"]['mail'] = array( 'type' => 'TRIM'), ), ), + 'rspamd_available' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), 'dkim_path' => array( 'datatype' => 'VARCHAR', 'formtype' => 'TEXT', diff --git a/interface/web/admin/server_config_edit.php b/interface/web/admin/server_config_edit.php index f50454591..fc37163e7 100644 --- a/interface/web/admin/server_config_edit.php +++ b/interface/web/admin/server_config_edit.php @@ -132,6 +132,14 @@ class page_action extends tform_actions { } } } + + if($section === 'mail') { + if(isset($server_config_array['mail']['rspamd_available']) && $server_config_array['mail']['rspamd_available'] === 'y') { + $this->dataRecord['rspamd_available'] = 'y'; + } else { + $this->dataRecord['rspamd_available'] = 'n'; + } + } if(isset($this->dataRecord['jailkit_chroot_app_programs'])) { $app->uses('file'); -- GitLab From 41601a5b5013a1ddc047c895798e83123a65d0fb Mon Sep 17 00:00:00 2001 From: Guillaume Chauvin <{ID}+{username}@noreply.gitlab.com> Date: Thu, 4 Apr 2019 14:22:56 +0200 Subject: [PATCH 300/310] Add French templates to mail notifications --- server/conf/mail/db_quota_notification_fr.txt | 13 +++++++++++++ server/conf/mail/db_quota_ok_notification_fr.txt | 13 +++++++++++++ server/conf/mail/mail_quota_notification_fr.txt | 14 ++++++++++++++ server/conf/mail/mail_quota_ok_notification_fr.txt | 14 ++++++++++++++ server/conf/mail/web_quota_notification_fr.txt | 14 ++++++++++++++ server/conf/mail/web_quota_ok_notification_fr.txt | 14 ++++++++++++++ server/conf/mail/web_traffic_notification_fr.txt | 8 ++++++++ server/conf/mail/welcome_email_fr.txt | 4 ++++ 8 files changed, 94 insertions(+) create mode 100644 server/conf/mail/db_quota_notification_fr.txt create mode 100644 server/conf/mail/db_quota_ok_notification_fr.txt create mode 100644 server/conf/mail/mail_quota_notification_fr.txt create mode 100644 server/conf/mail/mail_quota_ok_notification_fr.txt create mode 100644 server/conf/mail/web_quota_notification_fr.txt create mode 100644 server/conf/mail/web_quota_ok_notification_fr.txt create mode 100644 server/conf/mail/web_traffic_notification_fr.txt create mode 100644 server/conf/mail/welcome_email_fr.txt diff --git a/server/conf/mail/db_quota_notification_fr.txt b/server/conf/mail/db_quota_notification_fr.txt new file mode 100644 index 000000000..c48a1a2a9 --- /dev/null +++ b/server/conf/mail/db_quota_notification_fr.txt @@ -0,0 +1,13 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Notification de quota de base de données + +La base de données {database_name} a atteint ou est sur le point d'atteindre son quota maximum. + +Base de données : {database_name} +Espace utilisé : {used} +Quota : {quota} +Ratio d'utilisation : {ratio} diff --git a/server/conf/mail/db_quota_ok_notification_fr.txt b/server/conf/mail/db_quota_ok_notification_fr.txt new file mode 100644 index 000000000..3566c97d2 --- /dev/null +++ b/server/conf/mail/db_quota_ok_notification_fr.txt @@ -0,0 +1,13 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Quota de base de données ok + +La base de données {database_name} n'est plus à la limite de son quota. + +Base de données : {database_name} +Espace utilisé : {used} +Quota : {quota} +Ratio d'utilisation : {ratio} diff --git a/server/conf/mail/mail_quota_notification_fr.txt b/server/conf/mail/mail_quota_notification_fr.txt new file mode 100644 index 000000000..58029fe96 --- /dev/null +++ b/server/conf/mail/mail_quota_notification_fr.txt @@ -0,0 +1,14 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Notification de quota de votre compte email + +Le compte email {email} a atteint ou est sur le point d'atteindre son quota maximum. + +Compte email : {email} +Nom : {name} +Espace utilisé : {used} +Quota : {quota} +Ratio d'utilisation : {ratio} \ No newline at end of file diff --git a/server/conf/mail/mail_quota_ok_notification_fr.txt b/server/conf/mail/mail_quota_ok_notification_fr.txt new file mode 100644 index 000000000..4e9a3efa8 --- /dev/null +++ b/server/conf/mail/mail_quota_ok_notification_fr.txt @@ -0,0 +1,14 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Quota de votre compte email ok + +Le compte email {email} n'est plus à la limite de son quota. + +Compte email : {email} +Nom : {name} +Espace utilisé : {used} +Quota : {quota} +Ratio d'utilisation : {ratio} \ No newline at end of file diff --git a/server/conf/mail/web_quota_notification_fr.txt b/server/conf/mail/web_quota_notification_fr.txt new file mode 100644 index 000000000..4f7300eb4 --- /dev/null +++ b/server/conf/mail/web_quota_notification_fr.txt @@ -0,0 +1,14 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Notification de quota de votre espace web + +Le site web {domain} a atteint ou est sur le point d'atteindre son quota maximum. + +Domaine : {domain} +Espace utilisé : {used} +Limite souple : {soft} +Limite stricte : {hard} +Ratio d'utilisation : {ratio} \ No newline at end of file diff --git a/server/conf/mail/web_quota_ok_notification_fr.txt b/server/conf/mail/web_quota_ok_notification_fr.txt new file mode 100644 index 000000000..7d33fd022 --- /dev/null +++ b/server/conf/mail/web_quota_ok_notification_fr.txt @@ -0,0 +1,14 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Quota de votre espace web ok + +Le site web {domain} n'est plus à la limite de son quota. + +Domaine : {domain} +Espace utilisé : {used} +Limite souple : {soft} +Limite stricte : {hard} +Ratio d'utilisation : {ratio} \ No newline at end of file diff --git a/server/conf/mail/web_traffic_notification_fr.txt b/server/conf/mail/web_traffic_notification_fr.txt new file mode 100644 index 000000000..cb4b317f7 --- /dev/null +++ b/server/conf/mail/web_traffic_notification_fr.txt @@ -0,0 +1,8 @@ +MIME-Version: 1.0 +Content-type: text/plain; charset=utf-8 +Content-Transfer-Encoding: 8bit +From: {admin_mail} +Reply-To: {admin_mail} +Subject: Notification de trafic web dépassé - site désactivé + +Le site web {domain} a dépassé sa limite de trafic et a été désactivé. \ No newline at end of file diff --git a/server/conf/mail/welcome_email_fr.txt b/server/conf/mail/welcome_email_fr.txt new file mode 100644 index 000000000..b720377aa --- /dev/null +++ b/server/conf/mail/welcome_email_fr.txt @@ -0,0 +1,4 @@ +From: ISPConfig +Subject: Bienvenue dans votre nouvelle boîte aux lettres + +Votre nouveau compte email est désormais activé. Votre webmaster. \ No newline at end of file -- GitLab From 5662bd16b3df57d39c4ed0b18f8a5722d9cc0650 Mon Sep 17 00:00:00 2001 From: Guillaume Chauvin <{ID}+{username}@users.noreply.github.com> Date: Fri, 12 Apr 2019 20:33:37 +0200 Subject: [PATCH 301/310] Fixes #5290 - Allow Certbot http challenge behind basic auth --- server/conf/nginx_vhost.conf.master | 1 + 1 file changed, 1 insertion(+) diff --git a/server/conf/nginx_vhost.conf.master b/server/conf/nginx_vhost.conf.master index bc09c4293..4d6ee600f 100644 --- a/server/conf/nginx_vhost.conf.master +++ b/server/conf/nginx_vhost.conf.master @@ -143,6 +143,7 @@ server { location ^~ /.well-known/acme-challenge/ { access_log off; log_not_found off; + auth_basic off; root /usr/local/ispconfig/interface/acme/; autoindex off; index index.html; -- GitLab From 534a6dc06eec9b5eeaf5eea89499db1b9d3c999f Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Fri, 24 May 2019 12:15:51 +0200 Subject: [PATCH 302/310] improve datalog-viewer --- interface/web/monitor/dataloghistory_view.php | 65 ++++++++++++++++++- .../lib/lang/de_dataloghistory_view.lng | 17 +++++ .../lib/lang/en_dataloghistory_view.lng | 17 +++++ .../monitor/templates/dataloghistory_view.htm | 6 ++ 4 files changed, 103 insertions(+), 2 deletions(-) diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index 2b5ea1e03..78d4db045 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -1,5 +1,4 @@ tpl->setvar($wb); $id = intval($_GET['id']); $record = $app->db->queryOneRecord('SELECT * FROM sys_datalog WHERE datalog_id = ?', $id); - $out['id'] = $id; $out['timestamp'] = date($app->lng('conf_format_datetime'), $record['tstamp']); @@ -75,6 +73,7 @@ switch ($record['action']) { $app->tpl->setLoop('inserts', $inserts); break; case 'u': + $out = describe($record['dbtable'], $data, $out); $updates = array(); foreach ($data['new'] as $key=>$value) { if ($value != $data['old'][$key]) { @@ -128,4 +127,66 @@ function show_diff_if_needed($old, $new) { } } +function describe($dbtable, $data, $out) { + global $app; + $out['describe'] = $app->lng('describe_'.$dbtable); + switch ($dbtable) { + case 'client': + $check = 'username'; + break; + case 'directive_snippets': + $check = 'name'; + break; + case 'domain': + $check = 'domain'; + break; + case 'ftp_user': + $check = 'username'; + break; + case 'mail_domain': + $check = 'domain'; + break; + case 'mail_forwarding': + $check = 'source'; + break; + case 'mail_user': + $check = 'email'; + break; + case 'mail_user_filter': + $check = 'rulename'; + break; + case 'remote_user': + $check = 'remote_username'; + break; + case 'server_php': + $check = 'name'; + break; + case 'shell_user': + $check = 'username'; + break; + case 'spamfilter_policy': + $check = 'policy_name'; + break; + case 'spamfilter_users': + $check = 'email'; + break; + case 'web_domain': + $check = 'domain'; + break; + case 'web_database_user': + $check = 'database_user'; + break; + case 'web_database': + $check = 'database_name'; + break; + case 'web_folder_user': + $check = 'username'; + break; + } + + $out['describe_data'] = @(isset($data['old'][$check]) && $data['old'][$check] != $data['new'][$check])?$data['old'][$check].'/'.$data['new'][$check]:$data['new'][$check]; + + return $out; +} + ?> diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng index 81123a69c..0359f21e0 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -23,4 +23,21 @@ $wb['new_txt'] = 'Neu'; $wb['btn_cancel_txt'] = 'Zurück'; $wb['undo_txt'] = 'Rückgängig machen'; $wb['undo_confirmation_txt'] = 'Soll diese Änderung wirklich rückgängig gemacht werden?'; +$wb['describe_client'] = 'Username'; +$wb['describe_directive_snippets'] = 'Direktiven Schnippsel'; +$wb['describe_domain'] = 'Domain'; +$wb['describe_ftp_user'] = 'FTP-User'; +$wb['describe_mail_domain'] = 'Email-Domain'; +$wb['describe_mail_forwarding'] = 'Quelle'; +$wb['describe_mail_user'] = 'Email'; +$wb['describe_mail_user_filter'] = 'Mailuser-Filter'; +$wb['describe_remote_user'] = 'Remote-User'; +$wb['describe_server_php'] = 'PHP Version'; +$wb['describe_shell_user'] = 'Shell-User'; +$wb['describe_spamfilter_policy'] = 'Spam-Richtlinie'; +$wb['describe_spamfilter_users'] = 'Spam-User'; +$wb['describe_web_database'] = 'Datenbank'; +$wb['describe_web_database_user'] = 'Datenbank-User'; +$wb['describe_web_domain'] = 'Webseite'; +$wb['describe_web_folder_user'] = 'Web-Ordner User'; ?> diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng index df9ddd286..523018aae 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -23,4 +23,21 @@ $wb['new_txt'] = 'New'; $wb['btn_cancel_txt'] = 'Back'; $wb['undo_txt'] = 'Undo action'; $wb['undo_confirmation_txt'] = 'Do you really want to undo this action?'; +$wb['describe_client'] = 'Username'; +$wb['describe_directive_snippets'] = 'Direktive Snippet'; +$wb['describe_domain'] = 'Domain'; +$wb['describe_ftp_user'] = 'FTP-User'; +$wb['describe_mail_domain'] = 'Email-Domain'; +$wb['describe_mail_forwarding'] = 'Source'; +$wb['describe_mail_user'] = 'Email'; +$wb['describe_mail_user_filter'] = 'Mailuser-Filter'; +$wb['describe_remote_user'] = 'Remote-User'; +$wb['describe_shell_user'] = 'Shell-User'; +$wb['describe_server_php'] = 'PHP Version'; +$wb['describe_spamfilter_policy'] = 'Spam-Policy'; +$wb['describe_spamfilter_users'] = 'Spam-User'; +$wb['describe_web_database'] = 'Database'; +$wb['describe_web_database_user'] = 'Database-User'; +$wb['describe_web_domain'] = 'Website'; +$wb['describe_web_folder_user'] = 'Web-Folder User'; ?> diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm index 4ba82bbf0..f92a9a1e4 100644 --- a/interface/web/monitor/templates/dataloghistory_view.htm +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -20,6 +20,12 @@ + + + + + + -- GitLab From 46b74480809a224464a95cead5d722137d71bb2f Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Fri, 24 May 2019 13:04:02 +0200 Subject: [PATCH 303/310] add cron to last commit _ datalog-viewer --- interface/web/monitor/dataloghistory_view.php | 11 +++++++++-- .../web/monitor/lib/lang/de_dataloghistory_view.lng | 1 + .../web/monitor/lib/lang/en_dataloghistory_view.lng | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index 78d4db045..c18860c36 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -61,6 +61,8 @@ if(!$data = unserialize(stripslashes($record['data']))) { $data = unserialize($record['data']); } +$out = describe($record['dbtable'], $data, $out); + switch ($record['action']) { case 'i': $inserts = array(); @@ -73,7 +75,6 @@ switch ($record['action']) { $app->tpl->setLoop('inserts', $inserts); break; case 'u': - $out = describe($record['dbtable'], $data, $out); $updates = array(); foreach ($data['new'] as $key=>$value) { if ($value != $data['old'][$key]) { @@ -134,6 +135,10 @@ function describe($dbtable, $data, $out) { case 'client': $check = 'username'; break; + case 'cron': + $temp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); + $out['describe_data'] = $temp['domain']; + break; case 'directive_snippets': $check = 'name'; break; @@ -184,7 +189,9 @@ function describe($dbtable, $data, $out) { break; } - $out['describe_data'] = @(isset($data['old'][$check]) && $data['old'][$check] != $data['new'][$check])?$data['old'][$check].'/'.$data['new'][$check]:$data['new'][$check]; + if(!isset($out['describe_data'])) { + $out['describe_data'] = @(isset($data['old'][$check]) && $data['old'][$check] != $data['new'][$check])?$data['old'][$check].'/'.$data['new'][$check]:$data['new'][$check]; + } return $out; } diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng index 0359f21e0..de331bfeb 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -24,6 +24,7 @@ $wb['btn_cancel_txt'] = 'Zurück'; $wb['undo_txt'] = 'Rückgängig machen'; $wb['undo_confirmation_txt'] = 'Soll diese Änderung wirklich rückgängig gemacht werden?'; $wb['describe_client'] = 'Username'; +$wb['describe_cron'] = 'Webseite'; $wb['describe_directive_snippets'] = 'Direktiven Schnippsel'; $wb['describe_domain'] = 'Domain'; $wb['describe_ftp_user'] = 'FTP-User'; diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng index 523018aae..bdb961ffa 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -24,6 +24,7 @@ $wb['btn_cancel_txt'] = 'Back'; $wb['undo_txt'] = 'Undo action'; $wb['undo_confirmation_txt'] = 'Do you really want to undo this action?'; $wb['describe_client'] = 'Username'; +$wb['describe_cron'] = 'Website'; $wb['describe_directive_snippets'] = 'Direktive Snippet'; $wb['describe_domain'] = 'Domain'; $wb['describe_ftp_user'] = 'FTP-User'; -- GitLab From a122f6eed68d82cf5b150cafa555b6ef238ef861 Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Fri, 24 May 2019 17:30:27 +0200 Subject: [PATCH 304/310] datalog-viewer: show parent web-site for deleted cron-jobs, too --- interface/web/monitor/dataloghistory_view.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index c18860c36..ae0821b53 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -61,7 +61,7 @@ if(!$data = unserialize(stripslashes($record['data']))) { $data = unserialize($record['data']); } -$out = describe($record['dbtable'], $data, $out); +$out = describe($record['dbtable'], $data, $out, $record['action']); switch ($record['action']) { case 'i': @@ -136,7 +136,8 @@ function describe($dbtable, $data, $out) { $check = 'username'; break; case 'cron': - $temp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ?", $data['new']['parent_domain_id']); + $where = @($action == 'd')?$data['old']['parent_domain_id']:$data['new']['parent_domain_id']; + $temp = $app->db->queryOneRecord("SELECT domain FROM web_domain WHERE domain_id = ?", $where); $out['describe_data'] = $temp['domain']; break; case 'directive_snippets': -- GitLab From 118ed21100452d99c4cfb47d48b5f4581b54fa40 Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Tue, 28 May 2019 11:56:20 +0200 Subject: [PATCH 305/310] show user + ip in dataloghistory --- .../sql/incremental/upd_dev_collection.sql | 9 ++++++ install/sql/ispconfig3.sql | 15 ++++++++++ interface/web/login/index.php | 30 +++++-------------- interface/web/monitor/dataloghistory_view.php | 27 +++++++++++++++-- .../lib/lang/de_dataloghistory_view.lng | 6 ++++ .../lib/lang/en_dataloghistory_view.lng | 6 ++++ .../monitor/templates/dataloghistory_view.htm | 6 ++++ .../lib/classes/cron.d/200-logfiles.inc.php | 2 ++ 8 files changed, 75 insertions(+), 26 deletions(-) diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 671e3742b..26ad1d6c4 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -166,3 +166,12 @@ CREATE TABLE IF NOT EXISTS `sys_mailqueue` ( ALTER TABLE `web_domain` ADD `jailkit_jkupdate_cron` enum('n','y') NOT NULL DEFAULT 'y' AFTER `custom_php_ini`; ALTER TABLE `sys_datalog` ADD `session_id` varchar(64) NOT NULL DEFAULT '' AFTER `error`; + +CREATE TABLE IF NOT EXISTS `sys_login` ( + `session_id` varchar(64) NOT NULL, + `username` varchar(64) NOT NULL default '', + `ip` varchar(255) NOT NULL default '', + `login-time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`session_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 75a698e76..a94f859c4 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1556,6 +1556,21 @@ CREATE TABLE `sys_group` ( PRIMARY KEY (`groupid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; +-- -------------------------------------------------------- + +-- +-- Table structure for table `sys_login` +-- + +CREATE TABLE `sys_login` ( + `session_id` varchar(64) NOT NULL, + `username` varchar(64) NOT NULL default '', + `ip` varchar(255) NOT NULL default '', + `login-time` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`session_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + -- -------------------------------------------------------- -- diff --git a/interface/web/login/index.php b/interface/web/login/index.php index b55ac74f1..c439a636f 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -262,25 +262,18 @@ if(count($_POST) > 0) { $app->plugin->raiseEvent('login', $username); //* Save successfull login message to var - $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id(); + //$authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s'); + $authlog = 'Successful login for user \''. $username .'\' from '. $_SERVER['REMOTE_ADDR'] .' at '. date('Y-m-d H:i:s') . ' with session ID ' .session_id(); $authlog_handle = fopen($conf['ispconfig_log_dir'].'/auth.log', 'a'); fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); - - // get last IP used to login - $user_data = $app->db->queryOneRecord("SELECT last_login_ip,last_login_at FROM sys_user WHERE username = ?", $username); - - $_SESSION['s']['last_login_ip'] = $user_data['last_login_ip']; - $_SESSION['s']['last_login_at'] = $user_data['last_login_at']; - if(!$loginAs) { - $app->db->query("UPDATE sys_user SET last_login_ip = ?, last_login_at = ? WHERE username = ?", $_SERVER['REMOTE_ADDR'], time(), $username); - } + $app->db->query("INSERT INTO sys_login (`session_id`, `username`, `ip`, `login-time`) VALUES (?, ?, ?, CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE `login-time`=CURRENT_TIMESTAMP", session_id(), $username, $_SERVER['REMOTE_ADDR']); /* * We need LOGIN_REDIRECT instead of HEADER_REDIRECT to load the * new theme, if the logged-in user has another */ - if($loginAs) { + if ($loginAs){ echo 'LOGIN_REDIRECT:'.$_SESSION['s']['module']['startpage']; exit; } else { @@ -292,7 +285,8 @@ if(count($_POST) > 0) { $error = $app->lng('error_user_blocked'); } } else { - if(!$alreadyfailed['times']) { + if(!$alreadyfailed['times'] ) + { //* user login the first time wrong $sql = "INSERT INTO `attempts_login` (`ip`, `times`, `login_time`) VALUES (?, 1, NOW())"; $app->db->query($sql, $ip); @@ -351,17 +345,7 @@ $app->tpl->setVar('current_theme', isset($_SESSION['s']['theme']) ? $_SESSION['s //die(isset($_SESSION['s']['theme']) ? $_SESSION['s']['theme'] : 'default'); // Logo -$logo = $app->db->queryOneRecord("SELECT * FROM sys_ini WHERE sysini_id = 1"); -if($logo['custom_logo'] != ''){ - $base64_logo_txt = $logo['custom_logo']; -} else { - $base64_logo_txt = $logo['default_logo']; -} -$tmp_base64 = explode(',', $base64_logo_txt, 2); -$logo_dimensions = $app->functions->getimagesizefromstring(base64_decode($tmp_base64[1])); -$app->tpl->setVar('base64_logo_width', $logo_dimensions[0].'px'); -$app->tpl->setVar('base64_logo_height', $logo_dimensions[1].'px'); -$app->tpl->setVar('base64_logo_txt', $base64_logo_txt); +$app->tpl->logo(); // Title if (!empty($sys_config['company_name'])) { diff --git a/interface/web/monitor/dataloghistory_view.php b/interface/web/monitor/dataloghistory_view.php index ae0821b53..450fb4203 100644 --- a/interface/web/monitor/dataloghistory_view.php +++ b/interface/web/monitor/dataloghistory_view.php @@ -57,6 +57,13 @@ $out['action_name'] = $app->lng($record['action']); $out['session_id'] = $record['session_id']; +if ($out['session_id'] != '') { + $temp = $app->db->queryOneRecord("SELECT username, ip FROM sys_login WHERE session_id = ?", $out['session_id']); + $out['datalog_username'] = $temp['username']; + $out['datalog_userip'] = $temp['ip']; + unset($temp); +} + if(!$data = unserialize(stripslashes($record['data']))) { $data = unserialize($record['data']); } @@ -118,7 +125,7 @@ function show_diff_if_needed($old, $new) { global $app; $diff_min_lines = 6; - +$where = @($action == 'd')?$data['old']['parent_domain_id']:$data['new']['parent_domain_id']; if (substr_count($old, "\n") >= $diff_min_lines || substr_count($new, "\n") >= $diff_min_lines) { $opcodes = FineDiff::getDiffOpcodes($old, $new); $html = FineDiff::renderUTF8DiffToHTMLFromOpcodes($old, $opcodes); @@ -128,7 +135,7 @@ function show_diff_if_needed($old, $new) { } } -function describe($dbtable, $data, $out) { +function describe($dbtable, $data, $out, $action) { global $app; $out['describe'] = $app->lng('describe_'.$dbtable); switch ($dbtable) { @@ -149,6 +156,14 @@ function describe($dbtable, $data, $out) { case 'ftp_user': $check = 'username'; break; + case 'mail_archive': + $check = 'storage'; + break; + case 'mail_archive_store': + $where = @($action == 'd')?$data['old']['domain_id']:$data['new']['domain_id']; + $temp = $app->db->queryOneRecord("SELECT domain FROM mail_domain WHERE domain_id = ?", $where); + $out['describe_data'] = $temp['domain']; + break; case 'mail_domain': $check = 'domain'; break; @@ -161,6 +176,12 @@ function describe($dbtable, $data, $out) { case 'mail_user_filter': $check = 'rulename'; break; + case 'managed_monitor_checks': + $check = 'description'; + break; + case 'managed_php': + $check = 'version'; + break; case 'remote_user': $check = 'remote_username'; break; @@ -190,7 +211,7 @@ function describe($dbtable, $data, $out) { break; } - if(!isset($out['describe_data'])) { + if(!isset($out['describe_data'])) { $out['describe_data'] = @(isset($data['old'][$check]) && $data['old'][$check] != $data['new'][$check])?$data['old'][$check].'/'.$data['new'][$check]:$data['new'][$check]; } diff --git a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng index de331bfeb..1917564f8 100644 --- a/interface/web/monitor/lib/lang/de_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/de_dataloghistory_view.lng @@ -23,15 +23,21 @@ $wb['new_txt'] = 'Neu'; $wb['btn_cancel_txt'] = 'Zurück'; $wb['undo_txt'] = 'Rückgängig machen'; $wb['undo_confirmation_txt'] = 'Soll diese Änderung wirklich rückgängig gemacht werden?'; +$wb['datalog_username_txt'] = 'Username'; +$wb['datalog_userip_txt'] = 'IP'; $wb['describe_client'] = 'Username'; $wb['describe_cron'] = 'Webseite'; $wb['describe_directive_snippets'] = 'Direktiven Schnippsel'; $wb['describe_domain'] = 'Domain'; $wb['describe_ftp_user'] = 'FTP-User'; +$wb['describe_mail_archive'] = 'Mail-Archiv'; +$wb['describe_mail_archive_store'] = 'Archiviert Email-Domain'; $wb['describe_mail_domain'] = 'Email-Domain'; $wb['describe_mail_forwarding'] = 'Quelle'; $wb['describe_mail_user'] = 'Email'; $wb['describe_mail_user_filter'] = 'Mailuser-Filter'; +$wb['describe_managed_php'] = 'PHP Version'; +$wb['describe_managed_monitor_checks'] = 'Check'; $wb['describe_remote_user'] = 'Remote-User'; $wb['describe_server_php'] = 'PHP Version'; $wb['describe_shell_user'] = 'Shell-User'; diff --git a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng index bdb961ffa..cd24f5998 100644 --- a/interface/web/monitor/lib/lang/en_dataloghistory_view.lng +++ b/interface/web/monitor/lib/lang/en_dataloghistory_view.lng @@ -23,15 +23,21 @@ $wb['new_txt'] = 'New'; $wb['btn_cancel_txt'] = 'Back'; $wb['undo_txt'] = 'Undo action'; $wb['undo_confirmation_txt'] = 'Do you really want to undo this action?'; +$wb['datalog_username_txt'] = 'Username'; +$wb['datalog_userip_txt'] = 'IP'; $wb['describe_client'] = 'Username'; $wb['describe_cron'] = 'Website'; $wb['describe_directive_snippets'] = 'Direktive Snippet'; $wb['describe_domain'] = 'Domain'; $wb['describe_ftp_user'] = 'FTP-User'; +$wb['describe_mail_archive'] = 'Mail-Archiv'; +$wb['describe_mail_archive_store'] = 'Archived Email-Domain'; $wb['describe_mail_domain'] = 'Email-Domain'; $wb['describe_mail_forwarding'] = 'Source'; $wb['describe_mail_user'] = 'Email'; $wb['describe_mail_user_filter'] = 'Mailuser-Filter'; +$wb['describe_managed_monitor_checks'] = 'Check'; +$wb['describe_managed_php'] = 'PHP Version'; $wb['describe_remote_user'] = 'Remote-User'; $wb['describe_shell_user'] = 'Shell-User'; $wb['describe_server_php'] = 'PHP Version'; diff --git a/interface/web/monitor/templates/dataloghistory_view.htm b/interface/web/monitor/templates/dataloghistory_view.htm index f92a9a1e4..1ff5ec509 100644 --- a/interface/web/monitor/templates/dataloghistory_view.htm +++ b/interface/web/monitor/templates/dataloghistory_view.htm @@ -34,6 +34,12 @@ + + + + (: ) + +
diff --git a/server/lib/classes/cron.d/200-logfiles.inc.php b/server/lib/classes/cron.d/200-logfiles.inc.php index 6f38f0b40..153539a06 100644 --- a/server/lib/classes/cron.d/200-logfiles.inc.php +++ b/server/lib/classes/cron.d/200-logfiles.inc.php @@ -206,6 +206,8 @@ class cronjob_logfiles extends cronjob { } } + $app->db->query("DELETE FROM `sys_login` WHERE `login-time` < ADDDATE(NOW(), INTERVAL -? DAY)", $max_syslog); + //###################################################################################################### // Cleanup website tmp directories //###################################################################################################### -- GitLab From d0dd6702696a45aebbd66b7136e17d1f9b48fc5f Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Wed, 29 May 2019 08:40:52 +0200 Subject: [PATCH 306/310] re-add missing code for last commit --- interface/web/login/index.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/interface/web/login/index.php b/interface/web/login/index.php index c439a636f..c4c3f1772 100644 --- a/interface/web/login/index.php +++ b/interface/web/login/index.php @@ -268,6 +268,16 @@ if(count($_POST) > 0) { fwrite($authlog_handle, $authlog ."\n"); fclose($authlog_handle); $app->db->query("INSERT INTO sys_login (`session_id`, `username`, `ip`, `login-time`) VALUES (?, ?, ?, CURRENT_TIMESTAMP) ON DUPLICATE KEY UPDATE `login-time`=CURRENT_TIMESTAMP", session_id(), $username, $_SERVER['REMOTE_ADDR']); + + // get last IP used to login + $user_data = $app->db->queryOneRecord("SELECT last_login_ip,last_login_at FROM sys_user WHERE username = ?", $username); + + $_SESSION['s']['last_login_ip'] = $user_data['last_login_ip']; + $_SESSION['s']['last_login_at'] = $user_data['last_login_at']; + if(!$loginAs) { + $app->db->query("UPDATE sys_user SET last_login_ip = ?, last_login_at = ? WHERE username = ?", $_SERVER['REMOTE_ADDR'], time(), $username); + } + /* * We need LOGIN_REDIRECT instead of HEADER_REDIRECT to load the * new theme, if the logged-in user has another -- GitLab From 58ef2d95ea0a1b3578d4c31edae1f66142471d5b Mon Sep 17 00:00:00 2001 From: Pete Date: Sat, 15 Jun 2019 01:55:24 +0200 Subject: [PATCH 307/310] Update jail.local --- docs/hardening/anti-bruteforce/jail.local | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/hardening/anti-bruteforce/jail.local b/docs/hardening/anti-bruteforce/jail.local index cf9a981df..e9548d2b1 100644 --- a/docs/hardening/anti-bruteforce/jail.local +++ b/docs/hardening/anti-bruteforce/jail.local @@ -1,10 +1,13 @@ +# ++++++++++++++++++++++++++++++++++++++++++++++++++++ +# + NetworkSEC / NwSEC Layer 7 Bruteforce Protection + +# ++++++++++++++++++++++++++++++++++++++++++++++++++++ # -# This goes into (or at the end of) /etc/fail2ban/jail.local +# This goes into /etc/fail2ban/jail.local on Debian/GNU Linux # -[wp-auth] - enabled = true - filter = wp-auth - action = iptables-multiport[name=wp-auth, port="http,https"] - logpath = /var/log/ispconfig/httpd/*/*.log - bantime = 1200 - maxretry = 5 +[nws-wp] +enabled = true +filter = nws-wp +action = iptables-multiport[name=nws-wp, port="http,https"] +logpath = /var/www/clients/client*/web*/log/*.log +bantime = 1200 +maxretry = 5 \ No newline at end of file -- GitLab From 199c0d896911ae93b439e1af215b2fde22f2dafa Mon Sep 17 00:00:00 2001 From: Pete Date: Sat, 15 Jun 2019 01:57:38 +0200 Subject: [PATCH 308/310] Replace wp-auth.conf --- docs/hardening/anti-bruteforce/wp-auth.conf | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/hardening/anti-bruteforce/wp-auth.conf b/docs/hardening/anti-bruteforce/wp-auth.conf index 1fc420c87..cc22adda2 100644 --- a/docs/hardening/anti-bruteforce/wp-auth.conf +++ b/docs/hardening/anti-bruteforce/wp-auth.conf @@ -1,10 +1,26 @@ +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# + NetworkSEC / NwSEC Layer 7 Brute Force Protection + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++ +# +# v1.1 150619 +# +# BSD License +# +# S/W: Fail2ban or NWS ThreatBlock™ ¹ +# +# Application: WordPress +# +# Description: Looks for some login/exploit attempts +# # -# This goes into /etc/fail2ban/filter.d/wp-auth.conf # [Definition] failregex = ^ .* "POST /wp-login.php ^ .* "POST /wordpress/wp-login.php ^ .* "POST /wp/wp-login.php ^ .* "GET /login_page.php + ^ .* "POST /xmlrpc.php #ignoreregex = - \ No newline at end of file +# +# ¹ j/k +# -- GitLab From dddad2fe38ddf8f286e4882e1ff4d65a57fde0fa Mon Sep 17 00:00:00 2001 From: AndyPL Date: Thu, 27 Jun 2019 12:49:03 +0200 Subject: [PATCH 309/310] Change height select email domain in mail_user_mailbox_edit.htm --- interface/web/mail/templates/mail_user_mailbox_edit.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/web/mail/templates/mail_user_mailbox_edit.htm b/interface/web/mail/templates/mail_user_mailbox_edit.htm index bcab744de..b0bb8109a 100644 --- a/interface/web/mail/templates/mail_user_mailbox_edit.htm +++ b/interface/web/mail/templates/mail_user_mailbox_edit.htm @@ -16,7 +16,7 @@ @
- +
-- GitLab From f2df6e1707ae8a78e11d0dbc6cbe239367c06515 Mon Sep 17 00:00:00 2001 From: Jesse Norell Date: Wed, 14 Aug 2019 23:22:00 +0200 Subject: [PATCH 310/310] Example csv import email script. --- .../examples/ispc-import-csv-email.php | 305 ++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 remoting_client/examples/ispc-import-csv-email.php diff --git a/remoting_client/examples/ispc-import-csv-email.php b/remoting_client/examples/ispc-import-csv-email.php new file mode 100644 index 000000000..407ba1635 --- /dev/null +++ b/remoting_client/examples/ispc-import-csv-email.php @@ -0,0 +1,305 @@ +#!/usr/bin/php + $session_id ] ); + $result || die( "$msg\nAdditionally, could not get logout result, session id $session_id may now be abandoned.\n" ); + } + + die( "$msg\n" ); +} + +/** + * Make api call, checking for errors and return 'response' from the decoded data. Opens session if required. + */ +function apiCall( ...$args ) { + global $remote_user, $remote_pass, $session_id; + + // login to remote api and obtain session id if needed + if ( ! ( isset( $session_id ) && $session_id ) ) { + $result = restCall( 'login', [ 'username' => $remote_user, 'password' => $remote_pass, 'client_login' => false, ] ); + + if ( $result ) { + $result = json_decode( $result, true ); + if ( ! $result ) { + die( "Error: unable to login to remote api (json_decode failed)\n" ); + } + + if ( isset( $result['response'] ) ) { + $session_id = $result['response']; + } else { + die( "Error: failed to obtain session id from remote api login\n" ); + } + } + } + + $rest_args = func_get_args(); + $method = array_shift( $rest_args ); + + $result = restCall( $method, array_merge( [ 'session_id' => $session_id, ], ...$rest_args ) ); + + if ( $result ) $data = json_decode( $result, true ); + else session_die( "Could not get $method result" ); + + if ( isset( $data['code'] ) && 'ok' != $data['code'] ) { + $msg = "$method returned " . $data['code'] + . ( isset( $data['message'] ) ? ": " . $data['message'] . "\n" : "\n" ); + session_die( $msg ); + } + + return ( isset( $data['response'] ) ? $data['response'] : $data ); +} + +if ( ! file_exists( "$csv_file" ) ) { + die( "CSV file ($csv_file) not found.\n" ); +} + +// get all mail policies +$mail_policies = apiCall( 'mail_policy_get', [ 'primary_id' => [] ] ); +if ( ! $mail_policies ) { + session_die( "Error: could not look up mail policies\n" ); +} + +// get all spamfilter_user settings +$mail_spamfilter_users = apiCall( 'mail_spamfilter_user_get', [ 'primary_id' => [] ] ); +if ( ! $mail_spamfilter_users ) { + session_die( "Error: could not look up mail spamfilter users\n" ); +} + +$mail_domains = []; + +// Read csv file, map rows and loop through them +$rows = array_map( 'str_getcsv', file( $csv_file ) ); +$header = array_shift( $rows ); +$email_idx = array_search( 'email', $header ); +if ( $email_idx === FALSE ) { + session_die( "Error in csv file: 'email' field not found.\n" ); +} +$csv = []; +foreach( $rows as $row ) { + $email = $row[$email_idx]; + $domain = substr( $email, strpos( $email, '@' ) + 1 ); + + if ( is_array( $row ) && count( $header ) == count( $row ) ) { + $csv[$email] = array_combine( $header, $row ); + } else { + print "Error in csv file: problem parsing email '$email'\n"; + continue; + } + + // look up mail_domain record for this domain + if ( ! isset( $mail_domains[$domain] ) ) { + $data = apiCall( 'mail_domain_get_by_domain', [ 'domain' => $domain ] ); + + if ( is_array( $data ) && isset( $data[0] ) ) { + + // unset these (large and don't need them) + unset( $data[0]['dkim'] ); + unset( $data[0]['dkim_selector'] ); + unset( $data[0]['dkim_public'] ); + unset( $data[0]['dkim_private'] ); + + $mail_domains[$domain] = $data[0]; + + foreach ( $mail_spamfilter_users as $msu ) { + if ( $msu['email'] == "@$domain" && $msu['server_id'] == $mail_domains[$domain]['server_id'] ) { + $mail_domains[$domain]['spamfilter_policy_id'] = $msu['policy_id']; + } + } + } else { + $mail_domains[$domain] = [ 'domain_id' => -1, 'domain' => $domain, ]; + print( "Error: mail_domain $domain does not exist, you must create it first.\n" ); + } + } +} + +// dump manually created account to compare values +//$data = apiCall( 'mail_user_get', [ 'primary_id' => [ 'email' => 'manual@apitest.com' ] ] ); +//var_dump( $data, true ); + +foreach ( $csv as $record ) { + $email = $record['email']; + $addr = substr( $email, 0, strpos( $email, '@' ) ); + $domain = substr( $email, strpos( $email, '@' ) + 1 ); + + // ensure we have mail_domain info + if ( ! isset( $mail_domains[$domain] ) || -1 == $mail_domains[$domain]['domain_id'] ) { + print "Config for domain $domain not available, cannot add email $email.\n"; + continue; + } + + // skip if email already exists + $data = apiCall( 'mail_user_get', [ 'primary_id' => [ 'email' => $email ] ] ); + if ( is_array( $data ) && isset( $data[0] ) && isset( $data[0]['mailuser_id'] ) ) { + print "Email $email already exists, skipping.\n"; + continue; + } + + // get client_id for this sys_userid + if ( isset( $mail_domains[$domain]['client_id'] ) ) { + $client_id = $mail_domains[$domain]['client_id']; + } else { + $client_id = apiCall( 'client_get_id', [ 'sys_userid' => $mail_domains[$domain]['sys_userid'] ] ); + if ( ! $client_id ) { + print "Error: unable to determine client_id for $domain (sys_userid is " . $mail_domains[$domain]['sys_userid'] . "),\n"; + print "cannot create mailbox for Email $email\n"; + continue; + } + $mail_domains[$domain]['client_id'] = $client_id; + } + + // mail_user_add parameters for this email + $params = [ 'params' => [ + 'server_id' => $mail_domains[$domain]['server_id'], + 'email' => $email, + 'login' => $email, + 'password' => $record['password'], + 'name' => $record['name'], + 'uid' => 5000, + 'gid' => 5000, + 'maildir' => "/var/vmail/$domain/$addr", + 'quota' => $record['quota'] * 1024 * 1024, + 'cc' => implode( ',', array_filter( [ $record['cc'], $record['bcc'] ] ) ), + 'homedir' => "/var/vmail/", + 'autoresponder' => ( preg_match( '/^y/i', $record['autoresponder'] ) ? 'y' : 'n' ), + 'autoresponder_start_date' => date( 'Y-m-d H:i:s' ), + 'autoresponder_end_date' => date( '2024-m-d H:i:s' ), + 'autoresponder_text' => $record['autoresponder_text'], + 'move_junk' => ( preg_match( '/^y/i', $record['move_junk'] ) ? 'y' : 'n' ), + 'custom_mailfilter' => "", + 'postfix' => 'y', + 'access' => 'y', + // 'disableimap' => 'n', + // 'disablepop3' => 'n', + // 'disabledeliver' => 'n', + // 'disablesmtp' => 'n', + ], + ]; + + // add mail user + $data = apiCall( 'mail_user_add', [ 'client_id' => $client_id ], $params ); + + if ( ! $data ) { + print "mail_user_add may have a problem inserting $email\n"; + continue; + } + + //$data = apiCall( 'mail_user_get', [ 'primary_id' => [ 'email' => $email ] ] ); + //var_dump( $data, true ); + + // determine mail policy + $spam_lover = ( preg_match( '/^y/i', $record['move_junk'] ) ? $record['spam_lover'] : 'N' ); + $virus_lover = $record['virus_lover']; + $spamfilter_policy_id = null; + + // check domain's policy settings for bypass_spam_checks == 'N' and matching spam_lover/virus_lover, + // if a match, we're done + if ( isset( $mail_domains[$domain]['spamfilter_policy_id'] ) ) { + foreach ( $mail_policies as $policy ) { + if ( $policy['id'] == $mail_domains[$domain]['spamfilter_policy_id'] ) { + if ( 'N' == $policy['bypass_spam_checks'] && $policy['spam_lover'] == $spam_lover && $policy['virus_lover'] == $virus_lover ) { + $spamfilter_policy_id = $policy['id']; + } + } + } + } + // if domain's policy doesn't match, loop through all policies to find a match and insert it + if ( null === $spamfilter_policy_id ) { + foreach ( $mail_policies as $policy ) { + if ( 'Y' == $policy['bypass_spam_checks'] ) { + continue; + } + if ( $policy['spam_lover'] == $spam_lover && $policy['virus_lover'] == $virus_lover ) { + $spamfilter_policy_id = $policy['id']; + + // mail_spamfilter_user entry for this user / policy_id + $params = [ 'params' => [ + 'server_id' => $mail_domains[$domain]['server_id'], + 'priority' => "10", + 'policy_id' => $policy['id'], + 'email' => $email, + 'fullname' => $email, + 'local' => "Y", + ], + ]; + + $data = apiCall( 'mail_spamfilter_user_add', [ 'client_id' => $client_id ], $params ); + + // either we inserted a spamfilter_user or it failed, + // either way, on to the next email + continue 2; + } + } + } +} + + +// logout so session id is cleaned up +if ( isset( $session_id ) && $session_id ) { + $result = restCall( 'logout', [ 'session_id' => $session_id ] ); + $result || die( "Could not get logout result, session id $session_id may now be abandoned.\n" ); +} + +exit(); -- GitLab