Skip to content
......@@ -30,7 +30,7 @@ if (!defined('vlibTemplateClassLoaded')) {
include_once ISPC_INSTALL_ROOT.'/install/lib/classes/tpl_error.inc.php';
include_once ISPC_INSTALL_ROOT.'/install/lib/classes/tpl_ini.inc.php';
class tpl{
class tpl extends stdClass{
/*-----------------------------------------------------------------------------\
| ATTENTION |
......@@ -931,7 +931,7 @@ if (!defined('vlibTemplateClassLoaded')) {
{
array_push($this->_namespace, $varname);
$tempvar = count($this->_namespace) - 1;
$retstr = "for (\$_".$tempvar."=0 ; \$_".$tempvar." < count(\$this->_arrvars";
$retstr = "for (\$_".$tempvar."=0 ; \$_".$tempvar." < \$this->_tpl_count(\$this->_arrvars";
for ($i=0; $i < count($this->_namespace); $i++) {
$retstr .= "['".$this->_namespace[$i]."']";
if ($this->_namespace[$i] != $varname) $retstr .= "[\$_".$i."]";
......@@ -1170,7 +1170,15 @@ if (!defined('vlibTemplateClassLoaded')) {
array_push($this->_currentincludedir, dirname($this->_tmplfilename));
$this->_includedepth++;
$success = @eval($this->_tmplfilep);
try {
$success = @eval($this->_tmplfilep);
} catch(Exception $ex) {
print $this->_tmplfilep;
throw $ex;
} catch(TypeError $ex) {
print $this->_tmplfilep;
throw $ex;
}
$this->_includedepth--;
array_pop($this->_currentincludedir);
......@@ -1268,6 +1276,27 @@ if (!defined('vlibTemplateClassLoaded')) {
return $return;
}
/**
* Used during in evaled code to replace PHP count function for PHP 8 compatibility
* @var variable to be counted
*/
private function _tpl_count($var)
{
$retvar = 0;
if(isset($var)) {
if(is_array($var)) {
$retvar = count($var);
} elseif(is_null($var)) {
$retvar = 0;
} else {
$retvar = 1;
}
} else {
$retvar = 0;
}
return $retvar;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following functions have no use and are included just so that if the user
is making use of vlibTemplateCache functions, this doesn't crash when changed to
......
......@@ -98,6 +98,10 @@ function get_distname() {
$mainver = current($mainver).'.'.next($mainver);
}
switch ($mainver){
case "22.04":
$relname = "(Jammy Jellyfish)";
$distconfid = 'ubuntu2204';
break;
case "20.04":
$relname = "(Focal Fossa)";
$distconfid = 'ubuntu2004';
......@@ -248,6 +252,13 @@ function get_distname() {
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 11.0 (Bullseye) or compatible\n");
} elseif(substr(trim(file_get_contents('/etc/debian_version')),0,2) == '12') {
$distname = 'Debian';
$distver = 'Bookworm';
$distconfid = 'debian120';
$distid = 'debian60';
$distbaseid = 'debian';
swriteln("Operating System: Debian 12.0 (Bookworm) or compatible\n");
} elseif(strstr(trim(file_get_contents('/etc/debian_version')), '/sid')) {
$distname = 'Debian';
$distver = 'Testing';
......@@ -295,88 +306,93 @@ function get_distname() {
}
//** RHEL (including compatible clones) & Fedora
elseif(file_exists('/etc/redhat-release') && file_exists('/etc/os-release')) {
$content = file_get_contents('/etc/os-release');
preg_match('/(?<=PRETTY_NAME=\").+?(?=\")/', $content, $prettyname);
preg_match('/(?<=NAME=\").+?(?=\")/', $content, $name);
preg_match('/(?<=VERSION=\").+?(?=\")/', $content, $version);
preg_match('/(?<=VERSION_ID=\").+?(?=\")/', $content, $versionid);
if(stristr($prettyname[0], 'Fedora 32 (Thirty Two)')) {
$distname = 'Fedora';
$distver = '32';
$distid = 'fedora32';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 32 or compatible\n");
} elseif(stristr($prettyname[0], 'Fedora 33 (Thirty Three)')) {
$distname = 'Fedora';
$distver = '33';
$distid = 'fedora33';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 33 or compatible\n");
//** RHEL 7 and compatible clones
} elseif(preg_match('/^(?:7|7\.[0-9]{1,2})$/', $versionid[0])) {
preg_match_all('/([0-9]{1,2})\.?([0-9]{0,2})\.?([0-9]*)/', file_get_contents('/etc/redhat-release'), $centos7_version);
$distname = $name[0];
$distver = is_array($centos7_version)? implode('.', array_filter(array($centos7_version[1][0],$centos7_version[2][0],$centos7_version[3][0]),'strlen')) : $version[0];
$distid = 'centos72';
$distbaseid = 'fedora';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
//** RHEL 8 and compatible clones
} elseif(preg_match('/^(?:8|8\.[0-9]{1,2})$/', $versionid[0])) {
$distname = $name[0];
$distver = $version[0];
$distid = 'centos80';
$distbaseid = 'fedora';
swriteln("Operating System: " . $prettyname[0] . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Redhat or compatible\n");
}
elseif(file_exists('/etc/redhat-release') && file_exists('/etc/os-release')) {
$content = file_get_contents('/etc/os-release');
preg_match('/(?<=PRETTY_NAME=\").+?(?=\")/', $content, $prettyname);
preg_match('/(?<=NAME=\").+?(?=\")/', $content, $name);
preg_match('/(?<=VERSION=\").+?(?=\")/', $content, $version);
preg_match('/(?<=VERSION_ID=\").+?(?=\")/', $content, $versionid);
if(stristr($prettyname[0], 'Fedora 32 (Thirty Two)')) {
$distname = 'Fedora';
$distver = '32';
$distid = 'fedora32';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 32 or compatible\n");
} elseif(stristr($prettyname[0], 'Fedora 33 (Thirty Three)')) {
$distname = 'Fedora';
$distver = '33';
$distid = 'fedora33';
$distbaseid = 'fedora';
swriteln("Operating System: Fedora 33 or compatible\n");
//** RHEL 7 and compatible clones
} elseif(preg_match('/^(?:7|7\.[0-9]{1,2})$/', $versionid[0])) {
preg_match_all('/([0-9]{1,2})\.?([0-9]{0,2})\.?([0-9]*)/', file_get_contents('/etc/redhat-release'), $centos7_version);
$distname = $name[0];
$distver = is_array($centos7_version)? implode('.', array_filter(array($centos7_version[1][0],$centos7_version[2][0],$centos7_version[3][0]),'strlen')) : $version[0];
$distid = 'centos72';
$distbaseid = 'fedora';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
//** RHEL 8 and compatible clones
} elseif(preg_match('/^(?:8|8\.[0-9]{1,2})$/', $versionid[0])) {
$distname = $name[0];
$distver = $version[0];
$distid = 'centos80';
$distbaseid = 'fedora';
swriteln("Operating System: " . $prettyname[0] . "\n");
//** RHEL 9 and compatible clones
} elseif(preg_match('/^(?:9|9\.[0-9]{1,2})$/', $versionid[0])) {
$distname = $name[0];
$distver = $version[0];
$distid = 'centos90';
$distbaseid = 'fedora';
swriteln("Operating System: " . $prettyname[0] . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
swriteln("Operating System: Redhat or compatible\n");
}
//** CentOS 6
} elseif(file_exists('/etc/redhat-release') && !file_exists('/etc/os-release') && !file_exists('/etc/els-release')) {
} elseif(file_exists('/etc/redhat-release') && !file_exists('/etc/os-release') && !file_exists('/etc/els-release')) {
$content = file_get_contents('/etc/redhat-release');
$content = file_get_contents('/etc/redhat-release');
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6\.?([0-9]{0,2})\.?(\s)?([a-zA-Z()]+))$/', $content, $centos6_version);
$distname = 'CentOS Linux';
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6\.?([0-9]{0,2})\.?(\s)?([a-zA-Z()]+))$/', $content, $centos6_version);
$distname = 'CentOS Linux';
$distver = $centos6_version[0][0] ? $centos6_version[0][0] : '6';
$distid = 'centos53';
$distbaseid = 'fedora';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
}
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
}
//** CentOS 6 Extended Lifecycle Support by CloudLinux
} elseif(file_exists('/etc/redhat-release') && file_exists('/etc/els-release') && !file_exists('/etc/os-release')) {
} elseif(file_exists('/etc/redhat-release') && file_exists('/etc/els-release') && !file_exists('/etc/os-release')) {
$content = file_get_contents('/etc/els-release');
$content = file_get_contents('/etc/els-release');
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6)\.?([0-9]{0,2})?\.?\s([a-zA-Z(), ]+)?$/', $content, $centos6_version);
$distname = 'CentOS Linux';
$distver = $centos6_version[0][0] ? $centos6_version[0][0] : '6';
$distid = 'centos53';
if(stristr($content, 'CentOS Linux release 6') || stristr($content, 'CentOS release 6')) {
preg_match_all('/(6)\.?([0-9]{0,2})?\.?\s([a-zA-Z(), ]+)?$/', $content, $centos6_version);
$distname = 'CentOS Linux';
$distver = $centos6_version[0][0] ? $centos6_version[0][0] : '6';
$distid = 'centos53';
$distbaseid = 'fedora';
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
}
}
swriteln("Operating System: " . $distname . " " . $distver . "\n");
} else {
$distname = 'Redhat';
$distver = 'Unknown';
$distid = 'fedora9';
$distbaseid = 'fedora';
}
}
//** Gentoo
elseif(file_exists('/etc/gentoo-release')) {
......@@ -538,16 +554,15 @@ function remove_blank_lines($input, $file = 1){
$content = $input;
}
$lines = explode("\n", $content);
$new_lines = array();
if(!empty($lines)){
foreach($lines as $line){
if(trim($line) != '') $new_lines[] = $line;
}
}
if(is_array($new_lines)){
$content = implode("\n", $new_lines);
} else {
$content = '';
}
$content = implode("\n", $new_lines);
if($file){
wf($input, $content);
}else{
......
......@@ -28,7 +28,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class installer_base {
class installer_base extends stdClass {
var $wb = array();
var $language = 'en';
......@@ -52,7 +52,7 @@ class installer_base {
}
public function update_acme() {
$acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh 2> /dev/null'));
$acme = explode("\n", (string)shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh 2> /dev/null'));
$acme = reset($acme);
$val = 0;
......@@ -83,13 +83,13 @@ class installer_base {
global $autoinstall, $autoupdate;
$finished = false;
do {
if($name != '' && $autoinstall[$name] != '') {
if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') {
if($autoinstall[$name] == 'default') {
$input = $default;
} else {
$input = $autoinstall[$name];
}
} elseif($name != '' && $autoupdate[$name] != '') {
} elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') {
if($autoupdate[$name] == 'default') {
$input = $default;
} else {
......@@ -126,13 +126,13 @@ class installer_base {
public function free_query($query, $default, $name = '') {
global $autoinstall, $autoupdate;
if($name != '' && $autoinstall[$name] != '') {
if($name != '' && isset($autoinstall[$name]) && $autoinstall[$name] != '') {
if($autoinstall[$name] == 'default') {
$input = $default;
} else {
$input = $autoinstall[$name];
}
} elseif($name != '' && $autoupdate[$name] != '') {
} elseif($name != '' && isset($autoupdate[$name]) && $autoupdate[$name] != '') {
if($autoupdate[$name] == 'default') {
$input = $default;
} else {
......@@ -246,10 +246,15 @@ class installer_base {
//** Check prerequisites
public function check_prerequisites() {
global $conf;
$msg = '';
if(version_compare(phpversion(), '5.4', '<')) $msg .= "PHP Version 5.4 or newer is required. The currently used PHP version is ".phpversion().".\n";
if(version_compare(phpversion(), '8.0', '>=')) $msg .= "PHP Version 8 is not supported yet. Change PHP version back to the default version of the OS. The currently used PHP version is ".phpversion().".\n";
if ($conf['default_php'] != '') {
if(version_compare(phpversion('tidy'), $conf['default_php'], '==')) $msg .= "Your PHP version is not the OS default. Change the PHP version back to the default version of the OS. The currently used PHP version is " . phpversion() . "The default version for your OS is PHP " . $conf['default_php'] . ".\n";
}
if(version_compare(phpversion(), '5.4', '<')) $msg .= "PHP Version 5.4 or newer is required. The currently used PHP version is " . phpversion() . ".\n";
//if(version_compare(phpversion(), '8.2', '>=')) $msg .= "PHP Version 8.2+ is not supported yet. Change the PHP version back to the default version of the OS. The currently used PHP version is " . phpversion() . ".\n";
if(!function_exists('curl_init')) $msg .= "PHP Curl Module is missing.\n";
if(!function_exists('mysqli_connect')) $msg .= "PHP MySQLi Module is nmissing.\n";
if(!function_exists('mb_detect_encoding')) $msg .= "PHP Multibyte Module (MB) is missing.\n";
......@@ -257,6 +262,40 @@ class installer_base {
if($msg != '') die($msg);
}
//** Check MySQL version
public function check_mysql_version() {
global $conf;
// Set MariaDB version to 10.0.5 and MySQL version to 8.0.4 after CentOS 7 support ended to allow preg_* functions in SQL queries
$min_mariadb_version = '5.5';
$min_mysql_version = '5.5';
$rec = $this->db->queryOneRecord('SELECT VERSION() as mysql_version');
if(is_array($rec)) {
$version = $rec['mysql_version'];
} else {
die("Unable to get MySQL or compatible version\n");
}
if(strpos($version,'MariaDB')) {
// We have MariaDB
$parts = explode('-',$version);
$version = $parts[0];
if(version_compare($version, $min_mariadb_version, '<')) {
die("Minimum required MariaDB version is " . $min_mariadb_version . ",found " . $version . "\n");
} else {
swriteln("Checking MariaDB version " . $version . " .. OK");
}
} else {
// We have MySQL or Percona
if(version_compare($version, $min_mysql_version, '<')) {
die("Minimum required MySQL or compatible version is " . $min_mysql_version . ",found " . $version . "\n");
} else {
swriteln("Checking MySQL or compatible version " . $version . " .. OK");
}
}
}
public function force_configure_app($service, $enable_force=true) {
$force = false;
if(AUTOINSTALL == true) return false;
......@@ -807,6 +846,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, INSERT ON ?? TO ?@?";
if ($verbose){
echo $query ."\n";
}
if(!$this->dbmaster->query($query, $value['db'] . '.server_php', $value['user'], $host)) {
$this->warning('Unable to set rights of user in master database: '.$value['db']."\n Query: ".$query."\n Error: ".$this->dbmaster->errorMessage);
}
}
}
......@@ -833,9 +880,9 @@ class installer_base {
$addr_cleanup = "'%u'";
foreach (str_split($out[0]) as $delim) {
$recipient_delimiter = $this->db->escape( str_replace('%', '%%', $delim) );
$addr_cleanup = "SUBSTRING_INDEX(${addr_cleanup}, '${recipient_delimiter}', 1)";
$addr_cleanup = "SUBSTRING_INDEX({$addr_cleanup}, '{$recipient_delimiter}', 1)";
}
$no_addr_extension = "CONCAT(${addr_cleanup}, '@%d')";
$no_addr_extension = "CONCAT({$addr_cleanup}, '@%d')";
} else {
$no_addr_extension = "''";
}
......@@ -869,7 +916,7 @@ class installer_base {
if (is_dir($config_dir)) {
if(is_file($config_dir.'/'.$jk_init)) copy($config_dir.'/'.$jk_init, $config_dir.'/'.$jk_init.'~');
if(is_file($config_dir.'/'.$jk_chrootsh.'.master')) copy($config_dir.'/'.$jk_chrootsh.'.master', $config_dir.'/'.$jk_chrootsh.'~');
if(is_file($config_dir.'/'.$jk_chrootsh)) copy($config_dir.'/'.$jk_chrootsh, $config_dir.'/'.$jk_chrootsh.'~');
if(is_file($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_init.'.master')) {
copy($conf['ispconfig_install_dir'].'/server/conf-custom/install/'.$jk_init.'.master', $config_dir.'/'.$jk_init);
......@@ -1068,6 +1115,14 @@ class installer_base {
return true;
}
public function get_postfix_version() {
//* Get postfix version
exec('postconf -d mail_version 2>&1', $out);
$postfix_version = preg_replace('/.*=\s*/', '', $out[0]);
unset($out);
return $postfix_version;
}
public function configure_postfix($options = '') {
global $conf,$autoinstall;
$cf = $conf['postfix'];
......@@ -1077,10 +1132,7 @@ class installer_base {
$this->error("The postfix configuration directory '$config_dir' does not exist.");
}
//* Get postfix version
exec('postconf -d mail_version 2>&1', $out);
$postfix_version = preg_replace('/.*=\s*/', '', $out[0]);
unset($out);
$postfix_version = $this->get_postfix_version();
//* Install virtual mappings
foreach (glob('tpl/mysql-virtual_*.master') as $filename) {
......@@ -1126,7 +1178,7 @@ class installer_base {
//* If there are RBL's defined, format the list and add them to smtp_recipient_restrictions to prevent removal after an update
$rbl_list = '';
if (@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
if(@isset($server_ini_array['mail']['realtime_blackhole_list']) && $server_ini_array['mail']['realtime_blackhole_list'] != '') {
$rbl_hosts = explode(",", str_replace(" ", "", $server_ini_array['mail']['realtime_blackhole_list']));
foreach ($rbl_hosts as $key => $value) {
$rbl_list .= ", reject_rbl_client ". $value;
......@@ -1136,13 +1188,13 @@ class installer_base {
//* If Postgrey is installed, configure it
$greylisting = '';
if($conf['postgrey']['installed'] == true) {
if(isset($conf['postgrey']['installed']) && ($conf['postgrey']['installed'] == true)) {
$greylisting = ', check_recipient_access mysql:/etc/postfix/mysql-virtual_policy_greylist.cf';
}
$reject_sender_login_mismatch = '';
$reject_authenticated_sender_login_mismatch = '';
if (isset($server_ini_array['mail']['reject_sender_login_mismatch']) && ($server_ini_array['mail']['reject_sender_login_mismatch'] == 'y')) {
if(isset($server_ini_array['mail']['reject_sender_login_mismatch']) && ($server_ini_array['mail']['reject_sender_login_mismatch'] == 'y')) {
$reject_sender_login_mismatch = ',reject_sender_login_mismatch,';
$reject_authenticated_sender_login_mismatch = 'reject_authenticated_sender_login_mismatch, ';
}
......@@ -1152,11 +1204,11 @@ class installer_base {
$stress_adaptive = (isset($server_ini_array['mail']['stress_adaptive']) && ($server_ini_array['mail']['stress_adaptive'] == 'y')) ? '' : $stress_adaptive_placeholder;
$reject_unknown_client_hostname='';
if (isset($server_ini_array['mail']['reject_unknown']) && ($server_ini_array['mail']['reject_unknown'] == 'client' || $server_ini_array['mail']['reject_unknown'] == 'client_helo')) {
if(isset($server_ini_array['mail']['reject_unknown']) && ($server_ini_array['mail']['reject_unknown'] == 'client' || $server_ini_array['mail']['reject_unknown'] == 'client_helo')) {
$reject_unknown_client_hostname=',reject_unknown_client_hostname';
}
$reject_unknown_helo_hostname='';
if ((!isset($server_ini_array['mail']['reject_unknown'])) || $server_ini_array['mail']['reject_unknown'] == 'helo' || $server_ini_array['mail']['reject_unknown'] == 'client_helo') {
if((!isset($server_ini_array['mail']['reject_unknown'])) || $server_ini_array['mail']['reject_unknown'] == 'helo' || $server_ini_array['mail']['reject_unknown'] == 'client_helo') {
$reject_unknown_helo_hostname=',reject_unknown_helo_hostname';
}
......@@ -1301,7 +1353,7 @@ class installer_base {
$change_maildrop_flags = @(preg_match("/$quoted_regex/", $configfile))?false:true;
}
if ($change_maildrop_flags) {
//* Change maildrop service in posfix master.cf
//* Change maildrop service in postfix master.cf
if(is_file($config_dir.'/master.cf')) {
copy($config_dir.'/master.cf', $config_dir.'/master.cf~');
}
......@@ -1310,8 +1362,8 @@ class installer_base {
}
$configfile = $config_dir.'/master.cf';
$content = rf($configfile);
$content = str_replace('flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}',
'flags=DRhu user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' ${extension} ${recipient} ${user} ${nexthop} ${sender}',
$content = preg_replace('/flags=(DRX?hu) user=vmail argv=\/usr\/bin\/maildrop -d \${recipient}/',
'flags=$1 user='.$cf['vmail_username'].' argv=/usr/bin/maildrop -d '.$cf['vmail_username'].' \${extension} \${recipient} \${user} \${nexthop} \${sender}',
$content);
wf($configfile, $content);
}
......@@ -1479,8 +1531,7 @@ class installer_base {
$config_dir = $conf['postfix']['config_dir'];
$quoted_config_dir = preg_quote($config_dir, '|');
$postfix_version = `postconf -d mail_version 2>/dev/null`;
$postfix_version = preg_replace( '/mail_version\s*=\s*(.*)\s*/', '$1', $postfix_version );
$postfix_version = $this->get_postfix_version();
//* Configure master.cf and add a line for deliver
if(!$this->get_postfix_service('dovecot', 'unix')) {
......@@ -1488,7 +1539,7 @@ class installer_base {
if(is_file($config_dir.'/master.cf')){
copy($config_dir.'/master.cf', $config_dir.'/master.cf~2');
}
if(is_file($config_dir.'/master.cf~')){
if(is_file($config_dir.'/master.cf~2')){
chmod($config_dir.'/master.cf~2', 0400);
}
//* Configure master.cf and add a line for deliver
......@@ -1516,15 +1567,15 @@ class installer_base {
foreach ($options as $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
if (preg_match("|check_recipient_access\s+proxy:mysql:{$quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
$new_options[] = $value;
}
if ($configure_lmtp && $conf['mail']['content_filter'] === 'amavisd') {
if ($configure_lmtp && (!isset($conf['mail']['content_filter']) || $conf['mail']['content_filter'] === 'amavisd')) {
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'reject_unlisted_recipient') {
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf"));
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:{$config_dir}/mysql-verify_recipients.cf"));
break;
}
}
......@@ -1591,20 +1642,24 @@ class installer_base {
// Check if we have a dhparams file and if not, create it
if(!file_exists('/etc/dovecot/dh.pem')) {
// Create symlink to ISPConfig dhparam file
swriteln('Creating symlink /etc/dovecot/dh.pem to ISPConfig DHParam file.');
symlink('/usr/local/ispconfig/interface/ssl/dhparam4096.pem', '/etc/dovecot/dh.pem');
/*
swriteln('Creating new DHParams file, this takes several minutes. Do not interrupt the script.');
if(file_exists('/var/lib/dovecot/ssl-parameters.dat')) {
// convert existing ssl parameters file
$command = 'dd if=/var/lib/dovecot/ssl-parameters.dat bs=1 skip=88 | openssl dhparam -inform der > /etc/dovecot/dh.pem';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
} else {
/*
Create a new dhparams file. We use 2048 bit only as it simply takes too long
on smaller systems to generate a 4096 bit dh file (> 30 minutes). If you need
a 4096 bit file, create it manually before you install ISPConfig
*/
//Create a new dhparams file. We use 2048 bit only as it simply takes too long
// on smaller systems to generate a 4096 bit dh file (> 30 minutes). If you need
// a 4096 bit file, create it manually before you install ISPConfig
$command = 'openssl dhparam -out /etc/dovecot/dh.pem 2048';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
*/
}
//remove #2.3+ comment
$content = file_get_contents($config_dir.'/'.$configfile);
......@@ -1699,7 +1754,7 @@ class installer_base {
// Check for amavisd -> pure webserver with postfix for mailing without antispam
if ($conf['amavis']['installed']) {
$content_filter_service = ($configure_lmtp) ? 'lmtp' : 'amavis';
$postconf_commands[] = "content_filter = ${content_filter_service}:[127.0.0.1]:10024";
$postconf_commands[] = "content_filter = {$content_filter_service}:[127.0.0.1]:10024";
$postconf_commands[] = 'receive_override_options = no_address_mappings';
$postconf_commands[] = 'address_verify_virtual_transport = smtp:[127.0.0.1]:10025';
$postconf_commands[] = 'address_verify_transport_maps = static:smtp:[127.0.0.1]:10025';
......@@ -1710,7 +1765,7 @@ class installer_base {
foreach ($options as $value) {
$value = trim($value);
if ($value == '') continue;
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
if (preg_match("|check_recipient_access\s+proxy:mysql:{$quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
$new_options[] = $value;
......@@ -1718,10 +1773,11 @@ class installer_base {
if ($configure_lmtp) {
for ($i = 0; isset($new_options[$i]); $i++) {
if ($new_options[$i] == 'reject_unlisted_recipient') {
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:${config_dir}/mysql-verify_recipients.cf"));
array_splice($new_options, $i+1, 0, array("check_recipient_access proxy:mysql:{$config_dir}/mysql-verify_recipients.cf"));
break;
}
}
$postfix_version = $this->get_postfix_version();
# postfix < 3.3 needs this when using reject_unverified_recipient:
if(version_compare($postfix_version, 3.3, '<')) {
$postconf_commands[] = "enable_original_recipient = yes";
......@@ -1854,7 +1910,7 @@ class installer_base {
if (preg_match('/check_policy_service\s+inet:127.0.0.1:10023/', $value)) {
continue;
}
if (preg_match("|check_recipient_access\s+proxy:mysql:${quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
if (preg_match("|check_recipient_access\s+proxy:mysql:{$quoted_config_dir}/mysql-verify_recipients.cf|", $value)) {
continue;
}
$new_options[] = $value;
......@@ -1921,22 +1977,22 @@ class installer_base {
);
foreach ($local_d as $f) {
$tpl = new tpl();
if (file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
$tpl->newTemplate($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master");
if (file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master")) {
$tpl->newTemplate($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master");
} else {
$tpl->newTemplate("rspamd_${f}.master");
$tpl->newTemplate("rspamd_{$f}.master");
}
$tpl->setVar('dkim_path', $mail_config['dkim_path']);
$tpl->setVar('rspamd_redis_servers', $mail_config['rspamd_redis_servers']);
$tpl->setVar('rspamd_redis_password', $mail_config['rspamd_redis_password']);
$tpl->setVar('rspamd_redis_bayes_servers', $mail_config['rspamd_redis_bayes_servers']);
$tpl->setVar('rspamd_redis_bayes_password', $mail_config['rspamd_redis_bayes_password']);
$tpl->setVar('rspamd_redis_servers', (isset($mail_config['rspamd_redis_servers']) ? $mail_config['rspamd_redis_servers'] : ''));
$tpl->setVar('rspamd_redis_password', (isset($mail_config['rspamd_redis_password']) ? $mail_config['rspamd_redis_password'] : ''));
$tpl->setVar('rspamd_redis_bayes_servers', (isset($mail_config['rspamd_redis_bayes_servers']) ? $mail_config['rspamd_redis_bayes_servers'] : ''));
$tpl->setVar('rspamd_redis_bayes_password', (isset($mail_config['rspamd_redis_bayes_password']) ? $mail_config['rspamd_redis_bayes_password'] : ''));
if(count($local_addrs) > 0) {
$tpl->setLoop('local_addrs', $local_addrs);
}
wf("/etc/rspamd/local.d/${f}", $tpl->grab());
wf("/etc/rspamd/local.d/{$f}", $tpl->grab());
}
......@@ -1953,10 +2009,10 @@ class installer_base {
'arc.conf',
);
foreach ($local_d as $f) {
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/local.d/${f}");
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master /etc/rspamd/local.d/{$f}");
} else {
exec("cp tpl/rspamd_${f}.master /etc/rspamd/local.d/${f}");
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/local.d/{$f}");
}
}
......@@ -1966,10 +2022,10 @@ class installer_base {
'surbl_group.conf',
);
foreach ($override_d as $f) {
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/override.d/${f}");
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master /etc/rspamd/override.d/{$f}");
} else {
exec("cp tpl/rspamd_${f}.master /etc/rspamd/override.d/${f}");
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/override.d/{$f}");
}
}
......@@ -1981,10 +2037,10 @@ class installer_base {
'spf_whitelist.inc.ispc',
);
foreach ($maps_d as $f) {
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_${f}.master /etc/rspamd/local.d/maps.d/${f}");
if(file_exists($conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master")) {
exec('cp '.$conf['ispconfig_install_dir']."/server/conf-custom/install/rspamd_{$f}.master /etc/rspamd/local.d/maps.d/{$f}");
} else {
exec("cp tpl/rspamd_${f}.master /etc/rspamd/local.d/maps.d/${f}");
exec("cp tpl/rspamd_{$f}.master /etc/rspamd/local.d/maps.d/{$f}");
}
}
......@@ -1993,7 +2049,7 @@ class installer_base {
rename("/etc/rspamd/local.d/greylist.conf", "/etc/rspamd/local.d/greylist.old");
}
exec('chmod a+r /etc/rspamd/local.d/* /etc/rspamd/local.d/maps.d/* /etc/rspamd/override.d/*');
exec('chmod a+r,-x+X /etc/rspamd/local.d/* /etc/rspamd/local.d/maps.d/* /etc/rspamd/override.d/*');
# protect passwords in these files
exec('chgrp _rspamd /etc/rspamd/local.d/redis.conf /etc/rspamd/local.d/classifier-bayes.conf');
exec('chmod 640 /etc/rspamd/local.d/redis.conf /etc/rspamd/local.d/classifier-bayes.conf');
......@@ -2004,8 +2060,10 @@ class installer_base {
}
# unneccesary, since this was done above?
$command = 'usermod -a -G amavis _rspamd';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(is_user('_rspamd') && is_group('amavis')) {
$command = 'usermod -a -G amavis _rspamd';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
if(strpos(rf('/etc/rspamd/rspamd.conf'), '.include "$LOCAL_CONFDIR/local.d/users.conf"') === false){
af('/etc/rspamd/rspamd.conf', '.include "$LOCAL_CONFDIR/local.d/users.conf"');
......@@ -2187,7 +2245,7 @@ class installer_base {
//* Backup exiting file
if(is_file($full_file_name)) {
copy($full_file_name, $config_dir.$configfile.'~');
copy($full_file_name, $full_file_name.'~');
}
$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);
......@@ -2338,13 +2396,17 @@ class installer_base {
replaceLine('/etc/apache2/ports.conf', 'Listen 443', 'Listen 443', 1);
// Comment out the namevirtualhost lines, as they were added by ispconfig in ispconfig.conf file again
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:80', '# NameVirtualHost *:80', 1);
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:443', '# NameVirtualHost *:443', 1);
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:80', '# NameVirtualHost *:80', 1, 0);
replaceLine('/etc/apache2/ports.conf', 'NameVirtualHost *:443', '# NameVirtualHost *:443', 1, 0);
}
if(is_file('/etc/apache2/mods-available/fcgid.conf')) {
// add or modify the parameters for fcgid.conf
replaceLine('/etc/apache2/mods-available/fcgid.conf','MaxRequestLen','MaxRequestLen 15728640',1);
if(hasLine('/etc/apache2/mods-available/fcgid.conf','MaxRequestLen')) {
replaceLine('/etc/apache2/mods-available/fcgid.conf','MaxRequestLen',' MaxRequestLen 15728640',1);
} else {
preg_replace('/^(.*\n)(.*)$/sU', '$1 MaxRequestLen 15728640\n$2', '/etc/apache2/mods-available/fcgid.conf');
}
}
if(is_file('/etc/apache2/apache.conf')) {
......@@ -2626,7 +2688,7 @@ class installer_base {
//$command = 'adduser '.$conf['apache']['user'].' '.$apps_vhost_group;
$command = 'usermod -a -G '.$apps_vhost_group.' '.$conf['apache']['user'];
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
caselog($command.' &> /dev/null 2>&1', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(!@is_dir($install_dir)){
mkdir($install_dir, 0755, true);
......@@ -2718,7 +2780,7 @@ class installer_base {
//$command = 'adduser '.$conf['nginx']['user'].' '.$apps_vhost_group;
$command = 'usermod -a -G '.$apps_vhost_group.' '.$conf['nginx']['user'];
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
caselog($command.' &> /dev/null 2>&1', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(!@is_dir($install_dir)){
mkdir($install_dir, 0755, true);
......@@ -2926,7 +2988,7 @@ class installer_base {
$dnsa=dns_get_record($hostname, DNS_A);
if($dnsa) {
foreach ($dnsa as $rec) {
$dns_ips[] = $rec['ip'];
if(is_array($rec) && isset($rec['ip'])) $dns_ips[] = $rec['ip'];
}
}
}
......@@ -2934,7 +2996,7 @@ class installer_base {
$dnsaaaa=dns_get_record($hostname, DNS_AAAA);
if($dnsaaaa) {
foreach ($dnsaaaa as $rec) {
$dns_ips[] = $rec['ip'];
if(is_array($rec) && isset($rec['ip'])) $dns_ips[] = $rec['ip'];
}
}
}
......@@ -2989,6 +3051,8 @@ class installer_base {
$crt_issuer = exec("openssl x509 -in ".escapeshellarg($ssl_crt_file)." -inform PEM -noout -issuer");
}
$issued_successfully = false;
if ((@file_exists($ssl_crt_file) && ($crt_subject == $crt_issuer)) || (!@is_dir($acme_cert_dir) || !@file_exists($check_acme_file) || !@file_exists($ssl_crt_file) || md5_file($check_acme_file) != md5_file($ssl_crt_file)) && $ip_address_match == true) {
// This script is needed earlier to check and open http port 80 or standalone might fail
......@@ -3031,12 +3095,15 @@ class installer_base {
$hook = $pre_hook . $renew_hook;
}
$which_certbot = shell_exec('which certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot letsencrypt');
// Get the default LE client name and version
$le_client = explode("\n", shell_exec('which certbot /root/.local/share/letsencrypt/bin/letsencrypt /opt/eff.org/certbot/venv/bin/certbot letsencrypt'));
$le_client = explode("\n", $which_certbot ? $which_certbot : '');
$le_client = reset($le_client);
$which_acme = shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh');
// Check for Neilpang acme.sh as well
$acme = explode("\n", shell_exec('which acme.sh /usr/local/ispconfig/server/scripts/acme.sh /root/.acme.sh/acme.sh'));
$acme = explode("\n", $which_acme ? $which_acme : '');
$acme = reset($acme);
if((!$acme || !is_executable($acme)) && (!$le_client || !is_executable($le_client))) {
......@@ -3084,8 +3151,6 @@ class installer_base {
}
}
$issued_successfully = false;
// Backup existing ispserver ssl files
//
// We may find valid or broken symlinks or actual files here.
......@@ -3128,11 +3193,11 @@ class installer_base {
$out = null;
$ret = null;
if($conf['nginx']['installed'] == true || $conf['apache']['installed'] == true) {
exec("$acme --issue --log $acme_log -w /usr/local/ispconfig/interface/acme -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret);
exec("$acme --issue --keylength 4096 --log $acme_log -w /usr/local/ispconfig/interface/acme -d " . escapeshellarg($hostname) . " $renew_hook", $out, $ret);
}
// Else, it is not webserver, so we use standalone
else {
exec("$acme --issue --log $acme_log --standalone -d " . escapeshellarg($hostname) . " $hook", $out, $ret);
exec("$acme --issue --keylength 4096 --log $acme_log --standalone -d " . escapeshellarg($hostname) . " $hook", $out, $ret);
}
if($ret == 0 || ($ret == 2 && file_exists($check_acme_file))) {
......@@ -3306,7 +3371,8 @@ class installer_base {
// 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 dhparam2048.pem 2048; ln -sf dhparam2048.pem pure-ftpd-dhparams.pem");
symlink('/usr/local/ispconfig/interface/ssl/dhparam4096.pem', $pureftpd_dir.'/pure-ftpd-dhparams.pem');
//exec("cd $pureftpd_dir; openssl dhparam -out dhparam2048.pem 2048; ln -sf dhparam2048.pem pure-ftpd-dhparams.pem");
}
}
......@@ -3594,20 +3660,32 @@ class installer_base {
// and must be fixed as this will allow the apache user to read the ispconfig files.
// Later this must run as own apache server or via suexec!
if($conf['apache']['installed'] == true){
$command = 'adduser '.$conf['apache']['user'].' ispconfig';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(is_group('ispapps')){
$command = 'adduser '.$conf['apache']['user'].' ispapps';
$ispc_groupinfo = posix_getgrnam('ispconfig');
if(!in_array($conf['apache']['user'],$ispc_groupinfo['members'])) {
$command = 'adduser '.$conf['apache']['user'].' ispconfig';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
if(is_group('ispapps')){
$ispapps_groupinfo = posix_getgrnam('ispapps');
if(!in_array($conf['apache']['user'],$ispapps_groupinfo['members'])) {
$command = 'adduser '.$conf['apache']['user'].' ispapps';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
}
}
if($conf['nginx']['installed'] == true){
$command = 'adduser '.$conf['nginx']['user'].' ispconfig';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
if(is_group('ispapps')){
$command = 'adduser '.$conf['nginx']['user'].' ispapps';
$ispc_groupinfo = posix_getgrnam('ispconfig');
if(!in_array($conf['nginx']['user'],$ispc_groupinfo['members'])) {
$command = 'adduser '.$conf['nginx']['user'].' ispconfig';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
if(is_group('ispapps')){
$ispapps_groupinfo = posix_getgrnam('ispapps');
if(!in_array($conf['nginx']['user'],$ispapps_groupinfo['members'])) {
$command = 'adduser '.$conf['nginx']['user'].' ispapps';
caselog($command.' &> /dev/null', __FILE__, __LINE__, "EXECUTED: $command", "Failed to execute the command $command");
}
}
}
//* Make the shell scripts executable
......@@ -3849,7 +3927,7 @@ class installer_base {
$install_dir = $conf['ispconfig_install_dir'];
//* Root Crontab
exec('crontab -u root -l > crontab.txt');
exec('crontab -u root -l > crontab.txt 2>/dev/null');
$existing_root_cron_jobs = file('crontab.txt');
// remove existing ispconfig cronjobs, in case the syntax has changed
......@@ -3866,10 +3944,6 @@ class installer_base {
$root_cron_jobs[] = "0 0 * * * ".$install_dir."/server/scripts/create_daily_nginx_access_logs.sh &> /dev/null";
}
if ($conf['services']['mail'] == 1) {
$root_cron_jobs[] = "30 23 * * * ".$install_dir."/server/scripts/handle_mailbox_soft_deleted.sh &> /dev/null";
}
foreach($root_cron_jobs as $cron_job) {
if(!in_array($cron_job."\n", $existing_root_cron_jobs)) {
$existing_root_cron_jobs[] = $cron_job."\n";
......@@ -3882,7 +3956,7 @@ class installer_base {
//* Getmail crontab
if(is_user('getmail')) {
$cf = $conf['getmail'];
exec('crontab -u getmail -l > crontab.txt');
exec('crontab -u getmail -l > crontab.txt 2>/dev/null');
$existing_cron_jobs = file('crontab.txt');
$cron_jobs = array(
......
......@@ -64,9 +64,11 @@ class db
public function __destruct() {
if($this->_iConnId) mysqli_close($this->_iConnId);
}
private function do_connect() {
global $conf;
mysqli_report(MYSQLI_REPORT_OFF);
if($this->_iConnId) return true;
$this->dbHost = $conf['mysql']['host'];
......@@ -77,7 +79,7 @@ class db
$this->dbCharset = $conf["mysql"]["charset"];
$this->dbNewLink = false;
$this->dbClientFlags = null;
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort);
$try = 0;
while((!is_object($this->_iConnId) || mysqli_connect_error()) && $try < 5) {
......@@ -92,19 +94,19 @@ class db
$this->_sqlerror('Zugriff auf Datenbankserver fehlgeschlagen! / Database server not accessible!');
return false;
}
if($this->dbName) $this->setDBName($this->dbName);
$this->_setCharset();
}
public function setDBData($host, $user, $password, $port) {
$this->dbHost = $host;
$this->dbUser = $user;
$this->dbPass = $password;
$this->dbPort = $port;
}
public function setDBName($name) {
$this->dbName = $name;
$this->_iConnId = mysqli_connect($this->dbHost, $this->dbUser, $this->dbPass, '', (int)$this->dbPort);
......@@ -114,7 +116,7 @@ class db
return false;
}
}
public function close() {
if($this->_iConnId) mysqli_close($this->_iConnId);
$this->_iConnId = null;
......@@ -192,7 +194,7 @@ class db
}
private function _query($sQuery = '') {
$aArgs = func_get_args();
$this->do_connect();
......@@ -284,7 +286,7 @@ class db
* @return array result row or NULL if none found
*/
public function queryOneRecord($sQuery = '') {
$aArgs = func_get_args();
if(!empty($aArgs)) {
$sQuery = array_shift($aArgs);
......@@ -293,7 +295,7 @@ class db
}
array_unshift($aArgs, $sQuery);
}
$oResult = call_user_func_array([&$this, 'query'], $aArgs);
if(!$oResult) return null;
......@@ -534,7 +536,7 @@ class db
if($debug == 1) echo "mySQL Error Message: ".$this->errorMessage;
}
}
/* TODO: rewrite SQL */
function update($tablename, $form, $bedingung, $debug = 0)
{
......@@ -761,14 +763,14 @@ class db
break;
}
}
/**
* Get the database type (mariadb or mysql)
*
* @access public
* @return string 'mariadb' or string 'mysql'
*/
public function getDatabaseType() {
$tmp = $this->queryOneRecord('SELECT VERSION() as version');
if(stristr($tmp['version'],'mariadb')) {
......@@ -777,7 +779,7 @@ class db
return 'mysql';
}
}
/**
* Get the database version
*
......@@ -785,7 +787,7 @@ class db
* @param bool $major_version_only = true will return the major version only, e.g. 8 for MySQL 8
* @return string version number
*/
public function getDatabaseVersion($major_version_only = false) {
$tmp = $this->queryOneRecord('SELECT VERSION() as version');
$version = explode('-', $tmp['version']);
......
ALTER TABLE `sys_user` ADD `otp_type` SET('none', 'email') NOT NULL DEFAULT 'none' AFTER `lost_password_reqtime`, ADD `otp_data` VARCHAR(255) NULL AFTER `otp_type`, ADD `otp_recovery` VARCHAR(64) NULL AFTER `otp_data`, ADD `otp_attempts` TINYINT NOT NULL DEFAULT '0' AFTER `otp_recovery`;
ALTER TABLE `mail_user` CHANGE `quota` `quota` BIGINT(20) NOT NULL DEFAULT '0';
ALTER TABLE `server_php` ADD `sortprio` INT(20) NOT NULL DEFAULT '100' AFTER `active`;
ALTER TABLE `mail_user` ADD COLUMN `imap_prefix` varchar(255) NULL default NULL AFTER `backup_copies`;
-- #6456 comodoca.com needs to become sectigo.com
UPDATE `dns_ssl_ca` SET `ca_issue` = 'sectigo.com' WHERE `ca_issue` = 'comodo.com';
UPDATE `dns_ssl_ca` SET `ca_issue` = 'sectigo.com' WHERE `ca_issue` = 'comodoca.com';
UPDATE `dns_ssl_ca` SET `ca_name` = 'Sectigo (formerly Comodo CA)' WHERE `ca_issue` = 'sectigo.com';
-- not updating the dns_rr table to change all CAA records that have comodo.com / comodoca.com - we should not touch users records imo - TP
-- #6445 Update the mailbox_soft_delete config option to it's new structure.
-- UPDATE server SET config=REGEXP_REPLACE(config, 'mailbox_soft_delete=n', 'mailbox_soft_delete=0') WHERE config LIKE '%mailbox_soft_delete=n%'
-- UPDATE server SET config=REGEXP_REPLACE(config, 'mailbox_soft_delete=y', 'mailbox_soft_delete=7') WHERE config LIKE '%mailbox_soft_delete=y%'
\ No newline at end of file
ALTER TABLE `spamfilter_policy`
CHANGE `warnvirusrecip` `warnvirusrecip` VARCHAR(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT 'N',
CHANGE `warnbannedrecip` `warnbannedrecip` VARCHAR(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT 'N',
CHANGE `warnbadhrecip` `warnbadhrecip` VARCHAR(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT 'N';
ALTER TABLE `sys_ini` CHANGE `default_logo` `default_logo` TEXT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL;
ALTER TABLE `sys_ini` CHANGE `custom_logo` `custom_logo` TEXT CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL;
\ No newline at end of file
ALTER TABLE `sys_user` ADD `otp_type` SET('none', 'email') NOT NULL DEFAULT 'none' AFTER `lost_password_reqtime`, ADD `otp_data` VARCHAR(255) NULL AFTER `otp_type`, ADD `otp_recovery` VARCHAR(64) NULL AFTER `otp_data`, ADD `otp_attempts` TINYINT NOT NULL DEFAULT '0' AFTER `otp_recovery`;
......@@ -568,7 +568,7 @@ INSERT INTO `dns_ssl_ca` (`id`, `sys_userid`, `sys_groupid`, `sys_perm_user`, `s
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'certSIGN', 'certsign.ro', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'CFCA', 'cfca.com.cn', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'Chunghwa Telecom', 'cht.com.tw', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'Sectigo / Comodo CA', 'comodoca.com', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'Sectigo (formerly Comodo CA)', 'sectigo.com', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'D-TRUST', 'd-trust.net', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'DigiCert', 'digicert.com', 'Y', '', 0),
(NULL, 1, 1, 'riud', 'riud', '', 'Y', 'DocuSign', 'docusign.fr', 'Y', '', 0),
......@@ -1070,7 +1070,7 @@ CREATE TABLE `mail_user` (
`gid` int(11) NOT NULL default '5000',
`maildir` varchar(255) NOT NULL default '',
`maildir_format` varchar(255) NOT NULL default 'maildir',
`quota` bigint(20) NOT NULL default '-1',
`quota` bigint(20) NOT NULL default '0',
`cc` text,
`forward_in_lda` enum('n','y') NOT NULL default 'n',
`sender_cc` varchar(255) NOT NULL default '',
......@@ -1101,6 +1101,7 @@ CREATE TABLE `mail_user` (
`last_quota_notification` date NULL default NULL,
`backup_interval` VARCHAR( 255 ) NOT NULL default 'none',
`backup_copies` INT NOT NULL DEFAULT '1',
`imap_prefix` varchar(255) NULL default NULL,
PRIMARY KEY (`mailuser_id`),
KEY `server_id` (`server_id`,`email`),
KEY `email_access` (`email`,`access`)
......@@ -1460,6 +1461,7 @@ CREATE TABLE `server_php` (
`php_fpm_pool_dir` varchar(255) DEFAULT NULL,
`php_fpm_socket_dir` varchar(255) DEFAULT NULL,
`active` enum('n','y') NOT NULL DEFAULT 'y',
`sortprio` int(20) NOT NULL DEFAULT 100,
PRIMARY KEY (`server_php_id`)
) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
......@@ -1530,9 +1532,9 @@ CREATE TABLE `spamfilter_policy` (
`addr_extension_spam` varchar(64) default NULL,
`addr_extension_banned` varchar(64) default NULL,
`addr_extension_bad_header` varchar(64) default NULL,
`warnvirusrecip` enum('N','Y') default 'N',
`warnbannedrecip` enum('N','Y') default 'N',
`warnbadhrecip` enum('N','Y') default 'N',
`warnvirusrecip` VARCHAR(1) NULL default 'N',
`warnbannedrecip` VARCHAR(1) NULL default 'N',
`warnbadhrecip` VARCHAR(1) NULL default 'N',
`newvirus_admin` varchar(64) default NULL,
`virus_admin` varchar(64) default NULL,
`banned_admin` varchar(64) default NULL,
......@@ -1739,8 +1741,8 @@ CREATE TABLE `sys_group` (
CREATE TABLE `sys_ini` (
`sysini_id` int(11) unsigned NOT NULL auto_increment,
`config` longtext,
`default_logo` text NOT NULL,
`custom_logo` text NOT NULL,
`default_logo` text NULL,
`custom_logo` text NULL,
PRIMARY KEY (`sysini_id`)
) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
......
server/conf/apache_apps.vhost.master
\ No newline at end of file
../../server/conf/apache_apps.vhost.master
\ No newline at end of file
......@@ -56,7 +56,7 @@ $revision = str_replace(array('Revision:','$',' '), '', $svn_revision);
//** Application
define('ISPC_APP_TITLE', 'ISPConfig');
define('ISPC_APP_VERSION', '3.2dev');
define('DEVSYSTEM', 0);
define('DEVSYSTEM', false);
//** Database
......@@ -158,6 +158,7 @@ $conf['timezone'] = '{timezone}';
//** Misc.
$conf['interface_logout_url'] = ''; // example: http://www.domain.tld/
$conf['interface_base_url'] = ''; // example: http://www.domain.tld (no trailing slash)
//** Auto Load Modules
......
......@@ -5,9 +5,9 @@ connect = host={mysql_server_host} dbname={mysql_server_database} user={mysql_se
default_pass_scheme = CRYPT
# password-query with prefetch
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve, NULLIF(imap_prefix, '') as "userdb_namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve, NULLIF(imap_prefix, '') as "namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
# The iterate_query is required for the doveadm command only and works only on dovecot 2 servers.
# Do not enable it on Dovecot 1.x servers
......
......@@ -5,9 +5,9 @@ connect = host={mysql_server_host} dbname={mysql_server_database} user={mysql_se
default_pass_scheme = CRYPT
# password-query with prefetch
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve, NULLIF(imap_prefix, '') as "userdb_namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve, NULLIF(imap_prefix, '') as "namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
# The iterate_query is required for the doveadm command only and works only on dovecot 2 servers.
# Do not enable it on Dovecot 1.x servers
......
......@@ -5,9 +5,9 @@ connect = host={mysql_server_host} dbname={mysql_server_database} user={mysql_se
default_pass_scheme = CRYPT
# password-query with prefetch
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve, NULLIF(imap_prefix, '') as "userdb_namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve, NULLIF(imap_prefix, '') as "namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
# The iterate_query is required for the doveadm command only and works only on dovecot 2 servers.
# Do not enable it on Dovecot 1.x servers
......
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 = proxy:mysql:{config_dir}/mysql-virtual_alias_domains.cf
virtual_alias_maps = hash:/var/lib/mailman/data/virtual-mailman, proxy:mysql:{config_dir}/mysql-virtual_forwardings.cf, proxy:mysql:{config_dir}/mysql-virtual_alias_maps.cf, proxy:mysql:{config_dir}/mysql-virtual_email2email.cf
virtual_mailbox_domains = proxy:mysql:{config_dir}/mysql-virtual_domains.cf
......@@ -5,6 +7,9 @@ virtual_mailbox_maps = proxy:mysql:{config_dir}/mysql-virtual_mailboxes.cf
virtual_mailbox_base = {vmail_mailbox_base}
virtual_uid_maps = proxy:mysql:/etc/postfix/mysql-virtual_uids.cf
virtual_gid_maps = proxy:mysql:/etc/postfix/mysql-virtual_gids.cf
sender_bcc_maps = proxy:mysql:{config_dir}/mysql-virtual_outgoing_bcc.cf
inet_protocols=all
inet_interfaces = all
smtpd_sasl_auth_enable = yes
broken_sasl_auth_clients = yes
smtpd_sasl_authenticated_header = yes
......@@ -35,7 +40,7 @@ header_checks = regexp:{config_dir}/header_checks
mime_header_checks = regexp:{config_dir}/mime_header_checks
nested_header_checks = regexp:{config_dir}/nested_header_checks
body_checks = regexp:{config_dir}/body_checks
inet_interfaces = all
owner_request_special = no
smtp_tls_security_level = may
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_protocols = !SSLv2,!SSLv3
......
......@@ -240,7 +240,7 @@ includesections = php_common
[php8_2]
comment = php version 8.2
paths = /usr/bin/php8.2, /usr/lib/php/8.2/, /usr/lib/php/20210902/, /usr/share/php/8.2/, /etc/php/8.2/cli/, /etc/php/8.2/mods-available/
paths = /usr/bin/php8.2, /usr/lib/php/8.2/, /usr/lib/php/20220829/, /usr/share/php/8.2/, /etc/php/8.2/cli/, /etc/php/8.2/mods-available/
includesections = php_common
[imagemagick]
......
......@@ -5,9 +5,9 @@ connect = host={mysql_server_host} dbname={mysql_server_database} user={mysql_se
default_pass_scheme = CRYPT
# password-query with prefetch
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
password_query = SELECT email as user, password, maildir as userdb_home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as userdb_mail, uid as userdb_uid, gid as userdb_gid, CONCAT('*:storage=', quota, 'B') AS userdb_quota_rule, CONCAT(maildir, '/.sieve') as userdb_sieve, NULLIF(imap_prefix, '') as "userdb_namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}' AND NOT EXISTS (SELECT domain_id FROM mail_domain WHERE domain = '%d' AND active = 'n' AND server_id = {server_id})
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
user_query = SELECT email as user, maildir as home, CONCAT( maildir_format, ':', maildir, '/', IF(maildir_format='maildir','Maildir',maildir_format)) as mail, uid, gid, CONCAT('*:storage=', quota, 'B') AS quota_rule, CONCAT(maildir, '/.sieve') as sieve, NULLIF(imap_prefix, '') as "namespace/inbox/prefix" FROM mail_user WHERE (login = '%u' OR email = '%u') AND `disable%Ls` = 'n' AND server_id = '{server_id}'
# The iterate_query is required for the doveadm command only and works only on dovecot 2 servers.
# Do not enable it on Dovecot 1.x servers
......
......@@ -14,3 +14,6 @@
# validate DANE
smtp_dns_support_level = dnssec
smtp_tls_security_level = dane
# Disable SMTPUTF8 (until Dovecot supports it: https://git.ispconfig.org/ispconfig/ispconfig3/-/issues/6428)
smtputf8_enable = no
\ No newline at end of file
......@@ -56,9 +56,9 @@ relayhost_user=
relayhost_password=
mailbox_size_limit=0
message_size_limit=0
mailbox_soft_delete=n
mailbox_soft_delete=0
mailbox_quota_stats=y
realtime_blackhole_list=zen.spamhaus.org
realtime_blackhole_list=
overquota_notify_threshold=90
overquota_notify_admin=y
overquota_notify_reseller=y
......@@ -78,6 +78,7 @@ website_path=/var/www/clients/client[client_id]/web[website_id]
website_symlinks=/var/www/[website_domain]/:/var/www/clients/client[client_id]/[website_domain]/
website_symlinks_rel=n
network_filesystem=n
vhost_rewrite_v6=n
vhost_conf_dir=/etc/apache2/sites-available
vhost_conf_enabled_dir=/etc/apache2/sites-enabled
apache_init_script=
......@@ -135,12 +136,18 @@ overquota_notify_onok=n
logging=yes
php_fpm_reload_mode=reload
php_fpm_default_chroot=n
vhost_proxy_protocol_enabled=n
vhost_proxy_protocol_protocols=ipv4
vhost_proxy_protocol_http_port=880
vhost_proxy_protocol_https_port=8443
[dns]
bind_user=root
bind_group=bind
bind_zonefiles_dir=/etc/bind
bind_keyfiles_dir=/etc/bind
bind_zonefiles_masterprefix=pri.
bind_zonefiles_slaveprefix=slave/sec.
named_conf_path=/etc/bind/named.conf
named_conf_local_path=/etc/bind/named.conf.local
disable_bind_log=n
......
......@@ -13,7 +13,7 @@ mailbox_show_autoresponder_tab=y
mailbox_show_mail_filter_tab=y
mailbox_show_custom_rules_tab=y
mailboxlist_webmail_link=y
webmail_url=/webmail
webmail_url=https://[SERVERNAME]:8081/webmail
dkim_path=/var/lib/amavis/dkim
smtp_enabled=y
smtp_host=localhost
......@@ -28,14 +28,14 @@ ftpuser_prefix=[CLIENTNAME]
shelluser_prefix=[CLIENTNAME]
webdavuser_prefix=[CLIENTNAME]
dblist_phpmyadmin_link=y
phpmyadmin_url=/phpmyadmin
phpmyadmin_url=https://[SERVERNAME]:8081/phpmyadmin
webftp_url=
vhost_subdomains=n
vhost_aliasdomains=n
client_username_web_check_disabled=n
backups_include_into_web_quota=n
reseller_can_use_options=n
web_php_options=no,fast-cgi,mod,php-fpm
web_php_options=no,fast-cgi,php-fpm
show_aps_menu=n
client_protection=y
ssh_authentication=
......@@ -75,3 +75,4 @@ session_timeout=0
session_allow_endless=0
min_password_length=8
min_password_strength=3
show_delete_on_forms=n